Skip to content

Commit

Permalink
Merge pull request scala#1561 from gkossakowski/ticket/6562
Browse files Browse the repository at this point in the history
SI-6562 Fix crash with class nested in @inline method
  • Loading branch information
adriaanm committed Nov 3, 2012
2 parents f8ed076 + a525d37 commit 424072a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 5 additions & 7 deletions src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
8 changes: 8 additions & 0 deletions src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
14 changes: 14 additions & 0 deletions test/files/pos/t6562.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Test {

@inline
def foo {
def it = new {}
(_: Any) => it
}

@inline
private def bar {
def it = new {}
(_: Any) => it
}
}

0 comments on commit 424072a

Please sign in to comment.