@@ -1460,13 +1460,13 @@ object Types {
14601460 case _ => this
14611461 }
14621462
1463- /** Follow aliases and dereferences LazyRefs, annotated types and instantiated
1463+ /** Follow aliases and dereference LazyRefs, annotated types and instantiated
14641464 * TypeVars until type is no longer alias type, annotated type, LazyRef,
14651465 * or instantiated type variable.
14661466 */
14671467 final def dealias (using Context ): Type = dealias1(keepNever, keepOpaques = false )
14681468
1469- /** Follow aliases and dereferences LazyRefs and instantiated TypeVars until type
1469+ /** Follow aliases and dereference LazyRefs and instantiated TypeVars until type
14701470 * is no longer alias type, LazyRef, or instantiated type variable.
14711471 * Goes through annotated types and rewraps annotations on the result.
14721472 */
@@ -1475,12 +1475,30 @@ object Types {
14751475 /** Like `dealiasKeepAnnots`, but keeps only refining annotations */
14761476 final def dealiasKeepRefiningAnnots (using Context ): Type = dealias1(keepIfRefining, keepOpaques = false )
14771477
1478- /** Follow non-opaque aliases and dereferences LazyRefs, annotated types and instantiated
1479- * TypeVars until type is no longer alias type, annotated type, LazyRef,
1480- * or instantiated type variable.
1478+ /** Like dealias, but does not follow aliases if symbol is Opaque. This is
1479+ * necessary if we want to look at the info of a symbol containing opaque
1480+ * type aliases but pretend "it's from the outside". For instance, consider:
1481+ *
1482+ * opaque type IArray[T] = Array[? <: T]
1483+ * object IArray:
1484+ * def head[T](xs: IArray[T]): T = ???
1485+ *
1486+ * If we dealias types in the info of `head`, those types appear with prefix
1487+ * IArray.this, where IArray's self type is `IArray { type IArray[T] = Array[? <: T] }`.
1488+ * Hence, if we see IArray it will appear as an alias of [T] =>> Array[? <: T].
1489+ * But if we want to see the type from the outside of object IArray we need to
1490+ * suppress this dealiasing. A test case where this matters is i18909.scala.
1491+ * Here, we dealias symbol infos at the start of capture checking in operation `fluidify`.
1492+ * We have to be careful not to accidentally reveal opqaue aliases when doing so.
14811493 */
14821494 final def dealiasKeepOpaques (using Context ): Type = dealias1(keepNever, keepOpaques = true )
14831495
1496+ /** Like dealiasKeepAnnots, but does not follow opaque aliases. See `dealiasKeepOpaques`
1497+ * for why this is sometimes necessary.
1498+ */
1499+ final def dealiasKeepAnnotsAndOpaques (using Context ): Type =
1500+ dealias1(keepAlways, keepOpaques = true )
1501+
14841502 /** Approximate this type with a type that does not contain skolem types. */
14851503 final def deskolemized (using Context ): Type =
14861504 val deskolemizer = new ApproximatingTypeMap {
@@ -5351,6 +5369,8 @@ object Types {
53515369 case that : AliasingBounds => this .isTypeAlias == that.isTypeAlias && alias.eq(that.alias)
53525370 case _ => false
53535371 }
5372+
5373+ override def toString = s " ${getClass.getSimpleName}( $alias) "
53545374 }
53555375
53565376 /** = T
0 commit comments