@@ -403,7 +403,8 @@ class Namer { typer: Typer =>
403
403
flags |= HigherKinded
404
404
analyzeRHS(body)
405
405
case _ =>
406
- if tree.rhs.isEmpty then flags |= Deferred else analyzeRHS(tree.rhs)
406
+ if rhs.isEmpty || flags.is(Opaque ) then flags |= Deferred
407
+ analyzeRHS(tree.rhs)
407
408
408
409
// to complete a constructor, move one context further out -- this
409
410
// is the context enclosing the class. Note that the context in which a
@@ -416,13 +417,9 @@ class Namer { typer: Typer =>
416
417
// have no implementation.
417
418
val cctx = if (tree.name == nme.CONSTRUCTOR && ! flags.is(JavaDefined )) ctx.outer else ctx
418
419
419
- val completer = tree match {
420
- case tree : TypeDef =>
421
- if (flags.is(Opaque ) && ctx.owner.isClass) ctx.owner.setFlag(Opaque )
422
- new TypeDefCompleter (tree)(cctx)
423
- case _ =>
424
- new Completer (tree)(cctx)
425
- }
420
+ val completer = tree match
421
+ case tree : TypeDef => TypeDefCompleter (tree)(cctx)
422
+ case _ => Completer (tree)(cctx)
426
423
val info = adjustIfModule(completer, tree)
427
424
createOrRefine[Symbol ](tree, name, flags, ctx.owner, _ => info,
428
425
(fs, _, pwithin) => ctx.newSymbol(ctx.owner, name, fs, info, pwithin, tree.nameSpan))
@@ -939,7 +936,8 @@ class Namer { typer: Typer =>
939
936
}
940
937
}
941
938
942
- class TypeDefCompleter (original : TypeDef )(ictx : Context ) extends Completer (original)(ictx) with TypeParamsCompleter {
939
+ class TypeDefCompleter (original : TypeDef )(ictx : Context )
940
+ extends Completer (original)(ictx) with TypeParamsCompleter {
943
941
private var myTypeParams : List [TypeSymbol ] = null
944
942
private var nestedCtx : Context = null
945
943
assert(! original.isClassDef)
@@ -966,8 +964,61 @@ class Namer { typer: Typer =>
966
964
myTypeParams
967
965
end completerTypeParams
968
966
969
- override protected def typeSig (sym : Symbol ): Type =
970
- typeDefSig(original, sym, completerTypeParams(sym)(ictx))(nestedCtx)
967
+ override final def typeSig (sym : Symbol ): Type =
968
+ val tparamSyms = completerTypeParams(sym)(ictx)
969
+ given ctx as Context = nestedCtx
970
+ def abstracted (tp : TypeBounds ): TypeBounds = HKTypeLambda .boundsFromParams(tparamSyms, tp)
971
+ val dummyInfo1 = abstracted(TypeBounds .empty)
972
+ sym.info = dummyInfo1
973
+ sym.setFlag(Provisional )
974
+ // Temporarily set info of defined type T to ` >: Nothing <: Any.
975
+ // This is done to avoid cyclic reference errors for F-bounds.
976
+ // This is subtle: `sym` has now an empty TypeBounds, but is not automatically
977
+ // made an abstract type. If it had been made an abstract type, it would count as an
978
+ // abstract type of its enclosing class, which might make that class an invalid
979
+ // prefix. I verified this would lead to an error when compiling io.ClassPath.
980
+ // A distilled version is in pos/prefix.scala.
981
+ //
982
+ // The scheme critically relies on an implementation detail of isRef, which
983
+ // inspects a TypeRef's info, instead of simply dealiasing alias types.
984
+
985
+ val isDerived = original.rhs.isInstanceOf [untpd.DerivedTypeTree ]
986
+ val rhs = original.rhs match {
987
+ case LambdaTypeTree (_, body) => body
988
+ case rhs => rhs
989
+ }
990
+
991
+ // For match types: approximate with upper bound while evaluating the rhs.
992
+ val dummyInfo2 = rhs match {
993
+ case MatchTypeTree (bound, _, _) if ! bound.isEmpty =>
994
+ abstracted(TypeBounds .upper(typedAheadType(bound).tpe))
995
+ case _ =>
996
+ dummyInfo1
997
+ }
998
+ sym.info = dummyInfo2
999
+
1000
+ val rhsBodyType : TypeBounds = typedAheadType(rhs).tpe.toBounds
1001
+ val unsafeInfo = if (isDerived) rhsBodyType else abstracted(rhsBodyType)
1002
+ if (isDerived) sym.info = unsafeInfo
1003
+ else {
1004
+ sym.info = NoCompleter
1005
+ sym.info = sym.opaqueToBounds(checkNonCyclic(sym, unsafeInfo, reportErrors = true ))
1006
+ }
1007
+ if ! Config .newScheme then sym.normalizeOpaque()
1008
+ else if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
1009
+ sym.resetFlag(Provisional )
1010
+
1011
+ // Here we pay the price for the cavalier setting info to TypeBounds.empty above.
1012
+ // We need to compensate by reloading the denotation of references that might
1013
+ // still contain the TypeBounds.empty. If we do not do this, stdlib factories
1014
+ // fail with a bounds error in PostTyper.
1015
+ def ensureUpToDate (tref : TypeRef , outdated : Type ) =
1016
+ if (tref.info == outdated && sym.info != outdated) tref.recomputeDenot()
1017
+ ensureUpToDate(sym.typeRef, dummyInfo1)
1018
+ if (dummyInfo2 `ne` dummyInfo1) ensureUpToDate(sym.typeRef, dummyInfo2)
1019
+
1020
+ sym.info
1021
+ end typeSig
971
1022
}
972
1023
973
1024
class ClassCompleter (cls : ClassSymbol , original : TypeDef )(ictx : Context ) extends Completer (original)(ictx) {
@@ -1130,14 +1181,16 @@ class Namer { typer: Typer =>
1130
1181
1131
1182
index(constr)
1132
1183
index(rest)(localCtx)
1184
+
1133
1185
symbolOfTree(constr).info.stripPoly match // Completes constr symbol as a side effect
1134
1186
case mt : MethodType if cls.is(Case ) && mt.isParamDependent =>
1135
1187
// See issue #8073 for background
1136
1188
ctx.error(
1137
1189
i """ Implementation restriction: case classes cannot have dependencies between parameters """ ,
1138
1190
cls.sourcePos)
1139
1191
case _ =>
1140
- tempInfo = denot.info.asInstanceOf [TempClassInfo ]
1192
+
1193
+ tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
1141
1194
denot.info = savedInfo
1142
1195
tempInfo
1143
1196
}
@@ -1502,57 +1555,4 @@ class Namer { typer: Typer =>
1502
1555
}
1503
1556
else valOrDefDefSig(ddef, sym, typeParams, termParamss, wrapMethType)
1504
1557
}
1505
-
1506
- def typeDefSig (tdef : TypeDef , sym : Symbol , tparamSyms : List [TypeSymbol ])(implicit ctx : Context ): Type = {
1507
- def abstracted (tp : TypeBounds ): TypeBounds = HKTypeLambda .boundsFromParams(tparamSyms, tp)
1508
- val dummyInfo1 = abstracted(TypeBounds .empty)
1509
- sym.info = dummyInfo1
1510
- sym.setFlag(Provisional )
1511
- // Temporarily set info of defined type T to ` >: Nothing <: Any.
1512
- // This is done to avoid cyclic reference errors for F-bounds.
1513
- // This is subtle: `sym` has now an empty TypeBounds, but is not automatically
1514
- // made an abstract type. If it had been made an abstract type, it would count as an
1515
- // abstract type of its enclosing class, which might make that class an invalid
1516
- // prefix. I verified this would lead to an error when compiling io.ClassPath.
1517
- // A distilled version is in pos/prefix.scala.
1518
- //
1519
- // The scheme critically relies on an implementation detail of isRef, which
1520
- // inspects a TypeRef's info, instead of simply dealiasing alias types.
1521
-
1522
- val isDerived = tdef.rhs.isInstanceOf [untpd.DerivedTypeTree ]
1523
- val rhs = tdef.rhs match {
1524
- case LambdaTypeTree (_, body) => body
1525
- case rhs => rhs
1526
- }
1527
-
1528
- // For match types: approximate with upper bound while evaluating the rhs.
1529
- val dummyInfo2 = rhs match {
1530
- case MatchTypeTree (bound, _, _) if ! bound.isEmpty =>
1531
- abstracted(TypeBounds .upper(typedAheadType(bound).tpe))
1532
- case _ =>
1533
- dummyInfo1
1534
- }
1535
- sym.info = dummyInfo2
1536
-
1537
- val rhsBodyType : TypeBounds = typedAheadType(rhs).tpe.toBounds
1538
- val unsafeInfo = if (isDerived) rhsBodyType else abstracted(rhsBodyType)
1539
- if (isDerived) sym.info = unsafeInfo
1540
- else {
1541
- sym.info = NoCompleter
1542
- sym.info = checkNonCyclic(sym, unsafeInfo, reportErrors = true )
1543
- }
1544
- sym.normalizeOpaque()
1545
- sym.resetFlag(Provisional )
1546
-
1547
- // Here we pay the price for the cavalier setting info to TypeBounds.empty above.
1548
- // We need to compensate by reloading the denotation of references that might
1549
- // still contain the TypeBounds.empty. If we do not do this, stdlib factories
1550
- // fail with a bounds error in PostTyper.
1551
- def ensureUpToDate (tref : TypeRef , outdated : Type ) =
1552
- if (tref.info == outdated && sym.info != outdated) tref.recomputeDenot()
1553
- ensureUpToDate(sym.typeRef, dummyInfo1)
1554
- if (dummyInfo2 `ne` dummyInfo1) ensureUpToDate(sym.typeRef, dummyInfo2)
1555
-
1556
- sym.info
1557
- }
1558
1558
}
0 commit comments