diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-02 18:01:14 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-02 18:01:14 -0700 |
commit | 424072aeaa391de40531f33694985072cbb70152 (patch) | |
tree | eea8a41a840d7971bc963b30464eb2e0bcae96bf | |
parent | f8ed076e251ff8b6e2b1d27f8c8a0dde2117308d (diff) | |
parent | a525d371e10b2bb9b6a2228f67603aa318f97716 (diff) | |
download | scala-424072aeaa391de40531f33694985072cbb70152.tar.gz scala-424072aeaa391de40531f33694985072cbb70152.tar.bz2 scala-424072aeaa391de40531f33694985072cbb70152.zip |
Merge pull request #1561 from gkossakowski/ticket/6562
SI-6562 Fix crash with class nested in @inline method
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 8 | ||||
-rw-r--r-- | test/files/pos/t6562.scala | 14 |
4 files changed, 31 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 77ad65957d..3ac19650eb 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -499,8 +499,11 @@ abstract class ExplicitOuter extends InfoTransform case Select(qual, name) => // make not private symbol acessed from inner classes, as well as // symbols accessed from @inline methods + // + // See SI-6552 for an example of why `sym.owner.enclMethod hasAnnotation ScalaInlineClass` + // is not suitable; if we make a method-local class non-private, it mangles outer pointer names. if (currentClass != sym.owner || - (sym.owner.enclMethod hasAnnotation ScalaInlineClass)) + (closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass)) sym.makeNotPrivate(sym.owner) val qsym = qual.tpe.widen.typeSymbol diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 981ba10183..6b9848a1c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -234,14 +234,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case sel @ Select(qual, name) => def transformSelect = { - /** return closest enclosing method, unless shadowed by an enclosing class; - * no use of closures here in the interest of speed. - */ - def closestEnclMethod(from: Symbol): Symbol = - if (from.isSourceMethod) from - else if (from.isClass) NoSymbol - else closestEnclMethod(from.owner) + // FIXME Once Inliners is modified with the "'meta-knowledge' that all fields accessed by @inline will be made public" [1] + // this can be removed; the correct place for this in in ExplicitOuter. + // + // [1] https://groups.google.com/forum/#!topic/scala-internals/iPkMCygzws4 + // if (closestEnclMethod(currentOwner) hasAnnotation definitions.ScalaInlineClass) sym.makeNotPrivate(sym.owner) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index a6f156f947..4afebab493 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -3269,6 +3269,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f) + /** Return closest enclosing method, unless shadowed by an enclosing class. */ + // TODO Move back to ExplicitOuter when the other call site is removed. + // no use of closures here in the interest of speed. + final def closestEnclMethod(from: Symbol): Symbol = + if (from.isSourceMethod) from + else if (from.isClass) NoSymbol + else closestEnclMethod(from.owner) + /** An exception for cyclic references of symbol definitions */ case class CyclicReference(sym: Symbol, info: Type) extends TypeError("illegal cyclic reference involving " + sym) { diff --git a/test/files/pos/t6562.scala b/test/files/pos/t6562.scala new file mode 100644 index 0000000000..eec7aa5199 --- /dev/null +++ b/test/files/pos/t6562.scala @@ -0,0 +1,14 @@ +class Test { + + @inline + def foo { + def it = new {} + (_: Any) => it + } + + @inline + private def bar { + def it = new {} + (_: Any) => it + } +} |