Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anonymous class initialization in secondary constructor with self reference results in compiler crash #9368

Closed
scabug opened this issue Jun 30, 2015 · 6 comments · Fixed by scala/scala#7732

Comments

@scabug
Copy link

scabug commented Jun 30, 2015

This following snippet of code when compiled will break the compiler:

case class Event[T](sender: T)

class Foo(bar: String) {
  self =>

  def this() {
    this("baz")

    new { Event(self) } // crashes compiler
  }
}

object Main extends App {
  new Foo()
}

I've tested the code on versions 2.11.(1, 4, 7) and all of them will fail with the same error message of {{value is not a member of Object}}.

This issue seems to be related to SI-7853.

Compiling Main.scala with scalac version 2.11.7 on my Windows machine results in the following stack trace:

error: scala.reflect.internal.Types$TypeError: value <none> is not a member of Object
        at scala.tools.nsc.typechecker.Contexts$ThrowingReporter.handleError(Contexts.scala:1390)
        at scala.tools.nsc.typechecker.Contexts$ContextReporter.issue(Contexts.scala:1242)
        at scala.tools.nsc.typechecker.Contexts$Context.issue(Contexts.scala:573)
        at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$normalTypedApply$1$1.apply(Typers.scala:4548)
        at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$normalTypedApply$1$1.apply(Typers.scala:4547)
        at scala.tools.nsc.typechecker.Typers$Typer.onError$3(Typers.scala:4521)
        at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4547)
        at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4579)
        at scala.tools.nsc.typechecker.Typers$Typer.typedInAnyMode$1(Typers.scala:5342)
        at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5359)
        at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5395)
        at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5422)
        at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5369)
        at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5373)
        at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5447)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:263)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerValue(ExplicitOuter.scala:229)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:441)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:2559)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:2559)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformTrees(Trees.scala:2559)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1347)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1$$anonfun$apply$2.apply(Trees.scala:2588)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1$$anonfun$apply$2.apply(Trees.scala:2588)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:25)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:17)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2588)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2587)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2587)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1404)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.scala$tools$nsc$transform$TypingTransformers$TypingTransformer$$super$transform(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:40)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:412)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:2563)
        at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1408)
        at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1407)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:25)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:17)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1406)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2589)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2587)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2587)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1366)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2589)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2587)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2587)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1366)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.internal.Trees$$anonfun$itransform$2.apply(Trees.scala:1363)
        at scala.reflect.internal.Trees$$anonfun$itransform$2.apply(Trees.scala:1361)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:25)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:17)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1360)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:434)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2589)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2587)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2587)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1404)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.scala$tools$nsc$transform$TypingTransformers$TypingTransformer$$super$transform(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$1.apply(TypingTransformers.scala:40)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:412)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:2563)
        at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1408)
        at scala.reflect.internal.Trees$$anonfun$itransform$4.apply(Trees.scala:1407)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:25)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:17)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1406)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2589)
        at scala.reflect.api.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:2587)
        at scala.collection.immutable.List.loop$1(List.scala:173)
        at scala.collection.immutable.List.mapConserve(List.scala:189)
        at scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2587)
        at scala.reflect.internal.Trees$$anonfun$itransform$7.apply(Trees.scala:1426)
        at scala.reflect.internal.Trees$$anonfun$itransform$7.apply(Trees.scala:1426)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:25)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:17)
        at scala.reflect.internal.Trees$class.itransform(Trees.scala:1425)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
        at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.scala$tools$nsc$transform$TypingTransformers$TypingTransformer$$super$transform(TypingTransformers.scala:40)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$2.apply(TypingTransformers.scala:42)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$$anonfun$transform$2.apply(TypingTransformers.scala:42)
        at scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2600)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:30)
        at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:42)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
        at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1705)
        at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:496)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
        at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:147)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.scala$tools$nsc$transform$ExplicitOuter$ExplicitOuterTransformer$$super$transformUnit(ExplicitOuter.scala:504)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer$$anonfun$transformUnit$1.apply(ExplicitOuter.scala:504)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer$$anonfun$transformUnit$1.apply(ExplicitOuter.scala:504)
        at scala.reflect.internal.SymbolTable.enteringPhase(SymbolTable.scala:235)
        at scala.reflect.internal.SymbolTable.exitingPhase(SymbolTable.scala:256)
        at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transformUnit(ExplicitOuter.scala:504)
        at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:30)
        at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase$1.apply$mcV$sp(Global.scala:440)
        at scala.tools.nsc.Global$GlobalPhase.withCurrentUnit(Global.scala:431)
        at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:440)
        at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:398)
        at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:398)
        at scala.collection.Iterator$class.foreach(Iterator.scala:742)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1194)
        at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:398)
        at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1501)
        at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1486)
        at scala.tools.nsc.Global$Run.compileSources(Global.scala:1481)
        at scala.tools.nsc.Global$Run.compile(Global.scala:1582)
        at scala.tools.nsc.Driver.doCompile(Driver.scala:32)
        at scala.tools.nsc.MainClass.doCompile(Main.scala:23)
        at scala.tools.nsc.Driver.process(Driver.scala:51)
        at scala.tools.nsc.Driver.main(Driver.scala:64)
        at scala.tools.nsc.Main.main(Main.scala)

This at least seems to be a very specific issue issue with using self references in anonymous classes also in secondary constructors as this will compile without crashing the compiler which serves as a temporary fix in some cases:

