summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-03-28 21:37:39 -0700
committerPaul Phillips <paulp@improving.org>2013-03-28 21:38:30 -0700
commit5ddad9257162b47526ac1df9cc39c056b206377e (patch)
treed0e4a3f61a8aa78e6e46559fb3c874d0b5a86494
parentdf103faa5d5251d34a99a04f8d8b2b2786e6d3ab (diff)
parent395e90a786874ebe795e656f532b50110c8c1a98 (diff)
downloadscala-5ddad9257162b47526ac1df9cc39c056b206377e.tar.gz
scala-5ddad9257162b47526ac1df9cc39c056b206377e.tar.bz2
scala-5ddad9257162b47526ac1df9cc39c056b206377e.zip
Merge commit '395e90a786' into pr/merge-395e90a786
* commit '395e90a786': SI-7251, compiler crash with $. SI-7240 fixes language feature lookup SI-7233 Account for aliased imports in Erasure SI-7233 Account for aliased imports in eta expansion. SI-7132 - don't discard Unit type in interpreter SI-6725 `f` interpolator now supports %n tokens Conflicts: src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala221
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala1
-rw-r--r--src/compiler/scala/tools/reflect/MacroImplementations.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--test/files/neg/t7251.check4
-rw-r--r--test/files/neg/t7251/A_1.scala10
-rw-r--r--test/files/neg/t7251/B_2.scala7
-rw-r--r--test/files/pos/t7233.scala14
-rw-r--r--test/files/pos/t7233b.scala8
-rw-r--r--test/files/run/t6725-1.check2
-rw-r--r--test/files/run/t6725-1.scala5
-rw-r--r--test/files/run/t6725-2.check8
-rw-r--r--test/files/run/t6725-2.scala6
-rw-r--r--test/files/run/t7240.check0
-rw-r--r--test/files/run/t7240/Macros_1.scala48
-rw-r--r--test/files/run/t7240/Test_2.scala3
18 files changed, 227 insertions, 119 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 9d84ca1959..1206748b24 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -43,7 +43,7 @@ abstract class ClassfileParser {
def srcfile = srcfile0
- private def currentIsTopLevel = currentClass.toString.indexOf('$') < 0
+ private def currentIsTopLevel = !(currentClass.decodedName containsChar '$')
private object unpickler extends scala.reflect.internal.pickling.UnPickler {
val global: ClassfileParser.this.global.type = ClassfileParser.this.global
@@ -435,63 +435,59 @@ abstract class ClassfileParser {
sym
}
- /** Return the class symbol of the given name. */
- def classNameToSymbol(name: Name): Symbol = {
- def loadClassSymbol(name: Name): Symbol = {
- val file = global.classPath findSourceFile ("" +name) getOrElse {
- // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
- // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects
- // that are not in their correct place (see bug for details)
- if (!settings.isScaladoc)
- warning("Class " + name + " not found - continuing with a stub.")
- return NoSymbol.newClass(name.toTypeName)
- }
- val completer = new global.loaders.ClassfileLoader(file)
- var owner: Symbol = rootMirror.RootClass
- var sym: Symbol = NoSymbol
- var ss: Name = null
- var start = 0
- var end = name indexOf '.'
-
- while (end > 0) {
- ss = name.subName(start, end)
- sym = owner.info.decls lookup ss
- if (sym == NoSymbol) {
- sym = owner.newPackage(ss.toTermName) setInfo completer
- sym.moduleClass setInfo completer
- owner.info.decls enter sym
- }
- owner = sym.moduleClass
- start = end + 1
- end = name.indexOf('.', start)
- }
- ss = name.subName(0, start)
- owner.info.decls lookup ss orElse {
- sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer
- debuglog("loaded "+sym+" from file "+file)
- sym
+ private def loadClassSymbol(name: Name): Symbol = {
+ val file = global.classPath findSourceFile ("" +name) getOrElse {
+ // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
+ // therefore, it will rummage through the classpath triggering errors whenever it encounters package objects
+ // that are not in their correct place (see bug for details)
+ if (!settings.isScaladoc)
+ warning(s"Class $name not found - continuing with a stub.")
+ return NoSymbol.newClass(name.toTypeName)
+ }
+ val completer = new global.loaders.ClassfileLoader(file)
+ var owner: Symbol = rootMirror.RootClass
+ var sym: Symbol = NoSymbol
+ var ss: Name = null
+ var start = 0
+ var end = name indexOf '.'
+
+ while (end > 0) {
+ ss = name.subName(start, end)
+ sym = owner.info.decls lookup ss
+ if (sym == NoSymbol) {
+ sym = owner.newPackage(ss.toTermName) setInfo completer
+ sym.moduleClass setInfo completer
+ owner.info.decls enter sym
}
+ owner = sym.moduleClass
+ start = end + 1
+ end = name.indexOf('.', start)
}
-
- def lookupClass(name: Name) = try {
- if (name.pos('.') == name.length)
- definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName)
- else
- rootMirror.getClassByName(name) // see tickets #2464, #3756
- } catch {
- case _: FatalError => loadClassSymbol(name)
+ ss = name.subName(0, start)
+ owner.info.decls lookup ss orElse {
+ sym = owner.newClass(ss.toTypeName) setInfoAndEnter completer
+ debuglog("loaded "+sym+" from file "+file)
+ sym
}
+ }
- innerClasses.get(name) match {
- case Some(entry) =>
- //println("found inner class " + name)
- val res = innerClasses.classSymbol(entry.externalName)
- //println("\trouted to: " + res)
- res
- case None =>
- //if (name.toString.contains("$")) println("No inner class: " + name + innerClasses + " while parsing " + in.file.name)
- lookupClass(name)
- }
+ /** FIXME - we shouldn't be doing ad hoc lookups in the empty package.
+ * The method called "getClassByName" should either return the class or not.
+ */
+ private def lookupClass(name: Name) = (
+ if (name containsChar '.')
+ rootMirror getClassByName name // see tickets #2464, #3756
+ else
+ definitions.getMember(rootMirror.EmptyPackageClass, name.toTypeName)
+ )
+
+ /** Return the class symbol of the given name. */
+ def classNameToSymbol(name: Name): Symbol = {
+ if (innerClasses contains name)
+ innerClasses innerSymbol name
+ else
+ try lookupClass(name)
+ catch { case _: FatalError => loadClassSymbol(name) }
}
var sawPrivateConstructor = false
@@ -645,7 +641,7 @@ abstract class ClassfileParser {
info match {
case MethodType(params, restpe) =>
// if this is a non-static inner class, remove the explicit outer parameter
- val newParams = innerClasses.get(currentClass) match {
+ val newParams = innerClasses getEntry currentClass match {
case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) =>
/* About `clazz.owner.isPackage` below: SI-5957
* For every nested java class A$B, there are two symbols in the scala compiler.
@@ -743,7 +739,7 @@ abstract class ClassfileParser {
// raw type - existentially quantify all type parameters
else logResult(s"raw type from $classSym")(definitions.unsafeClassExistentialType(classSym))
case tp =>
- assert(sig.charAt(index) != '<', tp)
+ assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")
tp
}
@@ -1102,7 +1098,7 @@ abstract class ClassfileParser {
unlinkIfPresent(cName.toTypeName)
}
- for (entry <- innerClasses.values) {
+ for (entry <- innerClasses.entries) {
// create a new class member for immediate inner classes
if (entry.outerName == currentClass) {
val file = global.classPath.findSourceFile(entry.externalName.toString) getOrElse {
@@ -1140,14 +1136,9 @@ abstract class ClassfileParser {
case tpnme.InnerClassesATTR if !isScala =>
val entries = in.nextChar.toInt
for (i <- 0 until entries) {
- val innerIndex = in.nextChar.toInt
- val outerIndex = in.nextChar.toInt
- val nameIndex = in.nextChar.toInt
- val jflags = in.nextChar.toInt
- if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0) {
- val entry = InnerClassEntry(innerIndex, outerIndex, nameIndex, jflags)
- innerClasses += (pool.getClassName(innerIndex) -> entry)
- }
+ val innerIndex, outerIndex, nameIndex, jflags = in.nextChar.toInt
+ if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0)
+ innerClasses add InnerClassEntry(innerIndex, outerIndex, nameIndex, jflags)
}
case _ =>
in.skip(attrLen)
@@ -1161,58 +1152,58 @@ abstract class ClassfileParser {
def externalName = pool getClassName external
def outerName = pool getClassName outer
def originalName = pool getName name
-
- override def toString =
- originalName + " in " + outerName + "(" + externalName +")"
+ def isStatic = ClassfileParser.this.isStatic(jflags)
+ def isModule = originalName.isTermName
+ def scope = if (isStatic) staticScope else instanceScope
+ def enclosing = if (isStatic) enclModule else enclClass
+
+ // The name of the outer class, without its trailing $ if it has one.
+ private def strippedOuter = nme stripModuleSuffix outerName
+ private def isInner = innerClasses contains strippedOuter
+ private def enclClass = if (isInner) innerClasses innerSymbol strippedOuter else classNameToSymbol(strippedOuter)
+ private def enclModule = enclClass.companionModule
}
- object innerClasses extends mutable.HashMap[Name, InnerClassEntry] {
- /** Return the class symbol for `externalName`. It looks it up in its outer class.
- * Forces all outer class symbols to be completed.
- *
- * If the given name is not an inner class, it returns the symbol found in `definitions`.
- */
- def classSymbol(externalName: Name): Symbol = {
- /* Return the symbol of `innerName`, having the given `externalName`. */
- def innerSymbol(externalName: Name, innerName: Name, static: Boolean): Symbol = {
- def getMember(sym: Symbol, name: Name): Symbol =
- if (static)
- if (sym == clazz) staticScope.lookup(name)
- else sym.companionModule.info.member(name)
- else
- if (sym == clazz) instanceScope.lookup(name)
- else sym.info.member(name)
-
- innerClasses.get(externalName) match {
- case Some(entry) =>
- val outerName = entry.outerName.dropModule
- val sym = classSymbol(outerName)
- val s =
- // if loading during initialization of `definitions` typerPhase is not yet set.
- // in that case we simply load the member at the current phase
- if (currentRun.typerPhase != null)
- enteringTyper(getMember(sym, innerName.toTypeName))
- else
- getMember(sym, innerName.toTypeName)
-
- assert(s ne NoSymbol,
- "" + ((externalName, outerName, innerName, sym.fullLocationString)) + " / " +
- " while parsing " + ((in.file, busy)) +
- sym + "." + innerName + " linkedModule: " + sym.companionModule + sym.companionModule.info.members
- )
- s
-
- case None =>
- classNameToSymbol(externalName)
- }
- }
-
- get(externalName) match {
- case Some(entry) =>
- innerSymbol(entry.externalName, entry.originalName, isStatic(entry.jflags))
- case None =>
- classNameToSymbol(externalName)
- }
+ /** Return the class symbol for the given name. It looks it up in its outer class.
+ * Forces all outer class symbols to be completed.
+ *
+ * If the given name is not an inner class, it returns the symbol found in `definitions`.
+ */
+ object innerClasses {
+ private val inners = mutable.HashMap[Name, InnerClassEntry]()
+
+ def contains(name: Name) = inners contains name
+ def getEntry(name: Name) = inners get name
+ def entries = inners.values
+
+ def add(entry: InnerClassEntry): Unit = {
+ inners get entry.externalName foreach (existing =>
+ debugwarn(s"Overwriting inner class entry! Was $existing, now $entry")
+ )
+ inners(entry.externalName) = entry
+ }
+ def innerSymbol(externalName: Name): Symbol = this getEntry externalName match {
+ case Some(entry) => innerSymbol(entry)
+ case _ => NoSymbol
+ }
+ // if loading during initialization of `definitions` typerPhase is not yet set.
+ // in that case we simply load the member at the current phase
+ @inline private def enteringTyperIfPossible(body: => Symbol): Symbol =
+ if (currentRun.typerPhase eq null) body else enteringTyper(body)
+
+ private def innerSymbol(entry: InnerClassEntry): Symbol = {
+ val name = entry.originalName.toTypeName
+ val enclosing = entry.enclosing
+ def getMember = (
+ if (enclosing == clazz) entry.scope lookup name
+ else enclosing.info member name
+ )
+ enteringTyperIfPossible(getMember)
+ /** There used to be an assertion that this result is not NoSymbol; changing it to an error
+ * revealed it had been going off all the time, but has been swallowed by a catch t: Throwable
+ * in Repository.scala. Since it has been accomplishing nothing except misleading anyone who
+ * thought it wasn't triggering, I removed it entirely.
+ */
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 857c01c49a..e6cf5e6346 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -730,7 +730,7 @@ abstract class Erasure extends AddInterfaces
else if (tree.symbol == Any_isInstanceOf)
adaptMember(atPos(tree.pos)(Select(qual, Object_isInstanceOf)))
else if (tree.symbol.owner == AnyClass)
- adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, name))))
+ adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, tree.symbol.name))))
else {
var qual1 = typedQualifier(qual)
if ((isPrimitiveValueType(qual1.tpe) && !isPrimitiveValueMember(tree.symbol)) ||
diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
index 282dd8a99d..4075aa26f7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
@@ -98,6 +98,7 @@ trait EtaExpansion { self: Analyzer =>
case TypeApply(fn, args) =>
treeCopy.TypeApply(tree, liftoutPrefix(fn), args).clearType()
case Select(qual, name) =>
+ val name = tree.symbol.name // account for renamed imports, SI-7233
treeCopy.Select(tree, liftout(qual, byName = false), name).clearType() setSymbol NoSymbol
case Ident(name) =>
tree
diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala
index 002a3fce82..4e8f02084d 100644
--- a/src/compiler/scala/tools/reflect/MacroImplementations.scala
+++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala
@@ -117,7 +117,8 @@ abstract class MacroImplementations {
if (!strIsEmpty) {
val len = str.length
while (idx < len) {
- if (str(idx) == '%') {
+ def notPercentN = str(idx) != '%' || (idx + 1 < len && str(idx + 1) != 'n')
+ if (str(idx) == '%' && notPercentN) {
bldr append (str substring (start, idx)) append "%%"
start = idx + 1
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index db6f05294b..5392daf674 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -973,7 +973,7 @@ trait Definitions extends api.StandardDefinitions {
getMemberIfDefined(owner, name) orElse {
if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) {
val pkg = owner.owner
- val flatname = nme.flattenedName(owner.name, name)
+ val flatname = tpnme.flattenedName(owner.name, name)
getMember(pkg, flatname)
}
else fatalMissingSymbol(owner, name)
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 547fcdcfa7..037d44c540 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -3063,7 +3063,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (Statistics.canEnable) Statistics.incCounter(nameCount)
if (needsFlatClasses) {
if (flatname eq null)
- flatname = nme.flattenedName(rawowner.name, rawname).toTypeName
+ flatname = tpnme.flattenedName(rawowner.name, rawname)
flatname
}
diff --git a/test/files/neg/t7251.check b/test/files/neg/t7251.check
new file mode 100644
index 0000000000..8df8984d63
--- /dev/null
+++ b/test/files/neg/t7251.check
@@ -0,0 +1,4 @@
+B_2.scala:5: error: object s.Outer$Triple$ is not a value
+ println( s.Outer$Triple$ )
+ ^
+one error found
diff --git a/test/files/neg/t7251/A_1.scala b/test/files/neg/t7251/A_1.scala
new file mode 100644
index 0000000000..d05373ed28
--- /dev/null
+++ b/test/files/neg/t7251/A_1.scala
@@ -0,0 +1,10 @@
+package s
+
+object Outer {
+ type Triple[+A, +B, +C] = Tuple3[A, B, C]
+ object Triple {
+ def apply[A, B, C](x: A, y: B, z: C) = Tuple3(x, y, z)
+ def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x)
+ }
+}
+
diff --git a/test/files/neg/t7251/B_2.scala b/test/files/neg/t7251/B_2.scala
new file mode 100644
index 0000000000..eb59b30902
--- /dev/null
+++ b/test/files/neg/t7251/B_2.scala
@@ -0,0 +1,7 @@
+package s
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ println( s.Outer$Triple$ )
+ }
+}
diff --git a/test/files/pos/t7233.scala b/test/files/pos/t7233.scala
new file mode 100644
index 0000000000..ae15c08c35
--- /dev/null
+++ b/test/files/pos/t7233.scala
@@ -0,0 +1,14 @@
+object Foo {
+ def bar(i: Int) = i
+
+ def ol(i: Int) = i
+ def ol(i: String) = i
+}
+object Test {
+ import Foo.{ bar => quux, toString => bar, ol => olRenamed}
+
+ val f1 = quux _
+ val f1Typed: (Int => Int) = f1
+
+ val f2: String => String = olRenamed _
+}
diff --git a/test/files/pos/t7233b.scala b/test/files/pos/t7233b.scala
new file mode 100644
index 0000000000..927c7fcfd1
--- /dev/null
+++ b/test/files/pos/t7233b.scala
@@ -0,0 +1,8 @@
+object Test {
+ // crash
+ def foo(a: Any) = { import a.{toString => toS}; toS }
+
+ // okay
+ def ok1(a: String) = { import a.{isInstanceOf => iio}; iio[String] }
+ def ok2(a: Int) = { import a.{toInt => ti}; ti }
+}
diff --git a/test/files/run/t6725-1.check b/test/files/run/t6725-1.check
new file mode 100644
index 0000000000..6ed281c757
--- /dev/null
+++ b/test/files/run/t6725-1.check
@@ -0,0 +1,2 @@
+1
+1
diff --git a/test/files/run/t6725-1.scala b/test/files/run/t6725-1.scala
new file mode 100644
index 0000000000..a167ef8aa3
--- /dev/null
+++ b/test/files/run/t6725-1.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ val a = 1
+ val s = f"$a%s%n$a%s"
+ println(s)
+} \ No newline at end of file
diff --git a/test/files/run/t6725-2.check b/test/files/run/t6725-2.check
new file mode 100644
index 0000000000..3496917ad5
--- /dev/null
+++ b/test/files/run/t6725-2.check
@@ -0,0 +1,8 @@
+
+
+aaaa
+
+
+aaaa
+aaaa
+aaaa
diff --git a/test/files/run/t6725-2.scala b/test/files/run/t6725-2.scala
new file mode 100644
index 0000000000..e033cf5ea8
--- /dev/null
+++ b/test/files/run/t6725-2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ println(f"%n")
+ println(f"aaaa%n")
+ println(f"%naaaa")
+ println(f"aaaa%naaaa")
+} \ No newline at end of file
diff --git a/test/files/run/t7240.check b/test/files/run/t7240.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/t7240.check
diff --git a/test/files/run/t7240/Macros_1.scala b/test/files/run/t7240/Macros_1.scala
new file mode 100644
index 0000000000..6465e18760
--- /dev/null
+++ b/test/files/run/t7240/Macros_1.scala
@@ -0,0 +1,48 @@
+package bakery
+
+import scala.language.experimental.macros
+import scala.reflect.macros.Context
+
+trait FailureCake {
+ implicit def liftAnyFails[T: Manifest]: Any = ???
+
+ // This works
+ // implicit def liftAny[T]: Any = ???
+}
+
+object Bakery {
+
+ def failure: Any = macro failureImpl
+ def failureImpl(c: Context): c.Expr[Any] = {
+ import c.universe._
+
+ def dslTrait(dslName: String) = {
+ val names = dslName.split("\\.").toList.reverse
+ assert(names.length >= 1, "DSL trait name must be in the valid format. DSL trait name is " + dslName)
+
+ val tpeName = newTypeName(names.head)
+ names.tail.reverse match {
+ case head :: tail ⇒
+ Select(tail.foldLeft[Tree](Ident(newTermName(head)))((tree, name) ⇒ Select(tree, newTermName(name))), tpeName)
+ case Nil ⇒
+ Ident(tpeName)
+ }
+ }
+
+ def composeDSL(transformedBody: Tree) =
+ ClassDef(Modifiers(), newTypeName("eval"), List(), Template(
+ List(dslTrait("bakery.FailureCake")),
+ emptyValDef,
+ List(
+ DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(),
+ Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))),
+ DefDef(Modifiers(), newTermName("main"), List(), List(List()), Ident(newTypeName("Any")), transformedBody))))
+
+ def constructor = Apply(Select(New(Ident(newTypeName("eval"))), nme.CONSTRUCTOR), List())
+
+ c.eval(c.Expr[Any](
+ c.resetAllAttrs(Block(composeDSL(Literal(Constant(1))), constructor))))
+
+ c.Expr[Any](Literal(Constant(1)))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t7240/Test_2.scala b/test/files/run/t7240/Test_2.scala
new file mode 100644
index 0000000000..2450bdabf9
--- /dev/null
+++ b/test/files/run/t7240/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ bakery.Bakery.failure
+} \ No newline at end of file