Skip to content

Commit a6ed21e

Browse files
committed
Add Error type
1 parent c355424 commit a6ed21e

File tree

5 files changed

+32
-1
lines changed

5 files changed

+32
-1
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ class Definitions {
902902
final def isCompiletimeAppliedType(sym: Symbol)(implicit ctx: Context): Boolean = {
903903
def isOpsPackageObjectAppliedType: Boolean =
904904
sym.owner == CompiletimeOpsPackageObject.moduleClass && Set(
905-
tpnme.Equals, tpnme.NotEquals,
905+
tpnme.Error, tpnme.Equals, tpnme.NotEquals,
906906
tpnme.Plus, tpnme.Minus, tpnme.Times, tpnme.Div, tpnme.Mod,
907907
tpnme.Lt, tpnme.Gt, tpnme.Ge, tpnme.Le,
908908
tpnme.Abs, tpnme.Negate, tpnme.Min, tpnme.Max, tpnme.ToString,

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ object StdNames {
210210
final val Abs: N = "Abs"
211211
final val And: N = "&&"
212212
final val Div: N = "/"
213+
final val Error: N = "Error"
213214
final val Equals: N = "=="
214215
final val Ge: N = ">="
215216
final val Gt: N = ">"

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3619,6 +3619,11 @@ object Types {
36193619
case _ => None
36203620
}
36213621

3622+
def stringValue(tp: Type): Option[String] = tp match {
3623+
case ConstantType(Constant(n: String)) => Some(n)
3624+
case _ => None
3625+
}
3626+
36223627
def natValue(tp: Type): Option[Int] = intValue(tp).filter(n => n >= 0 && n < Int.MaxValue)
36233628

36243629
def constantFold1[T](extractor: Type => Option[T], op: T => Any): Option[Type] =
@@ -3637,6 +3642,7 @@ object Types {
36373642
case tpnme.Negate => constantFold1(intValue, x => -x)
36383643
case tpnme.Not => constantFold1(boolValue, x => !x)
36393644
case tpnme.ToString => constantFold1(intValue, _.toString)
3645+
case tpnme.Error => constantFold1(stringValue, msg => throw new TypeError(msg))
36403646
case _ => None
36413647
} else if (args.length == 2) tycon.symbol.name match {
36423648
case tpnme.Equals => constantFold2(constValue, _ == _)

library/src/scala/compiletime/ops/package.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package scala.compiletime
33
import scala.annotation.infix
44

55
package object ops {
6+
type Error[Msg <: String] <: Any
67
@infix type ==[X <: AnyVal, Y <: AnyVal] <: Boolean
78
@infix type !=[X <: AnyVal, Y <: AnyVal] <: Boolean
89

tests/playground/Errors.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import scala.compiletime.ops._
2+
3+
object Test {
4+
type Require[Cond <: Boolean, Msg <: String] = Cond match {
5+
case true => Any
6+
case false => Error[Msg]
7+
}
8+
9+
opaque type Positive = Int
10+
11+
object Positive {
12+
def apply[T <: Int](value: T)(given Require[T > 0, "The value provided isn't positive"]): Positive = value
13+
}
14+
15+
val x: Positive = Positive[1](1)
16+
17+
/*
18+
|no implicit argument of type Test.Require[Int(-1) > Int(0), String("The value provided isn\'t positive"),
19+
| scala.compiletime.ops.ToString[Int(-1)]
20+
|] was found for parameter x$2 of method apply in object Positive
21+
*/
22+
val y: Positive = Positive[-1](-1)
23+
}

0 commit comments

Comments
 (0)