8000 Propagate CyclicReferences for maybeInitialize. · scala/scala@e5ced65 · GitHub
[go: up one dir, main page]

Skip to content

Commit e5ced65

Browse files
committed
Propagate CyclicReferences for maybeInitialize.
1 parent 61c03eb commit e5ced65

File tree

6 files changed

+50
-11
lines changed

6 files changed

+50
-11
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ trait Contexts { self: Analyzer =>
265265
def inSecondTry_=(value: Boolean) = this(SecondTry) = value
266266
def inReturnExpr = this(ReturnExpr)
267267
def inTypeConstructorAllowed = this(TypeConstructorAllowed)
268+
def propagateCyclicReferences_=(value: Boolean)
269+
= this(PropagateCyclicReferences) = value
270+
def propagateCyclicReferences = this(PropagateCyclicReferences)
268271

269272
def defaultModeForTyped: Mode = if (inTypeConstructorAllowed) Mode.NOmode else Mode.EXPRmode
270273

@@ -395,6 +398,7 @@ trait Contexts { self: Analyzer =>
395398
@inline final def withinSuperInit[T](op: => T): T = withMode(enabled = SuperInit)(op)
396399
@inline final def withinSecondTry[T](op: => T): T = withMode(enabled = SecondTry)(op)
397400
@inline final def withinPatAlternative[T](op: => T): T = withMode(enabled = PatternAlternative)(op)
401+
@inline final def withPropagateCyclicReferences[T](op: => T): T = withMode(enabled = PropagateCyclicReferences)(op)
398402

399403
/** TypeConstructorAllowed is enabled when we are typing a higher-kinded type.
400404
* adapt should then check kind-arity based on the prototypical type's kind
@@ -1511,6 +1515,9 @@ object ContextMode {
15111515
/** Are unapplied type constructors allowed here? Formerly HKmode. */
15121516
final val TypeConstructorAllowed: ContextMode = 1 << 16
15131517

1518+
/** Should we propagate CyclicReferences? */
1519+
final val PropagateCyclicReferences: ContextMode = 1 << 17
1520+
15141521
/** TODO: The "sticky modes" are EXPRmode, PATTERNmode, TYPEmode.
15151522
* To mimic the sticky mode behavior, when captain stickyfingers
15161523
* comes around we need to propagate those modes but forget the other
@@ -1534,7 +1541,9 @@ object ContextMode {
15341541
StarPatterns -> "StarPatterns",
15351542
SuperInit -> "SuperInit",
15361543
SecondTry -> "SecondTry",
1537-
TypeConstructorAllowed -> "TypeConstructorAllowed"
1544+
TypeConstructorAllowed -> "TypeConstructorAllowed",
1545+
PropagateCyclicReferences
1546+
-> "PropagateCyclicReferences"
15381547
)
15391548
}
15401549

src/compiler/scala/tools/nsc/typechecker/Infer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ trait Infer extends Checkable {
7575
// [Eugene] is there a better way?
7676
private object CheckAccessibleMacroCycle extends TypeCompleter {
7777
val tree = EmptyTree
78+
val ctx = NoContext
7879
override def complete(sym: Symbol) = ()
7980
}
8081

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ trait Namers extends MethodSynthesis {
109109
protected def owner = context.owner
110110
def contextFile = context.unit.source.file
111111
def typeErrorHandler[T](tree: Tree, alt: T): PartialFunction[Throwable, T] = {
112-
case ex: TypeError =>
112+
case ex: TypeError if !context.propagateCyclicReferences =>
113113
// H@ need to ensure that we handle only cyclic references
114114
TypeSigError(tree, ex)
115115
alt
@@ -619,7 +619,7 @@ trait Namers extends MethodSynthesis {
619619
}
620620

621621
sym setInfo {
622-
mkTypeCompleter(copyDef) { sym =>
622+
mkTypeCompleter(copyDef, context) { sym =>
623623
assignParamTypes()
624624
lazyType complete sym
625625
}
@@ -765,7 +765,7 @@ trait Namers extends MethodSynthesis {
765765
NoSymbol
766766
}
767767

768-
def monoTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
768+
def monoTypeCompleter(tree: Tree) = mkTypeCompleter(tree, context) { sym =>
769769
// this early test is there to avoid infinite baseTypes when
770770
// adding setters and getters --> bug798
771771
// It is a def in an attempt to provide some insulation against
@@ -798,15 +798,15 @@ trait Namers extends MethodSynthesis {
798798
}
799799

800800
def moduleClassTypeCompleter(tree: ModuleDef) = {
801-
mkTypeCompleter(tree) { sym =>
801+
mkTypeCompleter(tree, context) { sym =>
802802
val moduleSymbol = tree.symbol
803803
assert(moduleSymbol.moduleClass == sym, moduleSymbol.moduleClass)
804804
moduleSymbol.info // sets moduleClass info as a side effect.
805805
}
806806
}
807807

808808
/* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
809-
def accessorTypeCompleter(tree: ValDef, isSetter: Boolean) = mkTypeCompleter(tree) { sym =>
809+
def accessorTypeCompleter(tree: ValDef, isSetter: Boolean) = mkTypeCompleter(tree, context) { sym =>
810810
logAndValidate(sym) {
811811
sym setInfo {
812812
val tp = if (isSetter) MethodType(List(sym.newSyntheticValueParam(typeSig(tree))), UnitTpe)
@@ -816,7 +816,7 @@ trait Namers extends MethodSynthesis {
816816
}
817817
}
818818

819-
def selfTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
819+
def selfTypeCompleter(tree: Tree) = mkTypeCompleter(tree, context) { sym =>
820820
val selftpe = typer.typedType(tree).tpe
821821
sym setInfo {
822822
if (selftpe.typeSymbol isNonBottomSubClass sym.owner) selftpe
@@ -1696,16 +1696,18 @@ trait Namers extends MethodSynthesis {
16961696

16971697
abstract class TypeCompleter extends LazyType {
16981698
val tree: Tree
1699+
val ctx: Context
16991700
override def forceDirectSuperclasses: Unit = {
17001701
tree.foreach {
1701-
case dt: DefTree => Option(dt.symbol).map(_.maybeInitialize)
1702+
case dt: DefTree => ctx.withPropagateCyclicReferences(Option(dt.symbol).map(_.maybeInitialize))
17021703
case _ =>
17031704
}
17041705
}
17051706
}
17061707

1707-
def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new LockingTypeCompleter with FlagAgnosticCompleter {
1708+
def mkTypeCompleter(t: Tree, ctx0: Context)(c: Symbol => Unit) = new LockingTypeCompleter with FlagAgnosticCompleter {
17081709
val tree = t
1710+
val ctx = ctx0
17091711
def completeImpl(sym: Symbol) = c(sym)
17101712
}
17111713

@@ -1726,7 +1728,7 @@ trait Namers extends MethodSynthesis {
17261728
* Constructing a PolyTypeCompleter for a DefDef creates type skolems for the type parameters and
17271729
* assigns them to the `tparams` trees.
17281730
*/
1729-
class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter {
1731+
class PolyTypeCompleter(tparams: List[TypeDef], restp: TypeCompleter, val ctx: Context) extends LockingTypeCompleter with FlagAgnosticCompleter {
17301732
// @M. If `owner` is an abstract type member, `typeParams` are all NoSymbol (see comment in `completerOf`),
17311733
// otherwise, the non-skolemized (external) type parameter symbols
17321734
override val typeParams = tparams map (_.symbol)

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
16501650
supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
16511651
}
16521652
catch {
1653-
case ex: TypeError =>
1653+
case ex: TypeError if !context.propagateCyclicReferences =>
16541654
// fallback in case of cyclic errors
16551655
// @H none of the tests enter here but I couldn't rule it out
16561656
// upd. @E when a definition inherits itself, we end up here
@@ -5425,6 +5425,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
54255425
}
54265426

54275427
try runTyper() catch {
5428+
case ex: CyclicReference if context.propagateCyclicReferences =>
5429+
throw ex
54285430
case ex: TypeError =>
54295431
tree.clearType()
54305432
// The only problematic case are (recoverable) cyclic reference errors which can pop up almost anywhere.

test/files/pos/t7046-2/Macros_1.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package p1
2+
3+
import scala.reflect.macros.blackbox._
4+
import language.experimental._
5+
6+
object Macro {
7+
def impl(c: Context): c.Tree = {
8+
import c.universe._
9+
println(rootMirror.staticClass("p1.Base").knownDirectSubclasses)
10+
q"()"
11+
}
12+
def p1_Base_knownDirectSubclasses: Unit = macro impl
13+
}

test/files/pos/t7046-2/Test_2.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package p1
2+
3+
sealed trait Base
4+
5+
object Test {
6+
val x = {
7+
Macro.p1_Base_knownDirectSubclasses
8+
""
9+
}
10+
}
11+
12+
case class B(val b: Test.x.type)

0 commit comments

Comments
 (0)
0