Skip to content

Commit 95d06bc

Browse files
committed
Make implicit match imply erased
1 parent fc2be78 commit 95d06bc

File tree

4 files changed

+15
-16
lines changed

4 files changed

+15
-16
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -974,9 +974,11 @@ class Typer extends Namer
974974
val unchecked = pt.isRef(defn.PartialFunctionClass)
975975
typed(desugar.makeCaseLambda(tree.cases, protoFormals.length, unchecked) withPos tree.pos, pt)
976976
case id @ untpd.ImplicitScrutinee() =>
977-
if (tree.getAttachment(PrepareTransparent.TopLevelMatch).isEmpty ||
978-
!ctx.owner.flagsUNSAFE.is(Erased))
979-
ctx.error(em"implicit match cannot be used here; it must occur as a toplevel match of an erased transparent method", tree.pos)
977+
if (tree.getAttachment(PrepareTransparent.TopLevelMatch).isDefined)
978+
ctx.owner.setFlag(Erased)
979+
else
980+
ctx.error(em"implicit match cannot be used here; it must occur as a toplevel match of a transparent method", tree.pos)
981+
980982
val sel1 = id.withType(defn.ImplicitScrutineeTypeRef)
981983
typedMatchFinish(tree, sel1, sel1.tpe, pt)
982984
case _ =>

docs/docs/typelevel.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ The following rewrite rules are performed when simplifying inlined bodies:
233233

234234
Transparent methods are effectively final; they may not be overwritten.
235235

236-
Transparent methods with an implicit match expression on their right-hand side must in addition be declared `erased`. Erased transparent methods must be always fully applied. In addition, the restrictions on normal erased methods apply, including:
236+
Transparent methods with a toplevel implicit match or macro splice are classified `erased` - an `erased` modifier can be given for them, but it is redundant. Erased transparent methods must be always fully applied. In addition, the restrictions on normal erased methods apply, including:
237237

238238
1. They may not override other methods.
239239
2. They may not be referred to from a non-erased context.
@@ -409,7 +409,8 @@ Patterns are tried in sequence. The first case with a pattern `x: T` such that a
409409
of type `T` can be summoned is chosen. The variable `x` is then bound to the implicit value for the remainder of the case. It can in turn be used as an implicit in the right hand side of the case.
410410
It is an error if one of the tested patterns gives rise to an ambiguous implicit search.
411411

412-
Implicit matches can only occur as toplevel match expressions of methods that are both `erased` and `transparent`. This ensures that all implicit searches are done at compile-time.
412+
Implicit matches can only occur as toplevel match expressions of a `transparent` method.
413+
If a transpatent method contains implicit matches, it is classified as `erased` - an `erased` modifier can be given for it, but it is redundant. This ensures that all implicit searches are done at compile-time.
413414

414415
## Transparent Values
415416

tests/neg/implicitMatch-ambiguous.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ object Test {
44
implicit val a1: A = new A
55
implicit val a2: A = new A
66

7-
erased transparent def f: Any = implicit match {
7+
transparent def f: Any = implicit match {
88
case _: A => ??? // error: ambiguous implicits
99
}
1010

tests/neg/implicitMatch-syntax.scala

+6-10
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,32 @@ object Test {
22
import collection.immutable.TreeSet
33
import collection.immutable.HashSet
44

5-
erased transparent def f1[T] = implicit implicit match { // error: repeated modifier // error: illegal modifier
5+
transparent def f1[T] = implicit implicit match { // error: repeated modifier // error: illegal modifier
66
case ord: Ordered[T] => new TreeSet[T] // error: no implicit
77
case _ => new HashSet[T]
88

99
}
1010

11-
erased transparent def f2[T] = implicit erased match { // error: illegal modifier
11+
transparent def f2[T] = implicit erased match { // error: illegal modifier
1212
case ord: Ordered[T] => new TreeSet[T] // error: no implicit
1313
case _ => new HashSet[T]
1414
}
1515

16-
erased transparent def f3[T] = erased implicit match { // error: illegal modifier
16+
transparent def f3[T] = erased implicit match { // error: illegal modifier
1717
case ord: Ordered[T] => new TreeSet[T] // error: no implicit
1818
case _ => new HashSet[T]
1919
}
2020

21-
erased transparent def f4() = implicit match {
21+
transparent def f4() = implicit match {
2222
case Nil => ??? // error: not a legal pattern
2323
case x :: xs => ??? // error: not a legal pattern
2424
}
2525

26-
erased transparent def f5[T] = locally { implicit match { // error: implicit match cannot be used here
26+
transparent def f5[T] = locally { implicit match { // error: implicit match cannot be used here
2727
case _ => new HashSet[T]
2828
}}
2929

30-
transparent def f6[T] = implicit match { // error: implicit match cannot be used here
31-
case _ => new HashSet[T]
32-
}
33-
34-
erased def f7[T] = implicit match { // error: implicit match cannot be used here
30+
erased def f6[T] = implicit match { // error: implicit match cannot be used here
3531
case _ => new HashSet[T]
3632
}
3733
}

0 commit comments

Comments
 (0)