@@ -403,7 +403,8 @@ class Namer { typer: Typer =>
403403 flags |= HigherKinded
404404 analyzeRHS(body)
405405 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)
407408
408409 // to complete a constructor, move one context further out -- this
409410 // is the context enclosing the class. Note that the context in which a
@@ -416,13 +417,9 @@ class Namer { typer: Typer =>
416417 // have no implementation.
417418 val cctx = if (tree.name == nme.CONSTRUCTOR && ! flags.is(JavaDefined )) ctx.outer else ctx
418419
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)
426423 val info = adjustIfModule(completer, tree)
427424 createOrRefine[Symbol ](tree, name, flags, ctx.owner, _ => info,
428425 (fs, _, pwithin) => ctx.newSymbol(ctx.owner, name, fs, info, pwithin, tree.nameSpan))
@@ -939,7 +936,8 @@ class Namer { typer: Typer =>
939936 }
940937 }
941938
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 {
943941 private var myTypeParams : List [TypeSymbol ] = null
944942 private var nestedCtx : Context = null
945943 assert(! original.isClassDef)
@@ -966,8 +964,61 @@ class Namer { typer: Typer =>
966964 myTypeParams
967965 end completerTypeParams
968966
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
9711022 }
9721023
9731024 class ClassCompleter (cls : ClassSymbol , original : TypeDef )(ictx : Context ) extends Completer (original)(ictx) {
@@ -1130,14 +1181,16 @@ class Namer { typer: Typer =>
11301181
11311182 index(constr)
11321183 index(rest)(localCtx)
1184+
11331185 symbolOfTree(constr).info.stripPoly match // Completes constr symbol as a side effect
11341186 case mt : MethodType if cls.is(Case ) && mt.isParamDependent =>
11351187 // See issue #8073 for background
11361188 ctx.error(
11371189 i """ Implementation restriction: case classes cannot have dependencies between parameters """ ,
11381190 cls.sourcePos)
11391191 case _ =>
1140- tempInfo = denot.info.asInstanceOf [TempClassInfo ]
1192+
1193+ tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
11411194 denot.info = savedInfo
11421195 tempInfo
11431196 }
@@ -1502,57 +1555,4 @@ class Namer { typer: Typer =>
15021555 }
15031556 else valOrDefDefSig(ddef, sym, typeParams, termParamss, wrapMethType)
15041557 }
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- }
15581558}
0 commit comments