Skip to content

Commit e6bf7b8

Browse files
committed
Don't use FullyDefinedType when synthesizing ClassTags
It's not necessary to instantiate all type variables, deeply, since we are only interested in the outermost shape. Also, that way we do not instantiate to Nothing, which is something difficult to recover from.
1 parent 7987a0c commit e6bf7b8

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,9 @@ object Inferencing {
444444
}
445445

446446
/** The instantiation decision for given poly param computed from the constraint. */
447-
enum Decision { case Min; case Max; case ToMax; case Skip; case Fail }
447+
enum Decision:
448+
case Min, Max, ToMax, Skip, Fail
449+
448450
private def instDecision(tvar: TypeVar, v: Int, minimizeSelected: Boolean, ifBottom: IfBottom)(using Context): Decision =
449451
import Decision.*
450452
val direction = instDirection(tvar.origin)

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
2929
private type SpecialHandlers = List[(ClassSymbol, SpecialHandler)]
3030

3131
val synthesizedClassTag: SpecialHandler = (formal, span) =>
32-
def instArg(tp: Type): Type = tp.stripTypeVar match
32+
def instArg(tp: Type): Type = tp.dealias match
3333
// Special case to avoid instantiating `Int & S` to `Int & Nothing` in
3434
// i16328.scala. The intersection comes from an earlier instantiation
3535
// to an upper bound.
3636
// The dual situation with unions is harder to trigger because lower
3737
// bounds are usually widened during instantiation.
3838
case tp: AndOrType if tp.tp1 =:= tp.tp2 =>
3939
instArg(tp.tp1)
40+
case tvar: TypeVar if ctx.typerState.constraint.contains(tvar) =>
41+
instArg(
42+
if tvar.hasLowerBound then tvar.instantiate(fromBelow = true)
43+
else if tvar.hasUpperBound then tvar.instantiate(fromBelow = false)
44+
else NoType)
4045
case _ =>
41-
if isFullyDefined(tp, ForceDegree.all) then tp
42-
else NoType // this happens in tests/neg/i15372.scala
46+
tp
4347

4448
val tag = formal.argInfos match
4549
case arg :: Nil =>

0 commit comments

Comments
 (0)