Skip to content

Dealias less in OrderingConstraint.replace and AvoidMap #14232

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
wants to merge 1 commit into from
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
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
* of the parameter elsewhere in the constraint by type `tp`.
*/
def replace(param: TypeParamRef, tp: Type)(using Context): OrderingConstraint =
val replacement = tp.dealiasKeepAnnots.stripTypeVar
val replacement = tp.withDealiased(_.stripTypeVar)
if param == replacement then this.checkNonCyclic()
else
assert(replacement.isValueTypeOrLambda)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,8 @@ object TypeOps:
try
tp match
case tp: TermRef if toAvoid(tp) =>
tp.info.widenExpr.dealias match {
case info: SingletonType => apply(info)
tp.info.widenExpr.withDealiased {
case singleton: SingletonType => apply(singleton)
case info => range(defn.NothingType, apply(info))
}
case tp: TypeRef if toAvoid(tp) =>
Expand Down
13 changes: 10 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,14 @@ object Types {
*/
final def dealiasKeepOpaques(using Context): Type = dealias1(keepNever, keepOpaques = true)

/** Apply `f` to this type dealiased. If the type changes, keep the change,
* otherwise return the original (not dealiased) type.
*/
final def withDealiased(f: Type => Type)(using Context): Type =
val tpd = dealias
val result = f(tpd)
if result eq tpd then this else result

/** Approximate this type with a type that does not contain skolem types. */
final def deskolemized(using Context): Type =
val deskolemizer = new ApproximatingTypeMap {
Expand Down Expand Up @@ -1478,10 +1486,9 @@ object Types {
}

/** Dealias, and if result is a dependent function type, drop the `apply` refinement. */
final def dropDependentRefinement(using Context): Type = dealias match {
final def dropDependentRefinement(using Context): Type = dealias match
case RefinedType(parent, nme.apply, _) => parent
case tp => tp
}
case _ => this

/** The type constructor of an applied type, otherwise the type itself */
final def typeConstructor(using Context): Type = this match {
Expand Down
13 changes: 13 additions & 0 deletions tests/neg/i14171.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
object Test:
trait MyTypeclass[F[_]]
def f[F[_]: MyTypeclass, U](t: F[U]) = ()

// using a non-singleton type makes it compile because `widenSingletons` dealiases
type MyType[T] = Nil.type
given MyTypeclass[MyType] = null

val stream: Option[MyType[Int]] = null
for
keyStream <- stream
x = 17 // commenting this line makes it compile
yield f(keyStream) // error
12 changes: 12 additions & 0 deletions tests/pos/i14171.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
object Test:
trait MyTypeclass[F[_]]
def f[F[_]: MyTypeclass, U](t: F[U]) = ()

type MyType[T] = String
given MyTypeclass[MyType] = null

val stream: Option[MyType[Int]] = null
for
keyStream <- stream
x = 17
yield f(keyStream)