diff options
44 files changed, 297 insertions, 49 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 10c1da59b8..e82c0fd16d 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -4,8 +4,8 @@ filter { # "scala.concurrent.impl" # "scala.reflect.runtime" ] - // see SI-8372 problems=[ + // see SI-8372 { matchName="scala.collection.mutable.ArrayOps#ofChar.unzip" problemName=IncompatibleMethTypeProblem @@ -101,6 +101,27 @@ filter { { matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3" problemName=IncompatibleMethTypeProblem + }, + // see SI-8331 + { + matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAppliedType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectTerm" + problemName=MissingMethodProblem } ] -}
\ No newline at end of file +} diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 96994f8969..f9bd0441a2 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -4,8 +4,8 @@ filter { # "scala.concurrent.impl" # "scala.reflect.runtime" ] - // see SI-8372 problems=[ + // see SI-8372 { matchName="scala.collection.mutable.ArrayOps#ofChar.unzip" problemName=IncompatibleMethTypeProblem @@ -101,6 +101,35 @@ filter { { matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3" problemName=IncompatibleMethTypeProblem + }, + // see SI-8331 + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAppliedType" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSelectTerm" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticSelectTermExtractor" + problemName=MissingClassProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply" + problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.api.Internals#ReificationSupportApi#SyntacticTypeAppliedExtractor.unapply" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticSelectTypeExtractor" + problemName=MissingClassProblem } ] } diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl index 88fee71843..194d92367b 100644 --- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl +++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl @@ -144,6 +144,10 @@ classpathArgs () { fi } +# SI-8358, SI-8368 -- the default should really be false, +# but I don't want to flip the default during 2.11's RC cycle +OVERRIDE_USEJAVACP="-Dscala.usejavacp=true" + while [[ $# -gt 0 ]]; do case "$1" in -D*) @@ -151,6 +155,8 @@ while [[ $# -gt 0 ]]; do # need it, e.g. communicating with a server compiler. java_args=("${java_args[@@]}" "$1") scala_args=("${scala_args[@@]}" "$1") + # respect user-supplied -Dscala.usejavacp + case "$1" in -Dscala.usejavacp) OVERRIDE_USEJAVACP="" esac shift ;; -J*) @@ -199,7 +205,7 @@ execCommand \ "${java_args[@@]}" \ $(classpathArgs) \ -Dscala.home="$SCALA_HOME" \ - -Dscala.usejavacp=true \ + $OVERRIDE_USEJAVACP \ "$EMACS_OPT" \ $WINDOWS_OPT \ @properties@ @class@ @toolflags@ "$@@" diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index bd2f6f0018..e036035397 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -600,7 +600,7 @@ abstract class Erasure extends AddInterfaces if (tree.symbol == NoSymbol) { tree } else if (name == nme.CONSTRUCTOR) { - if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.info.decl(nme.CONSTRUCTOR) + if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor tree } else if (tree.symbol == Any_asInstanceOf) adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf))) diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 2043eb5d5d..d439bb5603 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -725,11 +725,18 @@ trait ContextErrors { NormalTypeError(expandee, "too many argument lists for " + fun) } - def MacroIncompatibleEngineError(macroEngine: String) = { - val message = s"macro cannot be expanded, because it was compiled by an incompatible macro engine $macroEngine" + private def MacroIncompatibleEngineError(friendlyMessage: String, internalMessage: String) = { + def debugDiagnostic = s"(internal diagnostic: $internalMessage)" + val message = if (macroDebugLite || macroDebugVerbose) s"$friendlyMessage $debugDiagnostic" else friendlyMessage issueNormalTypeError(lastTreeToTyper, message) } + def MacroCantExpand210xMacrosError(internalMessage: String) = + MacroIncompatibleEngineError("can't expand macros compiled by previous versions of Scala", internalMessage) + + def MacroCantExpandIncompatibleMacrosError(internalMessage: String) = + MacroIncompatibleEngineError("macro cannot be expanded, because it was compiled by an incompatible macro engine", internalMessage) + case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 98ee4ad94d..133e80788b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -652,6 +652,13 @@ trait Contexts { self: Analyzer => c } + def enclosingNonImportContext: Context = { + var c = this + while (c != NoContext && c.tree.isInstanceOf[Import]) + c = c.outer + c + } + /** Is `sym` accessible as a member of `pre` in current context? */ def isAccessible(sym: Symbol, pre: Type, superAccess: Boolean = false): Boolean = { lastAccessCheckDetails = "" diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 677c94e063..9cf92ca5b9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -224,7 +224,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { val Apply(_, pickledPayload) = wrapped val payload = pickledPayload.map{ case Assign(k, v) => (unpickleAtom(k), unpickleAtom(v)) }.toMap - def fail(msg: String) = abort(s"bad macro impl binding: $msg") + import typer.TyperErrorGen._ + def fail(msg: String) = MacroCantExpandIncompatibleMacrosError(msg) def unpickle[T](field: String, clazz: Class[T]): T = { def failField(msg: String) = fail(s"$field $msg") if (!payload.contains(field)) failField("is supposed to be there") @@ -236,8 +237,9 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { raw.asInstanceOf[T] } + if (!payload.contains("macroEngine")) MacroCantExpand210xMacrosError("macroEngine field not found") val macroEngine = unpickle("macroEngine", classOf[String]) - if (self.macroEngine != macroEngine) typer.TyperErrorGen.MacroIncompatibleEngineError(macroEngine) + if (self.macroEngine != macroEngine) MacroCantExpandIncompatibleMacrosError(s"expected = ${self.macroEngine}, actual = $macroEngine") val isBundle = unpickle("isBundle", classOf[Boolean]) val isBlackbox = unpickle("isBlackbox", classOf[Boolean]) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2e1ed0863a..9f3f257529 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3946,7 +3946,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper * - simplest solution: have two method calls * */ - def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = { + def mkInvoke(context: Context, tree: Tree, qual: Tree, name: Name): Option[Tree] = { + val cxTree = context.enclosingNonImportContext.tree // SI-8364 debuglog(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)") val treeInfo.Applied(treeSelection, _, _) = tree def isDesugaredApply = { @@ -4608,7 +4609,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper t } def typedSelectInternal(tree: Tree, qual: Tree, name: Name): Tree = { - def asDynamicCall = dyna.mkInvoke(context.tree, tree, qual, name) map { t => + def asDynamicCall = dyna.mkInvoke(context, tree, qual, name) map { t => dyna.wrapErrors(t, (_.typed1(t, mode, pt))) } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index f8b5e7b6bd..850030e9ba 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -189,6 +189,8 @@ trait Reifiers { self: Quasiquotes => reifyBuildCall(nme.SyntacticApplied, fun, argss) case SyntacticTypeApplied(fun, targs) if targs.nonEmpty => reifyBuildCall(nme.SyntacticTypeApplied, fun, targs) + case SyntacticAppliedType(tpt, targs) if targs.nonEmpty => + reifyBuildCall(nme.SyntacticAppliedType, tpt, targs) case SyntacticFunction(args, body) => reifyBuildCall(nme.SyntacticFunction, args, body) case SyntacticIdent(name, isBackquoted) => @@ -219,6 +221,9 @@ trait Reifiers { self: Quasiquotes => // correctness of the trees produced by quasiquotes case Select(id @ Ident(nme.scala_), name) if id.symbol == ScalaPackage => reifyBuildCall(nme.ScalaDot, name) + case Select(qual, name) => + val ctor = if (name.isTypeName) nme.SyntacticSelectType else nme.SyntacticSelectTerm + reifyBuildCall(ctor, qual, name) case _ => super.reifyTreeSyntactically(tree) } diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 9ff648a05a..7f4a9dc45d 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -94,7 +94,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self => * Note that expression `pf.applyOrElse(x, default)` is equivalent to * {{{ if(pf isDefinedAt x) pf(x) else default(x) }}} * except that `applyOrElse` method can be implemented more efficiently. - * For all partial function literals compiler generates `applyOrElse` implementation which + * For all partial function literals the compiler generates an `applyOrElse` implementation which * avoids double evaluation of pattern matchers and guards. * This makes `applyOrElse` the basis for the efficient implementation for many operations and scenarios, such as: * diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index a55432fd71..a1e94c8876 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -14,8 +14,13 @@ import scala.annotation.implicitNotFound import scala.util.Try /** - * An `ExecutionContext` can execute program logic, typically but not - * necessarily on a thread pool. + * An `ExecutionContext` can execute program logic asynchronously, + * typically but not necessarily on a thread pool. + * + * A general purpose `ExecutionContext` must be asynchronous in executing + * any `Runnable` that is passed into its `execute`-method. A special purpose + * `ExecutionContext` may be synchronous but must only be passed to code that + * is explicitly safe to be run using a synchronously executing `ExecutionContext`. * * APIs such as `Future.onComplete` require you to provide a callback * and an implicit `ExecutionContext`. The implicit `ExecutionContext` diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala index 01f928ed61..d2e742726d 100644 --- a/src/reflect/scala/reflect/api/Internals.scala +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -600,10 +600,11 @@ trait Internals { self: Universe => } val SyntacticTypeApplied: SyntacticTypeAppliedExtractor + val SyntacticAppliedType: SyntacticTypeAppliedExtractor trait SyntacticTypeAppliedExtractor { def apply(tree: Tree, targs: List[Tree]): Tree - def unapply(tree: Tree): Some[(Tree, List[Tree])] + def unapply(tree: Tree): Option[(Tree, List[Tree])] } val SyntacticApplied: SyntacticAppliedExtractor @@ -784,6 +785,18 @@ trait Internals { self: Universe => def apply(expr: Tree, selectors: List[Tree]): Import def unapply(imp: Import): Some[(Tree, List[Tree])] } + + val SyntacticSelectType: SyntacticSelectTypeExtractor + trait SyntacticSelectTypeExtractor { + def apply(qual: Tree, name: TypeName): Select + def unapply(tree: Tree): Option[(Tree, TypeName)] + } + + val SyntacticSelectTerm: SyntacticSelectTermExtractor + trait SyntacticSelectTermExtractor { + def apply(qual: Tree, name: TermName): Select + def unapply(tree: Tree): Option[(Tree, TermName)] + } } @deprecated("Use `internal.reificationSupport` instead", "2.11.0") diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index a5a50f1088..dddd3c0e61 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -919,6 +919,14 @@ trait Symbols { self: Universe => * For a Scala package class, NoSymbol. * For a Java class, NoSymbol. * + * Known issues: Due to SI-8367, primaryConstructor may return unexpected results + * when called for Java classes (for some vague definition of a "Java class", which apparently + * not only includes javac-produced classfiles, but also consists of classes defined in + * Scala programs under the java.lang package). What's even worse, for some Java classes + * we can't even guarantee stability of the return value - depending on your classloader configuration + * and/or JDK version you might get different primaryConstructor for the same ClassSymbol. + * We have logged these issues at SI-8193. + * * @group Class */ // TODO: SI-8193 I think we should only return a non-empty symbol if called for Scala classes diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index 66ac4bc751..dfe1811ff0 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -101,7 +101,7 @@ trait ReificationSupport { self: SymbolTable => } def mkAnnotation(tree: Tree): Tree = tree match { - case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, noSelfType, Nil) => + case SyntacticNew(Nil, SyntacticApplied(SyntacticAppliedType(_, _), _) :: Nil, noSelfType, Nil) => tree case _ => throw new IllegalArgumentException(s"Tree ${showRaw(tree)} isn't a correct representation of annotation." + @@ -201,17 +201,35 @@ trait ReificationSupport { self: SymbolTable => def unapply(flags: Long): Some[Long] = Some(flags) } + /** Construct/deconstruct type application term trees. + * Treats other term trees as zero-argument type applications. + */ object SyntacticTypeApplied extends SyntacticTypeAppliedExtractor { def apply(tree: Tree, targs: List[Tree]): Tree = if (targs.isEmpty) tree else if (tree.isTerm) TypeApply(tree, targs) - else if (tree.isType) AppliedTypeTree(tree, targs) - else throw new IllegalArgumentException(s"can't apply types to $tree") + else throw new IllegalArgumentException(s"can't apply type arguments to $tree") - def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match { case TypeApply(fun, targs) => Some((fun, targs)) + case _ if tree.isTerm => Some((tree, Nil)) + case _ => None + } + } + + /** Construct/deconstruct applied type trees. + * Treats other types as zero-arity applied types. + */ + object SyntacticAppliedType extends SyntacticTypeAppliedExtractor { + def apply(tree: Tree, targs: List[Tree]): Tree = + if (targs.isEmpty) tree + else if (tree.isType) AppliedTypeTree(tree, targs) + else throw new IllegalArgumentException(s"can't create applied type from non-type $tree") + + def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match { case AppliedTypeTree(tpe, targs) => Some((tpe, targs)) - case _ => Some((tree, Nil)) + case _ if tree.isType => Some((tree, Nil)) + case _ => None } } @@ -223,7 +241,10 @@ trait ReificationSupport { self: SymbolTable => case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) => Some((fun, pats :: Nil)) case treeInfo.Applied(fun, targs, argss) => - Some((SyntacticTypeApplied(fun, targs), argss)) + val callee = + if (fun.isTerm) SyntacticTypeApplied(fun, targs) + else SyntacticAppliedType(fun, targs) + Some((callee, argss)) } } @@ -489,8 +510,8 @@ trait ReificationSupport { self: SymbolTable => gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition) def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match { - case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) => - Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, noSelfType, Nil)) + case SyntacticApplied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), argss) => + Some((Nil, SyntacticApplied(SyntacticAppliedType(ident, targs), argss) :: Nil, noSelfType, Nil)) case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, ListOfNil, earlyDefs, parents, selfType, body) :: Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) => Some((earlyDefs, parents, selfType, body)) @@ -987,6 +1008,22 @@ trait ReificationSupport { self: SymbolTable => Some((imp.expr, selectors)) } } + + object SyntacticSelectType extends SyntacticSelectTypeExtractor { + def apply(qual: Tree, name: TypeName): Select = Select(qual, name) + def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match { + case Select(qual, name: TypeName) => Some((qual, name)) + case _ => None + } + } + + object SyntacticSelectTerm extends SyntacticSelectTermExtractor { + def apply(qual: Tree, name: TermName): Select = Select(qual, name) + def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { + case Select(qual, name: TermName) => Some((qual, name)) + case _ => None + } + } } val build = new ReificationSupportImpl diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 339923a061..640e0606c7 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -613,6 +613,7 @@ trait StdNames { val SingleType: NameType = "SingleType" val SuperType: NameType = "SuperType" val SyntacticApplied: NameType = "SyntacticApplied" + val SyntacticAppliedType: NameType = "SyntacticAppliedType" val SyntacticAssign: NameType = "SyntacticAssign" val SyntacticBlock: NameType = "SyntacticBlock" val SyntacticClassDef: NameType = "SyntacticClassDef" @@ -630,6 +631,8 @@ trait StdNames { val SyntacticObjectDef: NameType = "SyntacticObjectDef" val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef" val SyntacticPatDef: NameType = "SyntacticPatDef" + val SyntacticSelectType: NameType = "SyntacticSelectType" + val SyntacticSelectTerm: NameType = "SyntacticSelectTerm" val SyntacticTraitDef: NameType = "SyntacticTraitDef" val SyntacticTry: NameType = "SyntacticTry" val SyntacticTuple: NameType = "SyntacticTuple" diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 03d8f97831..595d638c28 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -1904,6 +1904,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The next enclosing method. */ def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod + /** The primary constructor of a class. */ def primaryConstructor: Symbol = NoSymbol /** The self symbol (a TermSymbol) of a class with explicit self type, or else the @@ -3188,8 +3189,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def primaryConstructor = { val c = info decl primaryConstructorName - if (isJavaDefined) NoSymbol // need to force info before checking the flag - else if (c.isOverloaded) c.alternatives.head else c + if (c.isOverloaded) c.alternatives.head else c } override def associatedFile = ( diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index 8bb5757bbb..9c853fb514 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -306,7 +306,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set */ override protected def findAbstractFile(name: String): AbstractFile = super.findAbstractFile(name) match { - case null => translatePath(name) map (super.findAbstractFile(_)) orNull + case null if _initializeComplete => translatePath(name) map (super.findAbstractFile(_)) orNull case file => file } } diff --git a/test/files/lib/macro210.jar.desired.sha1 b/test/files/lib/macro210.jar.desired.sha1 new file mode 100644 index 0000000000..ff87a55129 --- /dev/null +++ b/test/files/lib/macro210.jar.desired.sha1 @@ -0,0 +1 @@ +3794ec22d9b27f2b179bd34e9b46db771b934ec3 ?macro210.jar diff --git a/test/files/neg/macro-incompatible-macro-engine-a.check b/test/files/neg/macro-incompatible-macro-engine-a.check new file mode 100644 index 0000000000..8ae08bd164 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-a.check @@ -0,0 +1,7 @@ +Test_3.scala:2: error: macro cannot be expanded, because it was compiled by an incompatible macro engine + Macros.foo + ^ +Test_3.scala:3: error: macro cannot be expanded, because it was compiled by an incompatible macro engine + Macros.foo + ^ +two errors found diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.flags index 966df731d0..966df731d0 100644 --- a/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags +++ b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.flags diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala index 39708eee49..39708eee49 100644 --- a/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala +++ b/test/files/neg/macro-incompatible-macro-engine-a/Macros_2.scala diff --git a/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala b/test/files/neg/macro-incompatible-macro-engine-a/Plugin_1.scala index 44ed91d2fb..44ed91d2fb 100644 --- a/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala +++ b/test/files/neg/macro-incompatible-macro-engine-a/Plugin_1.scala diff --git a/test/files/neg/macro-incompatible-macro-engine/Test_3.scala b/test/files/neg/macro-incompatible-macro-engine-a/Test_3.scala index 7e4fae5236..7e4fae5236 100644 --- a/test/files/neg/macro-incompatible-macro-engine/Test_3.scala +++ b/test/files/neg/macro-incompatible-macro-engine-a/Test_3.scala diff --git a/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml b/test/files/neg/macro-incompatible-macro-engine-a/scalac-plugin.xml index 42b9cdd75d..42b9cdd75d 100644 --- a/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml +++ b/test/files/neg/macro-incompatible-macro-engine-a/scalac-plugin.xml diff --git a/test/files/neg/macro-incompatible-macro-engine-b.check b/test/files/neg/macro-incompatible-macro-engine-b.check new file mode 100644 index 0000000000..2a7510cf86 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b.check @@ -0,0 +1,7 @@ +Test_3.scala:2: error: macro cannot be expanded, because it was compiled by an incompatible macro engine (internal diagnostic: expected = v7.0 (implemented in Scala 2.11.0-M8), actual = vxxx (implemented in the incompatibleMacroEngine plugin)) + Macros.foo + ^ +Test_3.scala:3: error: macro cannot be expanded, because it was compiled by an incompatible macro engine (internal diagnostic: expected = v7.0 (implemented in Scala 2.11.0-M8), actual = vxxx (implemented in the incompatibleMacroEngine plugin)) + Macros.foo + ^ +two errors found diff --git a/test/files/neg/macro-incompatible-macro-engine-b.flags b/test/files/neg/macro-incompatible-macro-engine-b.flags new file mode 100644 index 0000000000..037a693bbd --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b.flags @@ -0,0 +1 @@ +-Ymacro-debug-lite
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.flags b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala new file mode 100644 index 0000000000..39708eee49 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b/Macros_2.scala @@ -0,0 +1,7 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macros { + def impl(c: Context) = c.universe.Literal(c.universe.Constant(())) + def foo: Unit = macro impl +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Plugin_1.scala b/test/files/neg/macro-incompatible-macro-engine-b/Plugin_1.scala new file mode 100644 index 0000000000..44ed91d2fb --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b/Plugin_1.scala @@ -0,0 +1,35 @@ +package incompatibleMacroEngine + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "incompatibleMacroEngine" + val description = "A sample analyzer plugin that crafts a macro impl binding with a non-standard macro engine." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + def fixupBinding(tree: Tree) = new Transformer { + override def transform(tree: Tree) = { + tree match { + case Literal(const @ Constant(x)) if tree.tpe == null => tree setType ConstantType(const) + case _ if tree.tpe == null => tree setType NoType + case _ => ; + } + super.transform(tree) + } + }.transform(tree) + + override def pluginsTypedMacroBody(typer: Typer, ddef: DefDef): Option[Tree] = { + val result = standardTypedMacroBody(typer, ddef) + val List(AnnotationInfo(atp, List(Apply(nucleus, _ :: others)), Nil)) = ddef.symbol.annotations + val updatedBinding = Apply(nucleus, Assign(Literal(Constant("macroEngine")), Literal(Constant("vxxx (implemented in the incompatibleMacroEngine plugin)"))) :: others) + ddef.symbol.setAnnotations(List(AnnotationInfo(atp, List(fixupBinding(updatedBinding)), Nil))) + Some(result) + } + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala b/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala new file mode 100644 index 0000000000..7e4fae5236 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo + Macros.foo +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-b/scalac-plugin.xml b/test/files/neg/macro-incompatible-macro-engine-b/scalac-plugin.xml new file mode 100644 index 0000000000..42b9cdd75d --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-b/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>incompatible-macro-engine</name> + <classname>incompatibleMacroEngine.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine-c.check b/test/files/neg/macro-incompatible-macro-engine-c.check new file mode 100644 index 0000000000..fb6c59ab7c --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-c.check @@ -0,0 +1,4 @@ +macro-incompatible-macro-engine-c.scala:2: error: can't expand macros compiled by previous versions of Scala + MacroLibCompiledByScala210x.foo + ^ +one error found diff --git a/test/files/neg/macro-incompatible-macro-engine-c.scala b/test/files/neg/macro-incompatible-macro-engine-c.scala new file mode 100644 index 0000000000..037ac5f456 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine-c.scala @@ -0,0 +1,3 @@ +object Test extends App { + MacroLibCompiledByScala210x.foo +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine.check b/test/files/neg/macro-incompatible-macro-engine.check deleted file mode 100644 index 1d582e5ed6..0000000000 --- a/test/files/neg/macro-incompatible-macro-engine.check +++ /dev/null @@ -1,7 +0,0 @@ -Test_3.scala:2: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) - Macros.foo - ^ -Test_3.scala:3: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) - Macros.foo - ^ -two errors found diff --git a/test/files/pos/t8364.check b/test/files/pos/t8364.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/pos/t8364.check diff --git a/test/files/pos/t8364.scala b/test/files/pos/t8364.scala new file mode 100644 index 0000000000..7a7ea1ff12 --- /dev/null +++ b/test/files/pos/t8364.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics + +object MyDynamic extends Dynamic { + def selectDynamic(name: String): Any = ??? +} + +object Test extends App { + locally { + import java.lang.String + MyDynamic.id + } +} diff --git a/test/files/pos/t8367.scala b/test/files/pos/t8367.scala new file mode 100644 index 0000000000..cae2415405 --- /dev/null +++ b/test/files/pos/t8367.scala @@ -0,0 +1,11 @@ +package java.lang + +// SI-8367 shows something is wrong with primaryConstructor and it was made worse with the fix for SI-8192 +// perhaps primaryConstructor should not return NoSymbol when isJavaDefined +// or, perhaps isJavaDefined should be refined (the package definition above is pretty sneaky) +// also, why does this only happen for a (scala-defined!) class with this special name? +// (there are a couple of others: CloneNotSupportedException,InterruptedException) +class Throwable + +// class CloneNotSupportedException +// class InterruptedException
\ No newline at end of file diff --git a/test/files/run/t6392b.check b/test/files/run/t6392b.check index 83d8fe20c1..9bb9b5694f 100644 --- a/test/files/run/t6392b.check +++ b/test/files/run/t6392b.check @@ -1 +1 @@ -ModuleDef(Modifiers(), TermName("C")#MOD, Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), noSelfType, List(DefDef(Modifiers(), termNames.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), typeNames.EMPTY), termNames.CONSTRUCTOR#CTOR), List())), Literal(Constant(()))))))) +ModuleDef(Modifiers(), TermName("C")#MOD, Template(List(Select(Ident(scala#PK), TypeName("AnyRef")#TPE)), noSelfType, List(DefDef(Modifiers(), termNames.CONSTRUCTOR#PCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("C")), typeNames.EMPTY), termNames.CONSTRUCTOR#PCTOR), List())), Literal(Constant(()))))))) diff --git a/test/files/run/t7582-private-within.check b/test/files/run/t7582-private-within.check index 1b9a0910af..b2743ffa06 100644 --- a/test/files/run/t7582-private-within.check +++ b/test/files/run/t7582-private-within.check @@ -2,7 +2,7 @@ private[package pack] class JavaPackagePrivate private[package pack] module JavaPackagePrivate private[package pack] module class JavaPackagePrivate private[package pack] field field -private[package pack] constructor <init> +private[package pack] primary constructor <init> private[package pack] method meth private[package pack] field staticField private[package pack] method staticMeth diff --git a/test/files/run/t8192.check b/test/files/run/t8192.check index 7195703e19..2423a7acbf 100644 --- a/test/files/run/t8192.check +++ b/test/files/run/t8192.check @@ -1,10 +1,4 @@ compile-time -class File -primary constructor: NoSymbol -def <init>(x$1: String): java.io.File => false -def <init>(x$1: String,x$2: String): java.io.File => false -def <init>(x$1: java.io.File,x$2: String): java.io.File => false -def <init>(x$1: java.net.URI): java.io.File => false package scala primary constructor: NoSymbol object List @@ -21,12 +15,6 @@ primary constructor: def <init>(x: Int): C => true def <init>(x: Int): C => true def <init>(x: String): C => false runtime -class File -primary constructor: NoSymbol -def <init>(x$1: java.io.File,x$2: java.lang.String): java.io.File => false -def <init>(x$1: java.lang.String): java.io.File => false -def <init>(x$1: java.lang.String,x$2: java.lang.String): java.io.File => false -def <init>(x$1: java.net.URI): java.io.File => false package scala primary constructor: NoSymbol object List diff --git a/test/files/run/t8192/Macros_1.scala b/test/files/run/t8192/Macros_1.scala index ddad9fb872..72fb2cf313 100644 --- a/test/files/run/t8192/Macros_1.scala +++ b/test/files/run/t8192/Macros_1.scala @@ -30,7 +30,8 @@ object Macros { } println("compile-time") - test(typeOf[File].typeSymbol.asClass) + // SI-8367 primaryConstructor for Java-defined classes is unstable, so I'm commenting this out + // test(typeOf[File].typeSymbol.asClass) test(definitions.ScalaPackageClass) test(definitions.ListModule.moduleClass.asClass) test(typeOf[Product1[_]].typeSymbol.asClass) diff --git a/test/files/run/t8192/Test_2.scala b/test/files/run/t8192/Test_2.scala index 29f187c171..89302083ad 100644 --- a/test/files/run/t8192/Test_2.scala +++ b/test/files/run/t8192/Test_2.scala @@ -30,7 +30,8 @@ object Test extends App { Macros.foo println("runtime") - test(typeOf[File].typeSymbol.asClass) + // SI-8367 primaryConstructor for Java-defined classes is unstable, so I'm commenting this out + // test(typeOf[File].typeSymbol.asClass) test(definitions.ScalaPackageClass) test(definitions.ListModule.moduleClass.asClass) test(typeOf[Product1[_]].typeSymbol.asClass) diff --git a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala index e96d1186f7..f558a2f078 100644 --- a/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/TermDeconstructionProps.scala @@ -199,4 +199,16 @@ object TermDeconstructionProps extends QuasiquoteProperties("term deconstruction q"..$tpt; ()" } } + + property("term select doesn't match type select") = test { + assertThrows[MatchError] { + val q"$qual.$name" = tq"foo.bar" + } + } + + property("type application doesn't match applied type") = test { + assertThrows[MatchError] { + val q"$f[..$targs]" = tq"foo[bar]" + } + } } diff --git a/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala index 8ec1779353..7572b27b52 100644 --- a/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala +++ b/test/files/scalacheck/quasiquotes/TypeDeconstructionProps.scala @@ -63,4 +63,16 @@ object TypeDeconstructionProps extends QuasiquoteProperties("type deconstruction // matches because type tree isn't syntactic without original val tq"" = tq"${typeOf[Int]}" } + + property("type select doesn't match term select") = test { + assertThrows[MatchError] { + val tq"$qual.$name" = q"foo.bar" + } + } + + property("applied type doesn't match type appliction") = test { + assertThrows[MatchError] { + val tq"$tpt[..$tpts]" = q"foo[bar]" + } + } } |