diff options
Diffstat (limited to 'src/compiler')
10 files changed, 77 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 618bf3b9b3..4768417c67 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -2700,7 +2700,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self => case CMPG => (kind: @unchecked) match { case FLOAT => emit(Opcodes.FCMPG) - case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se5.0/html/Instructions2.doc3.html + case DOUBLE => emit(Opcodes.DCMPL) // TODO bug? why not DCMPG? http://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc3.html } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala index 2c4a0ad3c3..6b2786c1a3 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -705,9 +705,9 @@ class Inliner[BT <: BTypes](val btypes: BT) { // - a method name+type // // execution [3] - // - resolve the CSP, yielding the boostrap method handle, the static args and the name+type + // - resolve the CSP, yielding the bootstrap method handle, the static args and the name+type // - resolution entails accessibility checking [4] - // - execute the `invoke` method of the boostrap method handle (which is signature polymorphic, check its javadoc) + // - execute the `invoke` method of the bootstrap method handle (which is signature polymorphic, check its javadoc) // - the descriptor for the call is made up from the actual arguments on the stack: // - the first parameters are "MethodHandles.Lookup, String, MethodType", then the types of the constant arguments, // - the return type is CallSite diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala index 2967f67e9c..efb026cdff 100644 --- a/src/compiler/scala/tools/nsc/io/Jar.scala +++ b/src/compiler/scala/tools/nsc/io/Jar.scala @@ -154,7 +154,7 @@ object Jar { def update(key: Attributes.Name, value: String) = attrs.put(key, value) } - // See http://download.java.net/jdk7/docs/api/java/nio/file/Path.html + // See http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html // for some ideas. private val ZipMagicNumber = List[Byte](80, 75, 3, 4) private def magicNumberIsZip(f: Path) = f.isFile && (f.toFile.bytes().take(4).toList == ZipMagicNumber) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 79776485de..82e7c76409 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -111,7 +111,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => impl setInfo new LazyImplClassType(iface) } - /** Return the implementation class of a trait; create a new one of one does not yet exist */ + /** Return the implementation class of a trait; create a new one if one does not yet exist */ def implClass(iface: Symbol): Symbol = { iface.info diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 5a7f6c52da..ea8c1cbaf6 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -281,7 +281,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val parents = addSerializable(abstractFunctionErasedType) val funOwner = originalFunction.symbol.owner - // TODO harmonize the naming of delamdafy anon-fun classes with those spun up by Uncurry + // TODO harmonize the naming of delambdafy anon-fun classes with those spun up by Uncurry // - make `anonClass.isAnonymousClass` true. // - use `newAnonymousClassSymbol` or push the required variations into a similar factory method // - reinstate the assertion in `Erasure.resolveAnonymousBridgeClash` diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 7a9dfda43e..163c44822e 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -691,9 +691,46 @@ abstract class UnCurry extends InfoTransform // declared type and assign this to a synthetic val. Later, we'll patch // the method body to refer to this, rather than the parameter. val tempVal: ValDef = { + // SI-9442: using the "uncurry-erased" type (the one after the uncurry phase) can lead to incorrect + // tree transformations. For example, compiling: + // ``` + // def foo(c: Ctx)(l: c.Tree): Unit = { + // val l2: c.Tree = l + // } + // ``` + // Results in the following AST: + // ``` + // def foo(c: Ctx, l: Ctx#Tree): Unit = { + // val l$1: Ctx#Tree = l.asInstanceOf[Ctx#Tree] + // val l2: c.Tree = l$1 // no, not really, it's not. + // } + // ``` + // Of course, this is incorrect, since `l$1` has type `Ctx#Tree`, which is not a subtype of `c.Tree`. + // + // So what we need to do is to use the pre-uncurry type when creating `l$1`, which is `c.Tree` and is + // correct. Now, there are two additional problems: + // 1. when varargs and byname params are involved, the uncurry transformation desugares these special + // cases to actual typerefs, eg: + // ``` + // T* ~> Seq[T] (Scala-defined varargs) + // T* ~> Array[T] (Java-defined varargs) + // =>T ~> Function0[T] (by name params) + // ``` + // we use the DesugaredParameterType object (defined in scala.reflect.internal.transform.UnCurry) + // to redo this desugaring manually here + // 2. the type needs to be normalized, since `gen.mkCast` checks this (no HK here, just aliases have + // to be expanded before handing the type to `gen.mkAttributedCast`, which calls `gen.mkCast`) + val info0 = + enteringUncurry(p.symbol.info) match { + case DesugaredParameterType(desugaredTpe) => + desugaredTpe + case tpe => + tpe + } + val info = info0.normalize val tempValName = unit freshTermName (p.name + "$") - val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(p.symbol.info) - atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), p.symbol.info))) + val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(info) + atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), info))) } Packed(newParam, tempVal) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 031245346b..3ed128cbc5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -55,6 +55,13 @@ trait Macros extends MacroRuntimes with Traces with Helpers { def globalSettings = global.settings + /** Obtains a `ClassLoader` instance used for macro expansion. + * + * By default a new `ScalaClassLoader` is created using the classpath + * from global and the classloader of self as parent. + * + * Mirrors with runtime definitions (e.g. Repl) need to adjust this method. + */ protected def findMacroClassLoader(): ClassLoader = { val classpath = global.classPath.asURLs macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath)) diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index a7d48ceb89..e8db8309f1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -262,7 +262,14 @@ abstract class TreeCheckers extends Analyzer { checkedTyped(tree, mode, pt) ) private def checkedTyped(tree: Tree, mode: Mode, pt: Type): Tree = { - val typed = wrap(tree)(super.typed(tree, mode, pt)) + val typed = wrap(tree)(super.typed(tree.clearType(), mode, pt)) + + // Vlad: super.typed returns null for package defs, why is that? + if (typed eq null) + return tree + + if (typed.tpe ne null) + assert(!typed.tpe.isErroneous, "Tree has erroneous type: " + typed) if (tree ne typed) treesDiffer(tree, typed) diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 8d4d07759f..2811520b67 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -22,7 +22,7 @@ import Jar.isJarOrZip /** <p> * This module provides star expansion of '-classpath' option arguments, behaves the same as - * java, see [http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html] + * java, see [[http://docs.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html]] * </p> * * @author Stepan Koltsov diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala index ac63232967..e30d1ed7cd 100644 --- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala +++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala @@ -1,9 +1,11 @@ package scala.tools package reflect +import scala.reflect.internal.util.ScalaClassLoader import scala.tools.nsc.Global import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.Settings +import scala.tools.nsc.typechecker.Analyzer /** A version of Global that uses reflection to get class * infos, instead of reading class or source files. @@ -11,6 +13,20 @@ import scala.tools.nsc.Settings class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val rootClassLoader: ClassLoader) extends Global(currentSettings, reporter) with scala.tools.reflect.ReflectSetup with scala.reflect.runtime.SymbolTable { + override lazy val analyzer = new { + val global: ReflectGlobal.this.type = ReflectGlobal.this + } with Analyzer { + /** Obtains the classLoader used for runtime macro expansion. + * + * Macro expansion can use everything available in [[global.classPath]] or [[rootClassLoader]]. + * The [[rootClassLoader]] is used to obtain runtime defined macros. + */ + override protected def findMacroClassLoader(): ClassLoader = { + val classpath = global.classPath.asURLs + ScalaClassLoader.fromURLs(classpath, rootClassLoader) + } + } + override def transformedType(sym: Symbol) = postErasure.transformInfo(sym, erasure.transformInfo(sym, |