Skip to content

Commit 2145aa4

Browse files
committed
Normalize after avoidance
Avoid steps can yield match types that should be normalized to keep things clean. This means avoidance does the same steps as simplification in this respect. Fixes #12194
1 parent 3bcdc34 commit 2145aa4

File tree

4 files changed

+60
-40
lines changed

4 files changed

+60
-40
lines changed

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

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -420,46 +420,48 @@ object TypeOps:
420420
sym.is(Package) || sym.isStatic && isStaticPrefix(pre.prefix)
421421
case _ => true
422422

423-
def apply(tp: Type): Type = tp match {
424-
case tp: TermRef
425-
if toAvoid(tp.symbol) || partsToAvoid(Nil, tp.info).nonEmpty =>
426-
tp.info.widenExpr.dealias match {
427-
case info: SingletonType => apply(info)
428-
case info => range(defn.NothingType, apply(info))
429-
}
430-
case tp: TypeRef if toAvoid(tp.symbol) =>
431-
tp.info match {
432-
case info: AliasingBounds =>
433-
apply(info.alias)
434-
case TypeBounds(lo, hi) =>
435-
range(atVariance(-variance)(apply(lo)), apply(hi))
436-
case info: ClassInfo =>
437-
range(defn.NothingType, apply(classBound(info)))
438-
case _ =>
439-
emptyRange // should happen only in error cases
440-
}
441-
case tp: ThisType =>
442-
// ThisType is only used inside a class.
443-
// Therefore, either they don't appear in the type to be avoided, or
444-
// it must be a class that encloses the block whose type is to be avoided.
445-
tp
446-
case tp: SkolemType if partsToAvoid(Nil, tp.info).nonEmpty =>
447-
range(defn.NothingType, apply(tp.info))
448-
case tp: TypeVar if mapCtx.typerState.constraint.contains(tp) =>
449-
val lo = TypeComparer.instanceType(
450-
tp.origin, fromBelow = variance > 0 || variance == 0 && tp.hasLowerBound)(using mapCtx)
451-
val lo1 = apply(lo)
452-
if (lo1 ne lo) lo1 else tp
453-
case tp: LazyRef =>
454-
if localParamRefs.contains(tp.ref) then tp
455-
else if isExpandingBounds then emptyRange
456-
else mapOver(tp)
457-
case tl: HKTypeLambda =>
458-
localParamRefs ++= tl.paramRefs
459-
mapOver(tl)
460-
case _ =>
461-
mapOver(tp)
462-
}
423+
def apply(tp: Type): Type =
424+
val tp1 = tp match
425+
case tp: TermRef
426+
if toAvoid(tp.symbol) || partsToAvoid(Nil, tp.info).nonEmpty =>
427+
tp.info.widenExpr.dealias match {
428+
case info: SingletonType => apply(info)
429+
case info => range(defn.NothingType, apply(info))
430+
}
431+
case tp: TypeRef if toAvoid(tp.symbol) =>
432+
tp.info match {
433+
case info: AliasingBounds =>
434+
apply(info.alias)
435+
case TypeBounds(lo, hi) =>
436+
range(atVariance(-variance)(apply(lo)), apply(hi))
437+
case info: ClassInfo =>
438+
range(defn.NothingType, apply(classBound(info)))
439+
case _ =>
440+
emptyRange // should happen only in error cases
441+
}
442+
case tp: ThisType =>
443+
// ThisType is only used inside a class.
444+
// Therefore, either they don't appear in the type to be avoided, or
445+
// it must be a class that encloses the block whose type is to be avoided.
446+
tp
447+
case tp: SkolemType if partsToAvoid(Nil, tp.info).nonEmpty =>
448+
range(defn.NothingType, apply(tp.info))
449+
case tp: TypeVar if mapCtx.typerState.constraint.contains(tp) =>
450+
val lo = TypeComparer.instanceType(
451+
tp.origin, fromBelow = variance > 0 || variance == 0 && tp.hasLowerBound)(using mapCtx)
452+
val lo1 = apply(lo)
453+
if (lo1 ne lo) lo1 else tp
454+
case tp: LazyRef =>
455+
if localParamRefs.contains(tp.ref) then tp
456+
else if isExpandingBounds then emptyRange
457+
else mapOver(tp)
458+
case tl: HKTypeLambda =>
459+
localParamRefs ++= tl.paramRefs
460+
mapOver(tl)
461+
case _ =>
462+
mapOver(tp)
463+
if tp1 ne tp then tp1.normalized else tp
464+
end apply
463465

464466
/** Three deviations from standard derivedSelect:
465467
* 1. We first try a widening conversion to the type's info with

compiler/test/dotc/run-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ typeclass-derivation2d.scala
3333
typeclass-derivation3.scala
3434
varargs-abstract
3535
zero-arity-case-class.scala
36+
i12194.scala

tests/run/i12194.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
List(foo, bar)

tests/run/i12194.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.annotation.implicitNotFound
2+
import scala.compiletime.package$package.summonAll
3+
import scala.util.Try
4+
import scala.util.Success
5+
import scala.util.Failure
6+
import scala.util.NotGiven
7+
import scala.deriving.*
8+
9+
def f(): Unit =
10+
var t = (??? : Tuple1[ValueOf["foo"]]); t.toList.map(identity)
11+
(??? : Tuple1[ValueOf["foo"]]).toList.map(identity)
12+
13+
@main def Test(): Unit =
14+
println(summonAll[Tuple.Map[("foo", "bar"), ValueOf]].toList.map{
15+
case str: ValueOf[_] str.value
16+
})

0 commit comments

Comments
 (0)