case class Event[T](sender: T)

class Foo(bar: String) {
  self =>

  def this() {
    this("baz")

    val x = self
    new { Event(x) } // ok
  }
}

object Main extends App {
  new Foo()
}
@scabug
Copy link
Author

scabug commented Jun 30, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9368?orig=1
Reporter: Josh Bowden (jaxrtech)
Affected Versions: 2.11.1, 2.11.4, 2.11.7
See #7853, #9133

@scabug
Copy link
Author

scabug commented Mar 7, 2016

@liff said:
I offer my layman notes and a slightly smaller reproduction:

class Foo(x: Int) {
  def this() = {
    this(1)
    new { x }
  }
}

The problem seems to have something to do with the outer class of the anonymous class being resolved to package <empty> instead of class Foo, which it correctly does if the anonymous class construction is moved out of the secondary constructor.

This particular error goes away by changing ownerClass to:

    final def outerClass: Symbol =
      if (this == NoSymbol) {
        // ideally we shouldn't get here, but it's better to harden against this than suffer the infinite loop in SI-9133
        devWarningDumpStack("NoSymbol.outerClass", 15)
        NoSymbol
      } else if (owner.isClass) owner
      else if (owner.isAuxiliaryConstructor) owner.enclClass // <------
      else if (isClassLocalToConstructor) owner.enclClass.outerClass
      else owner.outerClass

But unfortunately that breaks t4842, t6666, t1909 and ‘origins’. I haven't been able to figure out how to avoid that :)

@dwijnand
Copy link
Member

dwijnand commented Feb 7, 2019

On 2.12.7 the former fails with

A.scala:9: error: Internal error: unable to find the outer accessor symbol of <$anon: Object>
    new { Event(self) } // crashes compiler
        ^
error: java.lang.StackOverflowError
	at java.lang.String.valueOf(String.java:2994)
	at scala.collection.mutable.StringBuilder.append(StringBuilder.scala:199)
	at scala.collection.TraversableOnce.$anonfun$addString$1(TraversableOnce.scala:358)
	at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:32)
	at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:29)
	at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:37)
	at scala.collection.TraversableOnce.addString(TraversableOnce.scala:356)
	at scala.collection.TraversableOnce.addString$(TraversableOnce.scala:352)
	at scala.collection.AbstractTraversable.addString(Traversable.scala:104)
	at scala.collection.TraversableOnce.mkString(TraversableOnce.scala:322)
	at scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:321)
	at scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
	at scala.collection.TraversableOnce.mkString(TraversableOnce.scala:324)
	at scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:324)
	at scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
	at scala.reflect.internal.Symbols$Symbol.compose(Symbols.scala:2788)
	at scala.reflect.internal.Symbols$Symbol.toString(Symbols.scala:2713)
	at java.lang.String.valueOf(String.java:2994)
	at java.lang.StringBuilder.append(StringBuilder.java:131)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:235)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)

and the smaller repo fails with

B.scala:4: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
    new { x }
          ^
B.scala:4: error: Internal error: unable to find the outer accessor symbol of <$anon: Object>
    new { x }
        ^
error: java.lang.StackOverflowError
	at scala.reflect.internal.Symbols$Symbol.loop$2(Symbols.scala:1296)
	at scala.reflect.internal.Symbols$Symbol.fullName(Symbols.scala:1308)
	at scala.reflect.internal.Symbols$Symbol.fullName(Symbols.scala:1291)
	at scala.reflect.internal.StdNames$TermNames.expandedNameInternal(StdNames.scala:409)
	at scala.reflect.internal.StdNames$TermNames.expandedName(StdNames.scala:413)
	at scala.tools.nsc.transform.ExplicitOuter.outerAccessor(ExplicitOuter.scala:78)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:228)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
	at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)

@joroKr21
Copy link
Member

joroKr21 commented Feb 8, 2019

On 2.13.x branch at least it's not crashing:

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Event[T](sender: T)

class Foo(bar: String) {
  self =>

  def this() {
    this("baz")

    new { Event(self) } // crashes compiler
  }
}

object Main extends App {
  new Foo()
}

// Exiting paste mode, now interpreting.

           new { Event(self) } // crashes compiler
               ^
On line 9: error: Internal error: unable to find the outer accessor symbol of <$anon: Object>

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Foo(x: Int) {
  def this() = {
    this(1)
    new { x }
  }
}

// Exiting paste mode, now interpreting.


    new { x }
          ^
<pastie>:4: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses

    new { x }
        ^
<pastie>:4: error: Internal error: unable to find the outer accessor symbol of <$anon: Object>

@joroKr21
Copy link
Member

joroKr21 commented Feb 8, 2019

Looks like this check didn't trigger properly:
https://github.com/scala/scala/blob/284a9c03c650c76e2b5295fee5c03565bcdf5246/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala#L237-L243

In any case this looks like implementation restriction.

@joroKr21
Copy link
Member

joroKr21 commented Feb 8, 2019

In the second example outerClass skips Foo because it considers new { x } local to Foo's constructor but I guess secondary constructors are not properly considered by this piece of code. What should happen in this case?

https://github.com/scala/scala/blob/e959f6ccf002696f2c4f871b2fa4961083fe2fc7/src/reflect/scala/reflect/internal/Symbols.scala#L2136-L2143

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants