Skip to content

Commit 445baff

Browse files
oderskytgodzik
authored andcommitted
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. [Cherry-picked e6bf7b8]
1 parent 068c6c7 commit 445baff

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
@@ -377,7 +377,9 @@ object Inferencing {
377377
}
378378

379379
/** The instantiation decision for given poly param computed from the constraint. */
380-
enum Decision { case Min; case Max; case ToMax; case Skip; case Fail }
380+
enum Decision:
381+
case Min, Max, ToMax, Skip, Fail
382+
381383
private def instDecision(tvar: TypeVar, v: Int, minimizeSelected: Boolean, ifBottom: IfBottom)(using Context): Decision =
382384
import Decision.*
383385
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
@@ -27,17 +27,21 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
2727
private type SpecialHandlers = List[(ClassSymbol, SpecialHandler)]
2828

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

4246
val tag = formal.argInfos match
4347
case arg :: Nil =>

0 commit comments

Comments
 (0)