Skip to content

simplify: Drop mapping tparams to tvars #18786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,19 @@ trait ConstraintHandling {
* than `maxLevel`.
*/
def instanceType(param: TypeParamRef, fromBelow: Boolean, widenUnions: Boolean, maxLevel: Int)(using Context): Type = {
val approx = approximation(param, fromBelow, maxLevel).simplified
val addTypeVars = new TypeMap with cc.CaptureSet.IdempotentCaptRefMap:
val constraint = ctx.typerState.constraint
def apply(tp: Type): Type = tp match
case tp: TypeParamRef => constraint.typeVarOfParam(tp).orElse(tp)
case tp: AppliedType if tp.isMatchAlias =>
// this case appears necessary to compile
// tests/pos-custom-args/captures/matchtypes.scala
// under -language:experimental.captureChecking
typer.Inferencing.isFullyDefined(tp, typer.ForceDegree.all)
val normed = tp.tryNormalize
if normed.exists then apply(normed) else mapOver(tp)
case _ => mapOver(tp)
val approx = addTypeVars(approximation(param, fromBelow, maxLevel))
if fromBelow then
val widened = widenInferred(approx, param, widenUnions)
// Widening can add extra constraints, in particular the widened type might
Expand Down
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,6 @@ object TypeOps:
case _ =>
val normed = tp.tryNormalize
if normed.exists then simplify(normed, theMap) else tp.map(simplify(_, theMap))
case tp: TypeParamRef =>
val tvar = ctx.typerState.constraint.typeVarOfParam(tp)
if tvar.exists then tvar else tp
case _: ThisType | _: BoundType =>
tp
case tp: AliasingBounds =>
Expand Down
17 changes: 1 addition & 16 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1464,22 +1464,7 @@ class TreeUnpickler(reader: TastyReader,
val fst = readTpt()
val (bound, scrut) =
if (nextUnsharedTag == CASEDEF) (EmptyTree, fst) else (fst, readTpt())
val tpt = MatchTypeTree(bound, scrut, readCases(end))
// If a match type definition can reduce (e.g. Id in i18261.min)
// then it's important to trigger that reduction
// before a TypeVar is added to the constraint,
// associated to the match type's type parameter.
// Otherwise, if the reduction is triggered with that constraint,
// the reduction will be simplified,
// at which point the TypeVar will replace the type parameter
// and then that TypeVar will be cached
// as the reduction of the match type definition!
//
// We also override the type, as that's what Typer does.
// The difference here is that a match type that reduces to a non-match type
// makes the TypeRef for that definition will have a TypeAlias info instead of a MatchAlias.
tpt.overwriteType(tpt.tpe.normalized)
tpt
MatchTypeTree(bound, scrut, readCases(end))
case TYPEBOUNDStpt =>
val lo = readTpt()
val hi = if currentAddr == end then lo else readTpt()
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i18261.bis.min/Main_0.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type MT[T, M] = M match { case VAL => T }

class Foo[A]
object Foo:
given inst[X, Y <: MT[X, VAL]]: Foo[Y] = new Foo[Y]

trait VAL
4 changes: 4 additions & 0 deletions tests/pos/i18261.bis.min/Test_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Test:
def test: Unit =
summon[Foo[Int]]
summon[Foo[Long]]
7 changes: 7 additions & 0 deletions tests/pos/i18261.bis/DFBits_0.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trait DFBits[W <: Int]

trait Candidate[R]:
type OutW <: Int
object Candidate:
given [W <: Int, R <: Foo[DFBits[W], VAL]]: Candidate[R] with
type OutW = W
4 changes: 4 additions & 0 deletions tests/pos/i18261.bis/Foo_0.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
trait VAL

type Foo[T, M] = M match
case VAL => T
5 changes: 5 additions & 0 deletions tests/pos/i18261.bis/Test_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def baz[L](lhs: L)(using icL: Candidate[L]): DFBits[Int] = ???
object Test:
val x: DFBits[8] = ???
val z: DFBits[Int] = baz(x)
summon[Candidate[z.type]]