Skip to content

Commit 5bafff7

Browse files
committed
Normalize match type usage during implicit lookup
1 parent d4a8600 commit 5bafff7

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -3180,7 +3180,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
31803180
tp
31813181
case Nil =>
31823182
val casesText = MatchTypeTrace.noMatchesText(scrut, cases)
3183-
throw TypeError(em"Match type reduction $casesText")
3183+
throw MatchTypeReductionError(em"Match type reduction $casesText")
31843184

31853185
inFrozenConstraint {
31863186
// Empty types break the basic assumption that if a scrutinee and a

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

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ object TypeError:
4646
def toMessage(using Context) = msg
4747
end TypeError
4848

49+
class MatchTypeReductionError(msg: Message)(using Context) extends TypeError:
50+
def toMessage(using Context) = msg
51+
4952
class MalformedType(pre: Type, denot: Denotation, absMembers: Set[Name])(using Context) extends TypeError:
5053
def toMessage(using Context) = em"malformed type: $pre is not a legal prefix for $denot because it contains abstract type member${if (absMembers.size == 1) "" else "s"} ${absMembers.mkString(", ")}"
5154

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

+7
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,13 @@ trait ImplicitRunInfo:
634634
case t: TypeLambda =>
635635
for p <- t.paramRefs do partSeen += p
636636
traverseChildren(t)
637+
case t: MatchType =>
638+
traverseChildren(t)
639+
traverse(try t.normalized catch case _: MatchTypeReductionError => t)
640+
case MatchType.InDisguise(mt)
641+
if !t.isInstanceOf[LazyRef] // skip recursive applications (eg. Tuple.Map)
642+
=>
643+
traverse(mt)
637644
case t =>
638645
traverseChildren(t)
639646

tests/pos/i17395.scala

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
trait TC[T]
2+
3+
object TC {
4+
def optionTCForPart[T](implicit tc: TC[ExtractPart[T]]): TC[Option[ExtractPart[T]]] = new TC[Option[ExtractPart[T]]] {}
5+
}
6+
7+
type ExtractPart[T] = T match {
8+
case PartField[t] => t
9+
}
10+
type PartField[T] = Any { type Part = T }
11+
12+
class ValuePartHolder {
13+
type Part = Value
14+
}
15+
16+
class Value
17+
object Value {
18+
implicit val tcValue: TC[Value] = new {}
19+
}
20+
21+
@main def main(): Unit = {
22+
// import Value.tcValue // explicit import works around the issue, but shouldn't be necessary
23+
val tc = TC.optionTCForPart[ValuePartHolder]
24+
println(tc)
25+
}

0 commit comments

Comments
 (0)