Skip to content

Commit f160cc3

Browse files
oderskymichelou
authored andcommitted
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 scala#12194
1 parent d95b9ff commit f160cc3

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
@@ -427,46 +427,48 @@ object TypeOps:
427427
sym.is(Package) || sym.isStatic && isStaticPrefix(pre.prefix)
428428
case _ => true
429429

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

471473
/** Three deviations from standard derivedSelect:
472474
* 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)