Skip to content

Commit 8d1a912

Browse files
authored
Merge pull request #8580 from dotty-staging/fix-#8573
Fix #8573: Fix higher-kinded bounded opaque types
2 parents 4df9b6f + c06f6d8 commit 8d1a912

File tree

6 files changed

+30
-12
lines changed

6 files changed

+30
-12
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,13 @@ object SymDenotations {
432432
* self type of the enclosing class.
433433
* Otherwise return `info`
434434
*
435-
* @param info Is assumed to be a (lambda-abstracted) right hand side TypeAlias
436-
* of the opaque type definition.
437-
* @param rhs The right hand side tree of the type definition
435+
* @param info Is assumed to be a (lambda-abstracted) right hand side TypeAlias
436+
* of the opaque type definition.
437+
* @param rhs The right hand side tree of the type definition
438+
* @param tparams The type parameters with which the right-hand side bounds should be abstracted
439+
*
438440
*/
439-
def opaqueToBounds(info: Type, rhs: tpd.Tree)(using Context): Type =
441+
def opaqueToBounds(info: Type, rhs: tpd.Tree, tparams: List[TypeParamInfo])(using Context): Type =
440442

441443
def setAlias(tp: Type) =
442444
def recur(self: Type): Unit = self match
@@ -449,7 +451,7 @@ object SymDenotations {
449451
end setAlias
450452

451453
def bounds(t: tpd.Tree): TypeBounds = t match
452-
case LambdaTypeTree(_, body) =>
454+
case LambdaTypeTree(tparams, body) =>
453455
bounds(body)
454456
case TypeBoundsTree(lo, hi, alias) =>
455457
assert(!alias.isEmpty)
@@ -460,7 +462,7 @@ object SymDenotations {
460462
info match
461463
case TypeAlias(alias) if isOpaqueAlias && owner.isClass =>
462464
setAlias(alias)
463-
HKTypeLambda.boundsFromParams(alias.typeParams, bounds(rhs))
465+
HKTypeLambda.boundsFromParams(tparams, bounds(rhs))
464466
case _ =>
465467
info
466468
end opaqueToBounds

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ class TreeUnpickler(reader: TastyReader,
839839
case _: TypeBounds | _: ClassInfo => checkNonCyclic(sym, rhs.tpe, reportErrors = false)
840840
case _ => rhs.tpe.toBounds
841841
},
842-
rhs)
842+
rhs, rhs.tpe.typeParams)
843843
if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
844844
sym.resetFlag(Provisional)
845845
TypeDef(rhs)

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,10 +997,16 @@ class Namer { typer: Typer =>
997997
val rhs1 = typedAheadType(rhs)
998998
val rhsBodyType: TypeBounds = rhs1.tpe.toBounds
999999
val unsafeInfo = if (isDerived) rhsBodyType else abstracted(rhsBodyType)
1000+
1001+
def opaqueToBounds(info: Type): Type =
1002+
if sym.isOpaqueAlias && tparamSyms.isEmpty && info.typeParams.nonEmpty then
1003+
ctx.error(em"opaque type alias must be fully applied", rhs.sourcePos)
1004+
sym.opaqueToBounds(info, rhs1, tparamSyms)
1005+
10001006
if (isDerived) sym.info = unsafeInfo
10011007
else {
10021008
sym.info = NoCompleter
1003-
sym.info = sym.opaqueToBounds(checkNonCyclic(sym, unsafeInfo, reportErrors = true), rhs1)
1009+
sym.info = opaqueToBounds(checkNonCyclic(sym, unsafeInfo, reportErrors = true))
10041010
}
10051011
if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
10061012
sym.resetFlag(Provisional)

tests/neg/i6225.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
object O1 {
1+
object O1 { // error: cannot be instantiated
22
type A[X] = X
3-
opaque type T = A
3+
opaque type T = A // error: opaque type alias must be fully applied
44
}
55

66
object O2 {
77
opaque type A[X] = X
8-
object A {
9-
opaque type T = A
8+
object A { // error: cannot be instantiated
9+
opaque type T = A // error: opaque type alias must be fully applied
1010
}
1111
}
1212

tests/pos/i8537.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
val f: Int => String = _ => "b"
2+
var g: Int => String = (_) => "b" // workaround
3+
var h: Int => String = _ => "b" // end of statement expected but '=>' found

tests/pos/i8573.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Example1 {
2+
opaque type Foo[A] <: A = A
3+
}
4+
5+
object Example2 {
6+
opaque type Foo[A] >: A = A
7+
}

0 commit comments

Comments
 (0)