diff options
382 files changed, 3064 insertions, 1964 deletions
diff --git a/lib/scala-compiler-src.jar.desired.sha1 b/lib/scala-compiler-src.jar.desired.sha1 index 7dae1a905e..debbce2d7e 100644 --- a/lib/scala-compiler-src.jar.desired.sha1 +++ b/lib/scala-compiler-src.jar.desired.sha1 @@ -1 +1 @@ -f9f41fb909df6a0178906c9fd02e5d0efa15c9ed ?scala-compiler-src.jar +19d04510ac6f25d088da82527d8435b68c00153d ?scala-compiler-src.jar diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1 index bb22879679..4ec9610bae 100644 --- a/lib/scala-compiler.jar.desired.sha1 +++ b/lib/scala-compiler.jar.desired.sha1 @@ -1 +1 @@ -c4cd524dc29d298a5034637f6b31122dccb300d6 ?scala-compiler.jar +3585351c6a62186097be55fff88bee88a985f5c0 ?scala-compiler.jar diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1 index 641324256e..6e97551fc7 100644 --- a/lib/scala-library-src.jar.desired.sha1 +++ b/lib/scala-library-src.jar.desired.sha1 @@ -1 +1 @@ -2cba5a13ef44bf93133be26cc89ba3a640a5c28f ?scala-library-src.jar +e606934dc00ced6bfac715bbdba427f9c2c18bc7 ?scala-library-src.jar diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1 index 1b4eeac625..36aedb2ad7 100644 --- a/lib/scala-library.jar.desired.sha1 +++ b/lib/scala-library.jar.desired.sha1 @@ -1 +1 @@ -d7c6e69eba3dba2f75a0f44e56480cd3dbab8931 ?scala-library.jar +36456c52b0395fc1e6e367291e45bd503fa019c5 ?scala-library.jar diff --git a/lib/scala-reflect-src.jar.desired.sha1 b/lib/scala-reflect-src.jar.desired.sha1 index f9d9618380..ebd6dcbf5a 100644 --- a/lib/scala-reflect-src.jar.desired.sha1 +++ b/lib/scala-reflect-src.jar.desired.sha1 @@ -1 +1 @@ -dbc00bd4b09012aa52e802926dee3f8a02a767ff ?scala-reflect-src.jar +51787a41cae5b0ec6910c5a1a6af392e17550856 ?scala-reflect-src.jar diff --git a/lib/scala-reflect.jar.desired.sha1 b/lib/scala-reflect.jar.desired.sha1 index 8663ef7c85..4378fec9d6 100644 --- a/lib/scala-reflect.jar.desired.sha1 +++ b/lib/scala-reflect.jar.desired.sha1 @@ -1 +1 @@ -c0eed5dee0a3204239c9b35134cad8b3ad140121 ?scala-reflect.jar +d4a4c0aab882412461fbd9d39cf47da5a619855e ?scala-reflect.jar diff --git a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala b/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala index ee8776f397..bfd4e7ac40 100644 --- a/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala +++ b/src/actors/scala/actors/scheduler/ThreadPoolConfig.scala @@ -42,10 +42,7 @@ private[actors] object ThreadPoolConfig { (propIsSetTo("actors.enableForkJoin", "true") || { Debug.info(this+": java.version = "+javaVersion) Debug.info(this+": java.vm.vendor = "+javaVmVendor) - - // on IBM J9 1.6 do not use ForkJoinPool - // XXX this all needs to go into Properties. - isJavaAtLeast("1.6") && ((javaVmVendor contains "Oracle") || (javaVmVendor contains "Sun") || (javaVmVendor contains "Apple")) + isJavaAtLeast("1.6") }) catch { case _: SecurityException => false diff --git a/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala new file mode 100644 index 0000000000..32c6da8007 --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/DefaultMacroCompiler.scala @@ -0,0 +1,33 @@ +package scala.reflect.macros +package compiler + +import scala.tools.nsc.Global +import scala.reflect.macros.contexts.Context + +abstract class DefaultMacroCompiler extends Resolvers + with Validators + with Errors { + val global: Global + import global._ + + val typer: global.analyzer.Typer + private implicit val context0 = typer.context + val context = typer.context + + val macroDdef: DefDef + lazy val macroDef = macroDdef.symbol + + private case class MacroImplResolutionException(pos: Position, msg: String) extends Exception + def abort(pos: Position, msg: String) = throw MacroImplResolutionException(pos, msg) + + def resolveMacroImpl: Tree = { + try { + validateMacroImplRef() + macroImplRef + } catch { + case MacroImplResolutionException(pos, msg) => + context.error(pos, msg) + EmptyTree + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala new file mode 100644 index 0000000000..dd3142127e --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -0,0 +1,113 @@ +package scala.reflect.macros +package compiler + +import scala.compat.Platform.EOL +import scala.reflect.macros.util.Traces + +trait Errors extends Traces { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import typer.TyperErrorGen._ + import typer.infer.InferErrorGen._ + def globalSettings = global.settings + + // sanity check errors + + private def implRefError(message: String) = abort(macroDdef.pos, message) + + def MacroImplReferenceWrongShapeError() = implRefError( + "macro implementation reference has wrong shape. required:\n"+ + "macro [<static object>].<method name>[[<type args>]] or\n" + + "macro [<macro bundle>].<method name>[[<type args>]]") + + def MacroImplNotPublicError() = implRefError("macro implementation must be public") + + def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded") + + def MacroImplWrongNumberOfTypeArgumentsError() = implRefError(TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef)) + + // compatibility errors + + // helpers + + private def lengthMsg(flavor: String, violation: String, extra: Symbol) = { + val noun = if (flavor == "value") "parameter" else "type parameter" + val message = noun + " lists have different length, " + violation + " extra " + noun + val suffix = if (extra ne NoSymbol) " " + extra.defString else "" + message + suffix + } + + private def abbreviateCoreAliases(s: String): String = List("WeakTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x)) + + private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { + var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString + if (abbreviate) argsPart = abbreviateCoreAliases(argsPart) + var retPart = restpe.toString + if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) + argsPart + ": " + retPart + } + + // not exactly an error generator, but very related + // and I dearly wanted to push it away from Macros.scala + private def checkConforms(slot: String, rtpe: Type, atpe: Type) = { + val verbose = macroDebugVerbose || settings.explaintypes.value + + def check(rtpe: Type, atpe: Type): Boolean = { + def success() = { if (verbose) println(rtpe + " <: " + atpe + "?" + EOL + "true"); true } + (rtpe, atpe) match { + case _ if rtpe eq atpe => success() + case (TypeRef(_, RepeatedParamClass, rtpe :: Nil), TypeRef(_, RepeatedParamClass, atpe :: Nil)) => check(rtpe, atpe) + case (ExprClassOf(_), TreeType()) => success() + case (TreeType(), ExprClassOf(_)) => success() + case _ => rtpe <:< atpe + } + } + + val ok = + if (verbose) withTypesExplained(check(rtpe, atpe)) + else check(rtpe, atpe) + if (!ok) { + if (!macroDebugVerbose) + explainTypes(rtpe, atpe) + compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString))) + } + } + + private def compatibilityError(message: String) = + implRefError( + "macro implementation has wrong shape:"+ + "\n required: " + showMeth(rparamss, rret, abbreviate = true) + + "\n found : " + showMeth(aparamss, aret, abbreviate = false) + + "\n" + message) + + def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences") + + def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ") + + def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length))) + + def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length)))) + + def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkConforms("parameter " + rparam.name, rparam.tpe, atpe) + + def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkConforms("return type", atpe, rret) + + def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name) + + def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = { + def fail(paramName: Name) = compatibilityError("types incompatible for parameter " + paramName + ": corresponding is not a vararg parameter") + if (isRepeated(rparam) && !isRepeated(aparam)) fail(rparam.name) + if (!isRepeated(rparam) && isRepeated(aparam)) fail(aparam.name) + } + + def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) = + compatibilityError(NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes.value)) + + def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) = + compatibilityError( + "type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ + ex.getMessage) +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala new file mode 100644 index 0000000000..3025eb52a1 --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala @@ -0,0 +1,91 @@ +package scala.reflect.macros +package compiler + +import scala.reflect.internal.Flags._ +import scala.reflect.macros.TypecheckException + +trait Resolvers { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import treeInfo._ + import gen._ + + /** Determines the type of context implied by the macro def. + */ + val ctxTpe = MacroContextClass.tpe + + /** Resolves a macro impl reference provided in the right-hand side of the given macro definition. + * + * Acceptable shapes of the right-hand side: + * 1) [<static object>].<method name>[[<type args>]] // vanilla macro def + * 2) [<macro bundle>].<method name>[[<type args>]] // shiny new macro bundle + * + * Produces a tree, which represents a reference to a macro implementation if everything goes well, + * otherwise reports found errors and returns EmptyTree. The resulting tree should have the following format: + * + * qualifier.method[targs] + * + * Qualifier here might be omitted (local macro defs), be a static object (vanilla macro defs) + * or be a dummy instance of a macro bundle (e.g. new MyMacro(???).expand). + */ + lazy val macroImplRef: Tree = { + val (maybeBundleRef, methName, targs) = macroDdef.rhs match { + case Applied(methRef @ Select(bundleRef @ RefTree(qual, bundleName), methName), targs, Nil) => + (RefTree(qual, bundleName.toTypeName), methName, targs) + case Applied(Ident(methName), targs, Nil) => + (Ident(context.owner.enclClass), methName, targs) + case _ => + (EmptyTree, TermName(""), Nil) + } + + val untypedImplRef = typer.silent(_.typedType(maybeBundleRef)) match { + case SilentResultValue(result) if isMacroBundleType(result.tpe) => + val bundleClass = result.tpe.typeSymbol + if (!bundleClass.owner.isPackageClass) abort(macroDef.pos, "macro bundles can only be defined as top-level classes or traits") + + // synthesize the invoker, i.e. given a top-level `trait Foo extends Macro { def expand = ... } ` + // create a top-level definition `class FooInvoker(val c: Context) extends Foo` in MACRO_INVOKER_PACKAGE + val invokerPid = gen.mkUnattributedRef(nme.MACRO_INVOKER_PACKAGE) + val invokerName = TypeName(bundleClass.fullName.split('.').map(_.capitalize).mkString("") + nme.MACRO_INVOKER_SUFFIX) + val invokerFullName = TypeName(s"$invokerPid.$invokerName") + val existingInvoker = rootMirror.getClassIfDefined(invokerFullName) + if (!currentRun.compiles(existingInvoker)) { + def mkContextValDef(flags: Long) = ValDef(Modifiers(flags), nme.c, TypeTree(ctxTpe), EmptyTree) + val contextField = mkContextValDef(PARAMACCESSOR) + val contextParam = mkContextValDef(PARAM | PARAMACCESSOR) + val invokerCtor = DefDef(Modifiers(), nme.CONSTRUCTOR, Nil, List(List(contextParam)), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))) + val invoker = atPos(bundleClass.pos)(ClassDef(NoMods, invokerName, Nil, Template(List(Ident(bundleClass)), emptyValDef, List(contextField, invokerCtor)))) + currentRun.compileLate(PackageDef(invokerPid, List(invoker))) + } + + // synthesize the macro impl reference, which is going to look like: + // `new Foo$invoker(???).expand` plus the optional type arguments + val instanceOfInvoker = New(Select(invokerPid, invokerName), List(List(Select(scalaDot(nme.Predef), nme.???)))) + gen.mkTypeApply(Select(instanceOfInvoker, methName), targs) + case _ => + macroDdef.rhs + } + + val typedImplRef = typer.silent(_.typed(markMacroImplRef(untypedImplRef)), reportAmbiguousErrors = false) + typedImplRef match { + case SilentResultValue(success) => success + case SilentTypeError(err) => abort(err.errPos, err.errMsg) + } + } + + // FIXME: cannot write this concisely because of SI-7507 + // lazy val (isImplBundle, macroImplOwner, macroImpl, macroImplTargs) = + private lazy val dissectedMacroImplRef = + macroImplRef match { + case MacroImplReference(isBundle, owner, meth, targs) => (isBundle, owner, meth, targs) + case _ => MacroImplReferenceWrongShapeError() + } + lazy val isImplBundle = dissectedMacroImplRef._1 + lazy val isImplMethod = !isImplBundle + lazy val macroImplOwner = dissectedMacroImplRef._2 + lazy val macroImpl = dissectedMacroImplRef._3 + lazy val targs = dissectedMacroImplRef._4 +} diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala new file mode 100644 index 0000000000..60cfc94a23 --- /dev/null +++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala @@ -0,0 +1,193 @@ +package scala.reflect.macros +package compiler + +import java.util.UUID.randomUUID +import scala.reflect.internal.Flags._ +import scala.reflect.macros.TypecheckException + +trait Validators { + self: DefaultMacroCompiler => + + import global._ + import analyzer._ + import definitions._ + import treeInfo._ + import typer.infer._ + + def validateMacroImplRef() = { + sanityCheck() + if (macroImpl != Predef_???) checkMacroDefMacroImplCorrespondence() + } + + private def sanityCheck() = { + if (!macroImpl.isMethod) MacroImplReferenceWrongShapeError() + if (!macroImpl.isPublic) MacroImplNotPublicError() + if (macroImpl.isOverloaded) MacroImplOverloadedError() + if (macroImpl.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError() + val declaredInStaticObject = isImplMethod && (macroImplOwner.isStaticOwner || macroImplOwner.moduleClass.isStaticOwner) + val declaredInTopLevelClass = isImplBundle && macroImplOwner.owner.isPackageClass + if (!declaredInStaticObject && !declaredInTopLevelClass) MacroImplReferenceWrongShapeError() + } + + private def checkMacroDefMacroImplCorrespondence() = { + val atvars = atparams map freshVar + def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) + + // we only check strict correspondence between value parameterss + // type parameters of macro defs and macro impls don't have to coincide with each other + val implicitParams = aparamss.flatten filter (_.isImplicit) + if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams) + if (aparamss.length != rparamss.length) MacroImplParamssMismatchError() + map2(aparamss, rparamss)((aparams, rparams) => { + if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) + if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) + }) + + try { + // cannot fuse this map2 and the map2 above because if aparamss.flatten != rparamss.flatten + // then `atpeToRtpe` is going to fail with an unsound substitution + map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => { + if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) + if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam) + val aparamtpe = aparam.tpe.dealias match { + case RefinedType(List(tpe), Scope(sym)) if tpe =:= ctxTpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe + case tpe => tpe + } + checkMacroImplParamTypeMismatch(atpeToRtpe(aparamtpe), rparam) + }) + + checkMacroImplResultTypeMismatch(atpeToRtpe(aret), rret) + + val maxLubDepth = lubDepth(aparamss.flatten map (_.tpe)) max lubDepth(rparamss.flatten map (_.tpe)) + val atargs = solvedTypes(atvars, atparams, atparams map varianceInType(aret), upper = false, depth = maxLubDepth) + val boundsOk = typer.silent(_.infer.checkBounds(macroDdef, NoPrefix, NoSymbol, atparams, atargs, "")) + boundsOk match { + case SilentResultValue(true) => // do nothing, success + case SilentResultValue(false) | SilentTypeError(_) => MacroImplTargMismatchError(atargs, atparams) + } + } catch { + case ex: NoInstance => MacroImplTparamInstantiationError(atparams, ex) + } + } + + // aXXX (e.g. aparamss) => characteristics of the actual macro impl signature extracted from the macro impl ("a" stands for "actual") + // rXXX (e.g. rparamss) => characteristics of the reference macro impl signature synthesized from the macro def ("r" stands for "reference") + // FIXME: cannot write this concisely because of SI-7507 + //lazy val MacroImplSig(atparams, aparamss, aret) = macroImplSig + //lazy val MacroImplSig(_, rparamss, rret) = referenceMacroImplSig + lazy val atparams = macroImplSig.tparams + lazy val aparamss = macroImplSig.paramss + lazy val aret = macroImplSig.ret + lazy val rparamss = referenceMacroImplSig.paramss + lazy val rret = referenceMacroImplSig.ret + + // Technically this can be just an alias to MethodType, but promoting it to a first-class entity + // provides better encapsulation and convenient syntax for pattern matching. + private case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type) + + /** An actual macro implementation signature extracted from a macro implementation method. + * + * For the following macro impl: + * def fooBar[T: c.WeakTypeTag] + * (c: scala.reflect.macros.Context) + * (xs: c.Expr[List[T]]) + * : c.Expr[T] = ... + * + * This function will return: + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] + * + * Note that type tag evidence parameters are not included into the result. + * Type tag context bounds for macro impl tparams are optional. + * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. + * + * This method cannot be reduced to just macroImpl.info, because macro implementations might + * come in different shapes. If the implementation is an apply method of a Macro-compatible object, + * then it won't have (c: Context) in its parameters, but will rather refer to Macro.c. + * + * @param macroImpl The macro implementation symbol + */ + private lazy val macroImplSig: MacroImplSig = { + val tparams = macroImpl.typeParams + val paramss = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => NoSymbol) + val ret = macroImpl.info.finalResultType + MacroImplSig(tparams, paramss, ret) + } + + /** A reference macro implementation signature extracted from a given macro definition. + * + * For the following macro def: + * def foo[T](xs: List[T]): T = macro fooBar + * + * This function will return: + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]])c.Expr[T] + * + * Note that type tag evidence parameters are not included into the result. + * Type tag context bounds for macro impl tparams are optional. + * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. + * + * Also note that we need a DefDef, not the corresponding MethodSymbol, because that symbol would be of no use for us. + * Macro signatures are verified when typechecking macro defs, which means that at that moment inspecting macroDef.info + * means asking for cyclic reference errors. + * + * We need macro implementation symbol as well, because the return type of the macro definition might be omitted, + * and in that case we'd need to infer it from the return type of the macro implementation. Luckily for us, we can + * use that symbol without a risk of running into cycles. + * + * @param typer Typechecker of `macroDdef` + * @param macroDdef The macro definition tree + * @param macroImpl The macro implementation symbol + */ + private lazy val referenceMacroImplSig: MacroImplSig = { + // had to move method's body to an object because of the recursive dependencies between sigma and param + object SigGenerator { + val cache = scala.collection.mutable.Map[Symbol, Symbol]() + val ctxPrefix = + if (isImplMethod) singleType(NoPrefix, makeParam(nme.macroContext, macroDdef.pos, ctxTpe, SYNTHETIC)) + else singleType(ThisType(macroImpl.owner), macroImpl.owner.tpe.member(nme.c)) + var paramss = + if (isImplMethod) List(ctxPrefix.termSymbol) :: mmap(macroDdef.vparamss)(param) + else mmap(macroDdef.vparamss)(param) + val macroDefRet = + if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe + else computeMacroDefTypeFromMacroImplRef(macroDdef, macroImplRef) + val implReturnType = sigma(increaseMetalevel(ctxPrefix, macroDefRet)) + + object SigmaTypeMap extends TypeMap { + def mapPrefix(pre: Type) = pre match { + case ThisType(sym) if sym == macroDef.owner => + singleType(singleType(ctxPrefix, MacroContextPrefix), ExprValue) + case SingleType(NoPrefix, sym) => + mfind(macroDdef.vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) + case _ => + mapOver(pre) + } + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = mapPrefix(pre) + val args1 = mapOverArgs(args, sym.typeParams) + if ((pre eq pre1) && (args eq args1)) tp + else typeRef(pre1, sym, args1) + case _ => + mapOver(tp) + } + } + def sigma(tpe: Type): Type = SigmaTypeMap(tpe) + + def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) = + macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe + def param(tree: Tree): Symbol = ( + cache.getOrElseUpdate(tree.symbol, { + val sym = tree.symbol + assert(sym.isTerm, s"sym = $sym, tree = $tree") + makeParam(sym.name, sym.pos, sigma(increaseMetalevel(ctxPrefix, sym.tpe)), sym.flags) + }) + ) + } + + import SigGenerator._ + macroLogVerbose(s"generating macroImplSigs for: $macroDdef") + val result = MacroImplSig(macroDdef.tparams map (_.symbol), paramss, implReturnType) + macroLogVerbose(s"result is: $result") + result + } +} diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/contexts/Aliases.scala index 1c6703aeee..cc64d97d85 100644 --- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala +++ b/src/compiler/scala/reflect/macros/contexts/Aliases.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts trait Aliases { self: Context => diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala new file mode 100644 index 0000000000..bd1d7d5248 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Context.scala @@ -0,0 +1,29 @@ +package scala.reflect.macros +package contexts + +import scala.tools.nsc.Global + +abstract class Context extends scala.reflect.macros.Context + with Aliases + with Enclosures + with Names + with Reifiers + with FrontEnds + with Infrastructure + with Typers + with Parsers + with Evals + with ExprUtils + with Synthetics + with Traces { + + val universe: Global + + val mirror: universe.Mirror = universe.rootMirror + + val callsiteTyper: universe.analyzer.Typer + + val prefix: Expr[PrefixType] + + val expandee: Tree +} diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala index f3f92550de..bb88c8d5e1 100644 --- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts import scala.reflect.{ClassTag, classTag} diff --git a/src/compiler/scala/reflect/macros/runtime/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala index 1f7b5f2ff1..84928ddf86 100644 --- a/src/compiler/scala/reflect/macros/runtime/Evals.scala +++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts import scala.reflect.runtime.{universe => ru} import scala.tools.reflect.ToolBox @@ -7,7 +7,7 @@ import scala.tools.reflect.ToolBox trait Evals { self: Context => - private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.macroClassloader) + private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.defaultMacroClassloader) private lazy val evalToolBox = evalMirror.mkToolBox() private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }] diff --git a/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala index a719beed97..4846325d1e 100644 --- a/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala +++ b/src/compiler/scala/reflect/macros/contexts/ExprUtils.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts trait ExprUtils { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala index a6a198e1b4..fda05de09c 100644 --- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala +++ b/src/compiler/scala/reflect/macros/contexts/FrontEnds.scala @@ -1,5 +1,7 @@ package scala.reflect.macros -package runtime +package contexts + +import scala.reflect.macros.runtime.AbortMacroException trait FrontEnds { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala index 7781693822..df7aa4d2be 100644 --- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala +++ b/src/compiler/scala/reflect/macros/contexts/Infrastructure.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts trait Infrastructure { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala index 635e8bcd45..e535754a98 100644 --- a/src/compiler/scala/reflect/macros/runtime/Names.scala +++ b/src/compiler/scala/reflect/macros/contexts/Names.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts trait Names { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala index 566bcde73d..3dab02beba 100644 --- a/src/compiler/scala/reflect/macros/runtime/Parsers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts import scala.language.existentials import scala.tools.reflect.ToolBox diff --git a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala index 7ec3457c6a..ecef1c7289 100644 --- a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Reifiers.scala @@ -4,7 +4,7 @@ */ package scala.reflect.macros -package runtime +package contexts trait Reifiers { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala b/src/compiler/scala/reflect/macros/contexts/Synthetics.scala index 73f3ab8d20..ada16a8113 100644 --- a/src/compiler/scala/reflect/macros/runtime/Synthetics.scala +++ b/src/compiler/scala/reflect/macros/contexts/Synthetics.scala @@ -3,9 +3,8 @@ */ package scala.reflect.macros -package runtime +package contexts -import java.util.UUID._ import scala.reflect.internal.Flags._ import scala.reflect.internal.util.BatchSourceFile import scala.reflect.io.VirtualFile @@ -42,11 +41,6 @@ trait Synthetics { else EmptyTree } - // TODO: provide a way to specify a pretty name for debugging purposes - private def randomFileName() = ( - "macroSynthetic-" + randomUUID().toString.replace("-", "") + ".scala" - ) - def introduceTopLevel[T: PackageSpec](packagePrototype: T, definition: universe.ImplDef): RefTree = introduceTopLevel(packagePrototype, List(definition)).head @@ -55,18 +49,7 @@ trait Synthetics { private def introduceTopLevel[T: PackageSpec](packagePrototype: T, definitions: List[universe.ImplDef]): List[RefTree] = { val code @ PackageDef(pid, _) = implicitly[PackageSpec[T]].mkPackageDef(packagePrototype, definitions) - val syntheticFileName = randomFileName() - // compatibility with SBT - // on the one hand, we need to specify some jfile here, otherwise sbt crashes with an NPE (SI-6870) - // on the other hand, we can't specify the obvious enclosingUnit, because then sbt somehow fails to run tests using type macros - // okay, now let's specify a guaranteedly non-existent file in an existing directory (so that we don't run into permission problems) - val relatedJfile = enclosingUnit.source.file.file - val fakeJfile = if (relatedJfile != null) new java.io.File(relatedJfile.getParent, syntheticFileName) else null - val virtualFile = new VirtualFile(syntheticFileName) { override def file = fakeJfile } - val sourceFile = new BatchSourceFile(virtualFile, code.toString) - val unit = new CompilationUnit(sourceFile) - unit.body = code - universe.currentRun.compileLate(unit) + universe.currentRun.compileLate(code) definitions map (definition => Select(pid, definition.name)) } diff --git a/src/compiler/scala/reflect/macros/runtime/Traces.scala b/src/compiler/scala/reflect/macros/contexts/Traces.scala index 0238e9f84e..df47f6ba81 100644 --- a/src/compiler/scala/reflect/macros/runtime/Traces.scala +++ b/src/compiler/scala/reflect/macros/contexts/Traces.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts trait Traces extends util.Traces { self: Context => diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala index f60b8dfeb4..4a1122b913 100644 --- a/src/compiler/scala/reflect/macros/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala @@ -1,5 +1,5 @@ package scala.reflect.macros -package runtime +package contexts import scala.reflect.internal.Mode @@ -24,7 +24,7 @@ trait Typers { // typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time // I'd advise fixing the root cause: finding why the context is not set to report errors // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) - wrapper(callsiteTyper.silent(_.typed(tree, pt)) match { + wrapper(callsiteTyper.silent(_.typed(tree, pt), reportAmbiguousErrors = false) match { case universe.analyzer.SilentResultValue(result) => macroLogVerbose(result) result diff --git a/src/compiler/scala/reflect/macros/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala deleted file mode 100644 index 76c684f6d7..0000000000 --- a/src/compiler/scala/reflect/macros/runtime/Context.scala +++ /dev/null @@ -1,29 +0,0 @@ -package scala.reflect.macros -package runtime - -import scala.tools.nsc.Global - -abstract class Context extends scala.reflect.macros.Context - with Aliases - with Enclosures - with Names - with Reifiers - with FrontEnds - with Infrastructure - with Typers - with Parsers - with Evals - with ExprUtils - with Synthetics - with Traces { - - val universe: Global - - val mirror: universe.Mirror = universe.rootMirror - - val callsiteTyper: universe.analyzer.Typer - - val prefix: Expr[PrefixType] - - val expandee: Tree -} diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala new file mode 100644 index 0000000000..3ef11fad9d --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala @@ -0,0 +1,31 @@ +package scala.reflect.macros +package runtime + +import scala.reflect.runtime.ReflectionUtils +import scala.reflect.macros.{Context => ApiContext} + +trait JavaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + trait JavaReflectionResolvers { + self: MacroRuntimeResolver => + + import global._ + + def resolveJavaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = { + val implClass = Class.forName(className, true, classLoader) + val implMeths = implClass.getDeclaredMethods.find(_.getName == methName) + // relies on the fact that macro impls cannot be overloaded + // so every methName can resolve to at maximum one method + val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") } + macroLogVerbose(s"successfully loaded macro impl as ($implClass, $implMeth)") + args => { + val implObj = + if (isBundle) implClass.getConstructor(classOf[ApiContext]).newInstance(args.c) + else ReflectionUtils.staticSingletonInstance(implClass) + val implArgs = if (isBundle) args.others else args.c +: args.others + implMeth.invoke(implObj, implArgs.asInstanceOf[Seq[AnyRef]]: _*) + } + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala new file mode 100644 index 0000000000..0f89163803 --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala @@ -0,0 +1,74 @@ +package scala.reflect.macros +package runtime + +import scala.collection.mutable.{Map => MutableMap} +import scala.reflect.internal.Flags._ +import scala.reflect.runtime.ReflectionUtils +import scala.tools.nsc.util.ScalaClassLoader +import scala.tools.nsc.util.AbstractFileClassLoader + +trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + import global._ + import definitions._ + + /** Produces a function that can be used to invoke macro implementation for a given macro definition: + * 1) Looks up macro implementation symbol in this universe. + * 2) Loads its enclosing class from the macro classloader. + * 3) Loads the companion of that enclosing class from the macro classloader. + * 4) Resolves macro implementation within the loaded companion. + * + * @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors, + * `null` otherwise. + */ + private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime] + def macroRuntime(macroDef: Symbol): MacroRuntime = { + macroLogVerbose(s"looking for macro implementation: $macroDef") + if (fastTrack contains macroDef) { + macroLogVerbose("macro expansion is serviced by a fast track") + fastTrack(macroDef) + } else { + macroRuntimesCache.getOrElseUpdate(macroDef, new MacroRuntimeResolver(macroDef).resolveRuntime()) + } + } + + /** Macro classloader that is used to resolve and run macro implementations. + * Loads classes from from -cp (aka the library classpath). + * Is also capable of detecting REPL and reusing its classloader. + * + * When -Xmacro-jit is enabled, we sometimes fallback to on-the-fly compilation of macro implementations, + * which compiles implementations into a virtual directory (very much like REPL does) and then conjures + * a classloader mapped to that virtual directory. + */ + lazy val defaultMacroClassloader: ClassLoader = findMacroClassLoader() + + /** Abstracts away resolution of macro runtimes. + */ + type MacroRuntime = MacroArgs => Any + class MacroRuntimeResolver(val macroDef: Symbol) extends JavaReflectionResolvers + with ScalaReflectionResolvers { + val binding = loadMacroImplBinding(macroDef) + val isBundle = binding.isBundle + val className = binding.className + val methName = binding.methName + + def resolveRuntime(): MacroRuntime = { + if (className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded) { + args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing") + } else { + try { + macroLogVerbose(s"resolving macro implementation as $className.$methName (isBundle = $isBundle)") + macroLogVerbose(s"classloader is: ${ReflectionUtils.show(defaultMacroClassloader)}") + // resolveScalaReflectionRuntime(defaultMacroClassloader) + resolveJavaReflectionRuntime(defaultMacroClassloader) + } catch { + case ex: Exception => + macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") + macroDef setFlag IS_ERROR + null + } + } + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala new file mode 100644 index 0000000000..1999e525ff --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala @@ -0,0 +1,33 @@ +package scala.reflect.macros +package runtime + +import scala.reflect.runtime.{universe => ru} + +trait ScalaReflectionRuntimes { + self: scala.tools.nsc.typechecker.Analyzer => + + trait ScalaReflectionResolvers { + self: MacroRuntimeResolver => + + import global._ + + def resolveScalaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = { + val macroMirror: ru.JavaMirror = ru.runtimeMirror(classLoader) + val implContainerSym = macroMirror.classSymbol(Class.forName(className, true, classLoader)) + val implMethSym = implContainerSym.typeSignature.member(ru.TermName(methName)).asMethod + macroLogVerbose(s"successfully loaded macro impl as ($implContainerSym, $implMethSym)") + args => { + val implContainer = + if (isBundle) { + val implCtorSym = implContainerSym.typeSignature.member(ru.nme.CONSTRUCTOR).asMethod + macroMirror.reflectClass(implContainerSym).reflectConstructor(implCtorSym)(args.c) + } else { + macroMirror.reflectModule(implContainerSym.module.asModule).instance + } + val implMeth = macroMirror.reflect(implContainer).reflectMethod(implMethSym) + val implArgs = if (isBundle) args.others else args.c +: args.others + implMeth(implArgs: _*) + } + } + } +} diff --git a/src/compiler/scala/reflect/macros/runtime/package.scala b/src/compiler/scala/reflect/macros/runtime/package.scala new file mode 100644 index 0000000000..9ef8200760 --- /dev/null +++ b/src/compiler/scala/reflect/macros/runtime/package.scala @@ -0,0 +1,5 @@ +package scala.reflect.macros + +package object runtime { + type Context = scala.reflect.macros.contexts.Context +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala new file mode 100644 index 0000000000..ada8efa833 --- /dev/null +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -0,0 +1,71 @@ +package scala.reflect.macros +package util + +import scala.tools.nsc.typechecker.Analyzer + +trait Helpers { + self: Analyzer => + + import global._ + import definitions._ + + /** Transforms parameters lists of a macro impl. + * The `transform` function is invoked only for WeakTypeTag evidence parameters. + * + * The transformer takes two arguments: a value parameter from the parameter list + * and a type parameter that is witnesses by the value parameter. + * + * If the transformer returns a NoSymbol, the value parameter is not included from the result. + * If the transformer returns something else, this something else is included in the result instead of the value parameter. + * + * Despite of being highly esoteric, this function significantly simplifies signature analysis. + * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) + * or to streamline creation of the list of macro arguments. + */ + def transformTypeTagEvidenceParams(macroImplRef: Tree, transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { + val treeInfo.MacroImplReference(isBundle, owner, macroImpl, _) = macroImplRef + val paramss = macroImpl.paramss + if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do + val rc = + if (isBundle) macroImpl.owner.tpe.member(nme.c) + else { + def cparam = paramss.head.head + if (paramss.head.isEmpty || !(cparam.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do + cparam + } + def transformTag(param: Symbol): Symbol = param.tpe.dealias match { + case TypeRef(SingleType(SingleType(_, ac), universe), WeakTypeTagClass, targ :: Nil) + if ac == rc && universe == MacroContextUniverse => + transform(param, targ.typeSymbol) + case _ => + param + } + val transformed = paramss.last map transformTag filter (_ ne NoSymbol) + if (transformed.isEmpty) paramss.init else paramss.init :+ transformed + } + + private def dealiasAndRewrap(tp: Type)(fn: Type => Type): Type = { + if (isRepeatedParamType(tp)) scalaRepeatedType(fn(tp.typeArgs.head.dealias)) + else fn(tp.dealias) + } + + /** Increases metalevel of the type, i.e. transforms: + * * T to c.Expr[T] + * + * @see Metalevels.scala for more information and examples about metalevels + */ + def increaseMetalevel(pre: Type, tp: Type): Type = dealiasAndRewrap(tp) { + case tp => typeRef(pre, MacroContextExprClass, List(tp)) + } + + /** Decreases metalevel of the type, i.e. transforms: + * * c.Expr[T] to T + * * Anything else to Any + * + * @see Metalevels.scala for more information and examples about metalevels + */ + def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) { + case ExprClassOf(runtimeType) => runtimeType + case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala index 9659134e5b..0bffe55403 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -1,7 +1,7 @@ package scala.reflect.reify import scala.reflect.macros.{ReificationException, UnexpectedReificationException, TypecheckException} -import scala.reflect.macros.runtime.Context +import scala.reflect.macros.contexts.Context abstract class Taggers { val c: Context diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index ae0288186b..d3cae3d123 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -46,11 +46,14 @@ package object reify { def reifyType(global: Global)(typer: global.analyzer.Typer,universe: global.Tree, mirror: global.Tree, tpe: global.Type, concrete: Boolean = false): global.Tree = mkReifier(global)(typer, universe, mirror, tpe, concrete = concrete).reification.asInstanceOf[global.Tree] - def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { + def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe0: global.Type, concrete: Boolean = true): global.Tree = { import global._ import definitions._ import analyzer.enclosingMacroPosition + // SI-7375 + val tpe = tpe0.dealiasWiden + if (tpe.isSpliceable) { val classTagInScope = typer0.resolveClassTag(enclosingMacroPosition, tpe, allowMaterialization = false) if (!classTagInScope.isEmpty) return Select(classTagInScope, nme.runtimeClass) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index f1fccd6069..a08633ffc8 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -9,6 +9,7 @@ package nsc import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException } import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException } +import java.util.UUID._ import scala.compat.Platform.currentTime import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } @@ -16,6 +17,7 @@ import reporters.{ Reporter, ConsoleReporter } import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString, stackTraceHeadString } import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } +import scala.reflect.io.VirtualFile import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } import symtab.classfile.Pickler import plugins.Plugins @@ -1621,6 +1623,25 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } } + // TODO: provide a way to specify a pretty name for debugging purposes + private def randomFileName() = ( + "compileLateSynthetic-" + randomUUID().toString.replace("-", "") + ".scala" + ) + + def compileLate(code: PackageDef) { + // compatibility with SBT + // on the one hand, we need to specify some jfile here, otherwise sbt crashes with an NPE (SI-6870) + // on the other hand, we can't specify the obvious enclosingUnit, because then sbt somehow fails to run tests using type macros + // okay, now let's specify a guaranteedly non-existent file in an existing directory (so that we don't run into permission problems) + val syntheticFileName = randomFileName() + val fakeJfile = new java.io.File(syntheticFileName) + val virtualFile = new VirtualFile(syntheticFileName) { override def file = fakeJfile } + val sourceFile = new BatchSourceFile(virtualFile, code.toString) + val unit = new CompilationUnit(sourceFile) + unit.body = code + compileLate(unit) + } + /** Reset package class to state at typer (not sure what this * is needed for?) */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 89f933f577..fc532f5d44 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1423,8 +1423,9 @@ self => * }}} */ def postfixExpr(): Tree = { - val base = opstack - var top = prefixExpr() + val start = in.offset + val base = opstack + var top = prefixExpr() while (isIdent) { top = reduceStack(isExpr = true, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) @@ -1442,9 +1443,7 @@ self => val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(isExpr = true, base, topinfo.operand, 0, leftAssoc = true)) - return atPos(od.pos.startOrPoint, topinfo.offset) { - new PostfixSelect(od, topinfo.operator.encode) - } + return makePostfixSelect(start, topinfo.offset, od, topinfo.operator) } } reduceStack(isExpr = true, base, top, 0, leftAssoc = true) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index f737fcc635..ec4e932aae 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -242,6 +242,12 @@ abstract class TreeBuilder { Assign(lhs, rhs) } + /** Tree for `od op`, start is start0 if od.pos is borked. */ + def makePostfixSelect(start0: Int, end: Int, od: Tree, op: Name): Tree = { + val start = if (od.pos.isDefined) od.pos.startOrPoint else start0 + atPos(r2p(start, end, end)) { new PostfixSelect(od, op.encode) } + } + /** A type tree corresponding to (possibly unary) intersection type */ def makeIntersectionTypeTree(tps: List[Tree]): Tree = if (tps.tail.isEmpty) tps.head diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 98fb6bd0ef..250feb69bf 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -234,14 +234,10 @@ abstract class SymbolLoaders { } } if (!root.isEmptyPackageClass) { - // Only enter packages which contain a class or a non-empty package for (pkg <- classpath.packages) { - if (pkg.isEmptyOfClassfiles) { - log(s"Discarding $root/$pkg as it contains no classfiles.") - } - else - enterPackage(root, pkg.name, new PackageLoader(pkg)) + enterPackage(root, pkg.name, new PackageLoader(pkg)) } + openPackageModule(root) } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 6948d02fd5..fb927d15d3 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -491,8 +491,10 @@ abstract class ClassfileParser { } } - val c = if (currentIsTopLevel) pool.getClassSymbol(nameIdx) else clazz - if (currentIsTopLevel) { + val isTopLevel = !(currentClass containsChar '$') // Java class name; *don't* try to to use Scala name decoding (SI-7532) + + val c = if (isTopLevel) pool.getClassSymbol(nameIdx) else clazz + if (isTopLevel) { if (c != clazz) { if ((clazz eq NoSymbol) && (c ne NoSymbol)) clazz = c else mismatchError(c) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index c9a7cc2e3f..0f65b11e9b 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -342,11 +342,6 @@ abstract class Erasure extends AddInterfaces } } - // Each primitive value class has its own getClass for ultra-precise class object typing. - private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( - ScalaValueClasses map (_.tpe member nme.getClass_) - ) - // ## requires a little translation private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##) // Methods on Any/Object which we rewrite here while we still know what diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index dbcb6c19a0..fe1607c631 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -460,7 +460,7 @@ trait ContextErrors { def AbstractionFromVolatileTypeError(vd: ValDef) = issueNormalTypeError(vd, "illegal abstraction from value with volatile type "+vd.symbol.tpe) - private[ContextErrors] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) = + private[scala] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) = "wrong number of type parameters for "+treeSymTypeMsg(fun) def TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) = { @@ -476,7 +476,7 @@ trait ContextErrors { // doTypeApply //tryNamesDefaults def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = - NormalTypeError(tree, "macros application do not support named and/or default arguments") + NormalTypeError(tree, "macro applications do not support named and/or default arguments") def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) = NormalTypeError(tree, "too many arguments for "+treeSymTypeMsg(fun)) @@ -571,7 +571,7 @@ trait ContextErrors { //adapt def MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) = { val message = - if (meth.isMacro) MacroPartialApplicationErrorMessage + if (meth.isMacro) MacroTooFewArgumentListsMessage else "missing arguments for " + meth.fullLocationString + ( if (meth.isConstructor) "" else ";\nfollow this method with `_' if you want to treat it as a partially applied function" @@ -692,7 +692,6 @@ trait ContextErrors { issueNormalTypeError(expandee, s"macro in $role role can only expand into $allowedExpansions") } - // same reason as for MacroBodyTypecheckException case object MacroExpansionException extends Exception with scala.util.control.ControlThrowable protected def macroExpansionError(expandee: Tree, msg: String, pos: Position = NoPosition) = { @@ -703,15 +702,24 @@ trait ContextErrors { throw MacroExpansionException } - def MacroPartialApplicationErrorMessage = "macros cannot be partially applied" - def MacroPartialApplicationError(expandee: Tree) = { + private def macroExpansionError2(expandee: Tree, msg: String) = { // macroExpansionError won't work => swallows positions, hence needed to do issueTypeError // kinda contradictory to the comment in `macroExpansionError`, but this is how it works - issueNormalTypeError(expandee, MacroPartialApplicationErrorMessage) + issueNormalTypeError(expandee, msg) setError(expandee) throw MacroExpansionException } + private def MacroTooFewArgumentListsMessage = "too few argument lists for macro invocation" + def MacroTooFewArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooFewArgumentListsMessage) + + private def MacroTooManyArgumentListsMessage = "too many argument lists for macro invocation" + def MacroTooManyArgumentListsError(expandee: Tree) = macroExpansionError2(expandee, MacroTooManyArgumentListsMessage) + + def MacroTooFewArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too few arguments for macro invocation") + + def MacroTooManyArgumentsError(expandee: Tree) = macroExpansionError2(expandee, "too many arguments for macro invocation") + def MacroGeneratedAbort(expandee: Tree, ex: AbortMacroException) = { // errors have been reported by the macro itself, so we do nothing here macroLogVerbose("macro expansion has been aborted") @@ -917,7 +925,7 @@ trait ContextErrors { kindErrors.toList.mkString("\n", ", ", "")) } - private[ContextErrors] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = { + private[scala] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = { if (explaintypes) { val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds) (targs, bounds).zipped foreach ((targ, bound) => explainTypes(bound.lo, targ)) @@ -1224,142 +1232,4 @@ trait ContextErrors { setError(arg) } } - - // using an exception here is actually a good idea - // because the lifespan of this exception is extremely small and controlled - // moreover exceptions let us avoid an avalanche of "if (!hasError) do stuff" checks - case object MacroBodyTypecheckException extends Exception with scala.util.control.ControlThrowable - - trait MacroErrors { - self: MacroTyper => - - private implicit val context0 = typer.context - val context = typer.context - - // helpers - - private def lengthMsg(flavor: String, violation: String, extra: Symbol) = { - val noun = if (flavor == "value") "parameter" else "type parameter" - val message = noun + " lists have different length, " + violation + " extra " + noun - val suffix = if (extra ne NoSymbol) " " + extra.defString else "" - message + suffix - } - - private def abbreviateCoreAliases(s: String): String = List("WeakTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x)) - - private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = { - var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString - if (abbreviate) argsPart = abbreviateCoreAliases(argsPart) - var retPart = restpe.toString - if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart) - argsPart + ": " + retPart - } - - // not exactly an error generator, but very related - // and I dearly wanted to push it away from Macros.scala - private def checkSubType(slot: String, rtpe: Type, atpe: Type) = { - val ok = if (macroDebugVerbose) { - withTypesExplained(rtpe <:< atpe) - } else rtpe <:< atpe - if (!ok) { - if (!macroDebugVerbose) - explainTypes(rtpe, atpe) - compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString))) - } - } - - // errors - - private def fail() = { - // need to set the IS_ERROR flag to prohibit spurious expansions - if (macroDef != null) macroDef setFlag IS_ERROR - // not setting ErrorSymbol as in `infer.setError`, because we still need to know that it's a macro - // otherwise assignTypeToTree in Namers might fail if macroDdef.tpt == EmptyTree - macroDdef setType ErrorType - throw MacroBodyTypecheckException - } - - private def genericError(tree: Tree, message: String) = { - issueNormalTypeError(tree, message) - fail() - } - - private def implRefError(message: String) = { - val treeInfo.Applied(implRef, _, _) = macroDdef.rhs - genericError(implRef, message) - } - - private def compatibilityError(message: String) = - implRefError( - "macro implementation has wrong shape:"+ - "\n required: " + showMeth(rparamss, rret, abbreviate = true) + - "\n found : " + showMeth(aparamss, aret, abbreviate = false) + - "\n" + message) - - // Phase I: sanity checks - - def MacroDefIsFastTrack() = { - macroLogVerbose("typecheck terminated unexpectedly: macro is fast track") - assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type") - throw MacroBodyTypecheckException // don't call fail, because we don't need IS_ERROR - } - - def MacroDefIsQmarkQmarkQmark() = { - macroLogVerbose("typecheck terminated unexpectedly: macro is ???") - throw MacroBodyTypecheckException - } - - def MacroFeatureNotEnabled() = { - macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled") - fail() - } - - // Phase II: typecheck the right-hand side of the macro def - - // do nothing, just fail. relevant typecheck errors have already been reported - def MacroDefUntypeableBodyError() = fail() - - def MacroDefInvalidBodyError() = genericError(macroDdef, "macro body has wrong shape:\n required: macro [<implementation object>].<method name>[[<type args>]]") - - def MacroImplNotPublicError() = implRefError("macro implementation must be public") - - def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded") - - def MacroImplWrongNumberOfTypeArgumentsError(macroImplRef: Tree) = implRefError(typer.TyperErrorGen.TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef)) - - def MacroImplNotStaticError() = implRefError("macro implementation must be in statically accessible object") - - // Phase III: check compatibility between the macro def and its macro impl - // aXXX (e.g. aparams) => characteristics of the macro impl ("a" stands for "actual") - // rXXX (e.g. rparams) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference") - - def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than WeakTypeTag evidences") - - def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ") - - def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length))) - - def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length)))) - - def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkSubType("parameter " + rparam.name, rparam.tpe, atpe) - - def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkSubType("return type", atpe, rret) - - def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name) - - def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = { - if (isRepeated(rparam) && !isRepeated(aparam)) - compatibilityError("types incompatible for parameter " + rparam.name + ": corresponding is not a vararg parameter") - if (!isRepeated(rparam) && isRepeated(aparam)) - compatibilityError("types incompatible for parameter " + aparam.name + ": corresponding is not a vararg parameter") - } - - def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) = - compatibilityError(typer.infer.InferErrorGen.NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes)) - - def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) = - compatibilityError( - "type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+ - ex.getMessage) - } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 5622f67459..b53efafdd4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -931,22 +931,11 @@ trait Implicits { if (DivergentImplicitRecovery.sym != null) { DivergingImplicitExpansionError(tree, pt, DivergentImplicitRecovery.sym)(context) } - else if (invalidImplicits.nonEmpty) { - val sym = invalidImplicits.head - // We don't even dare look if errors are being buffered - // !sym.hasFlag(LOCKED) is a hail mary between SI-2206 and SI-7486 - def isSensibleAddendum = !sym.hasFlag(LOCKED) && (pt match { - case Function1(_, out) => out <:< sym.tpe.finalResultType - case _ => pt <:< sym.tpe.finalResultType - }) - // Don't pitch in with this theory unless it looks plausible that the - // implicit would have helped + + if (invalidImplicits.nonEmpty) setAddendum(pos, () => - if (isSensibleAddendum) - s"\n Note: implicit $sym is not applicable here because it comes after the application point and it lacks an explicit result type" - else "" + s"\n Note: implicit ${invalidImplicits.head} is not applicable here because it comes after the application point and it lacks an explicit result type" ) - } } best diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 5ac37251ee..6c4d1e20aa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1,6 +1,7 @@ package scala.tools.nsc package typechecker +import java.lang.Math.min import symtab.Flags._ import scala.tools.nsc.util._ import scala.reflect.runtime.ReflectionUtils @@ -9,7 +10,12 @@ import scala.reflect.ClassTag import scala.reflect.internal.util.Statistics import scala.reflect.macros.util._ import scala.util.control.ControlThrowable -import scala.reflect.macros.runtime.AbortMacroException +import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} +import scala.reflect.runtime.{universe => ru} +import scala.reflect.macros.compiler.DefaultMacroCompiler +import scala.tools.reflect.FastTrack +import scala.runtime.ScalaRunTime +import Fingerprint._ /** * Code to deal with macros, namely with: @@ -36,7 +42,7 @@ import scala.reflect.macros.runtime.AbortMacroException * (Expr(elems)) * (TypeTag(Int)) */ -trait Macros extends scala.tools.reflect.FastTrack with Traces { +trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { self: Analyzer => import global._ @@ -74,7 +80,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * Includes a path to load the implementation via Java reflection, * and various accounting information necessary when composing an argument list for the reflective invocation. */ - private case class MacroImplBinding( + case class MacroImplBinding( + // Is this macro impl a bundle (a trait extending Macro) or a vanilla def? + val isBundle: Boolean, // Java class name of the class that contains the macro implementation // is used to load the corresponding object with Java reflection className: String, @@ -82,14 +90,21 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // `className` and `methName` are all we need to reflectively invoke a macro implementation // because macro implementations cannot be overloaded methName: String, - // flattens the macro impl's parameter lists having symbols replaced with metadata - // currently metadata is an index of the type parameter corresponding to that type tag (if applicable) - // f.ex. for: def impl[T: WeakTypeTag, U: WeakTypeTag, V](c: Context)(x: c.Expr[T]): (U, V) = ??? - // `signature` will be equal to List(-1, -1, 0, 1) - signature: List[Int], + // flattens the macro impl's parameter lists having symbols replaced with their fingerprints + // currently fingerprints are calculated solely from types of the symbols: + // * c.Expr[T] => IMPLPARAM_EXPR + // * c.WeakTypeTag[T] => index of the type parameter corresponding to that type tag + // * everything else (e.g. scala.reflect.macros.Context) => IMPLPARAM_OTHER + // f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: Context)(x: c.Expr[T], y: c.Tree): (U, V) = ??? + // `signature` will be equal to List(List(Other), List(Lifted, Other), List(Tagged(0), Tagged(2))) + signature: List[List[Fingerprint]], // type arguments part of a macro impl ref (the right-hand side of a macro definition) // these trees don't refer to a macro impl, so we can pickle them as is - targs: List[Tree]) + targs: List[Tree]) { + + // Was this binding derived from a `def ... = macro ???` definition? + def is_??? = className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded + } /** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation * with synthetic content that carries the payload described in `MacroImplBinding`. @@ -102,31 +117,35 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * * @scala.reflect.macros.internal.macroImpl( * `macro`( - * "signature" = List(-1), + * "isBundle" = false, + * "signature" = List(Other), * "methodName" = "impl", - * "versionFormat" = 1, + * "versionFormat" = <current version format>, * "className" = "Macros$")) */ - private object MacroImplBinding { - val versionFormat = 1 + object MacroImplBinding { + val versionFormat = 4.0 def pickleAtom(obj: Any): Tree = obj match { case list: List[_] => Apply(Ident(ListModule), list map pickleAtom) case s: String => Literal(Constant(s)) - case i: Int => Literal(Constant(i)) + case d: Double => Literal(Constant(d)) + case b: Boolean => Literal(Constant(b)) + case f: Fingerprint => Literal(Constant(f.value)) } def unpickleAtom(tree: Tree): Any = tree match { case Apply(list @ Ident(_), args) if list.symbol == ListModule => args map unpickleAtom case Literal(Constant(s: String)) => s - case Literal(Constant(i: Int)) => i + case Literal(Constant(d: Double)) => d + case Literal(Constant(b: Boolean)) => b + case Literal(Constant(i: Int)) => new Fingerprint(i) } def pickle(macroImplRef: Tree): Tree = { - val MacroImplReference(owner, macroImpl, targs) = macroImplRef - val paramss = macroImpl.paramss + val MacroImplReference(isBundle, owner, macroImpl, targs) = macroImplRef // todo. refactor when fixing SI-5498 def className: String = { @@ -142,13 +161,20 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { loop(owner) } - def signature: List[Int] = { - val transformed = transformTypeTagEvidenceParams(paramss, (param, tparam) => tparam) - transformed.flatten map (p => if (p.isTerm) -1 else p.paramPos) + def signature: List[List[Fingerprint]] = { + def fingerprint(tpe: Type): Fingerprint = tpe.dealiasWiden match { + case TypeRef(_, RepeatedParamClass, underlying :: Nil) => fingerprint(underlying) + case ExprClassOf(_) => Lifted + case _ => Other + } + + val transformed = transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => tparam) + mmap(transformed)(p => if (p.isTerm) fingerprint(p.info) else Tagged(p.paramPos)) } val payload = List[(String, Any)]( "versionFormat" -> versionFormat, + "isBundle" -> isBundle, "className" -> className, "methodName" -> macroImpl.name.toString, "signature" -> signature @@ -188,362 +214,119 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val Apply(_, pickledPayload) = wrapped val payload = pickledPayload.map{ case Assign(k, v) => (unpickleAtom(k), unpickleAtom(v)) }.toMap - val pickleVersionFormat = payload("versionFormat").asInstanceOf[Int] - if (versionFormat != pickleVersionFormat) throw new Error(s"macro impl binding format mismatch: expected $versionFormat, actual $pickleVersionFormat") + def fail(msg: String) = abort(s"bad macro impl binding: $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") + val raw: Any = payload(field) + if (raw == null) failField(s"is not supposed to be null") + val expected = ScalaRunTime.box(clazz) + val actual = raw.getClass + if (!expected.isAssignableFrom(actual)) failField(s"has wrong type: expected $expected, actual $actual") + raw.asInstanceOf[T] + } + + val pickleVersionFormat = unpickle("versionFormat", classOf[Double]) + if (versionFormat != pickleVersionFormat) fail(s"expected version format $versionFormat, actual $pickleVersionFormat") - val className = payload("className").asInstanceOf[String] - val methodName = payload("methodName").asInstanceOf[String] - val signature = payload("signature").asInstanceOf[List[Int]] - MacroImplBinding(className, methodName, signature, targs) + val isBundle = unpickle("isBundle", classOf[Boolean]) + val className = unpickle("className", classOf[String]) + val methodName = unpickle("methodName", classOf[String]) + val signature = unpickle("signature", classOf[List[List[Fingerprint]]]) + MacroImplBinding(isBundle, className, methodName, signature, targs) } } - private def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = { + def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = { val pickle = MacroImplBinding.pickle(macroImplRef) macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(pickle), Nil) } - private def loadMacroImplBinding(macroDef: Symbol): MacroImplBinding = { + def loadMacroImplBinding(macroDef: Symbol): MacroImplBinding = { val Some(AnnotationInfo(_, List(pickle), _)) = macroDef.getAnnotation(MacroImplAnnotation) MacroImplBinding.unpickle(pickle) } - /** Transforms parameters lists of a macro impl. - * The `transform` function is invoked only for WeakTypeTag evidence parameters. - * - * The transformer takes two arguments: a value parameter from the parameter list - * and a type parameter that is witnesses by the value parameter. - * - * If the transformer returns a NoSymbol, the value parameter is not included from the result. - * If the transformer returns something else, this something else is included in the result instead of the value parameter. - * - * Despite of being highly esoteric, this function significantly simplifies signature analysis. - * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) - * or to streamline creation of the list of macro arguments. - */ - private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { - if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do - if (paramss.head.isEmpty || !(paramss.head.head.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do - def transformTag(param: Symbol): Symbol = param.tpe.dealias match { - case TypeRef(SingleType(SingleType(NoPrefix, c), universe), WeakTypeTagClass, targ :: Nil) - if c == paramss.head.head && universe == MacroContextUniverse => - transform(param, targ.typeSymbol) - case _ => - param - } - val transformed = paramss.last map transformTag filter (_ ne NoSymbol) - if (transformed.isEmpty) paramss.init else paramss.init :+ transformed - } - - def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroImpl: Symbol): Type = { - // Step I. Transform c.Expr[T] to T - var runtimeType = macroImpl.tpe.finalResultType.dealias match { - case TypeRef(_, ExprClass, runtimeType :: Nil) => runtimeType - case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference - } - - // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body - runtimeType = runtimeType.substituteTypes(macroImpl.typeParams, loadMacroImplBinding(macroDdef.symbol).targs.map(_.tpe)) - - // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY - def unsigma(tpe: Type): Type = - transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) match { - case (implCtxParam :: Nil) :: implParamss => - val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap - object UnsigmaTypeMap extends TypeMap { - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) => - val pre1 = pre match { - case SingleType(SingleType(SingleType(NoPrefix, c), prefix), value) if c == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => - ThisType(macroDdef.symbol.owner) - case SingleType(SingleType(NoPrefix, implParam), value) if value == ExprValue => - implToDef get implParam map (defParam => SingleType(NoPrefix, defParam.symbol)) getOrElse pre + def computeMacroDefTypeFromMacroImplRef(macroDdef: DefDef, macroImplRef: Tree): Type = { + macroImplRef match { + case MacroImplReference(_, _, macroImpl, targs) => + // Step I. Transform c.Expr[T] to T and everything else to Any + var runtimeType = decreaseMetalevel(macroImpl.info.finalResultType) + + // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body + runtimeType = runtimeType.substituteTypes(macroImpl.typeParams, targs map (_.tpe)) + + // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY + def unsigma(tpe: Type): Type = + transformTypeTagEvidenceParams(macroImplRef, (param, tparam) => NoSymbol) match { + case (implCtxParam :: Nil) :: implParamss => + val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap + object UnsigmaTypeMap extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, args) => + val pre1 = pre match { + case SingleType(SingleType(SingleType(NoPrefix, c), prefix), value) if c == implCtxParam && prefix == MacroContextPrefix && value == ExprValue => + ThisType(macroDdef.symbol.owner) + case SingleType(SingleType(NoPrefix, implParam), value) if value == ExprValue => + implToDef get implParam map (defParam => SingleType(NoPrefix, defParam.symbol)) getOrElse pre + case _ => + pre + } + val args1 = args map mapOver + TypeRef(pre1, sym, args1) case _ => - pre + mapOver(tp) } - val args1 = args map mapOver - TypeRef(pre1, sym, args1) - case _ => - mapOver(tp) - } - } - - UnsigmaTypeMap(tpe) - case _ => - tpe - } + } - unsigma(runtimeType) - } + UnsigmaTypeMap(tpe) + case _ => + tpe + } - /** A reference macro implementation signature compatible with a given macro definition. - * - * In the example above for the following macro def: - * def foo[T](xs: List[T]): T = macro fooBar - * - * This function will return: - * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]]): c.Expr[T] - * - * Note that type tag evidence parameters are not included into the result. - * Type tag context bounds for macro impl tparams are optional. - * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here. - * - * @param macroDef The macro definition symbol - * @param tparams The type parameters of the macro definition - * @param vparamss The value parameters of the macro definition - * @param retTpe The return type of the macro definition - */ - private def macroImplSig(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[Symbol]], Type) = { - // had to move method's body to an object because of the recursive dependencies between sigma and param - object SigGenerator { - def WeakTagClass = getMember(MacroContextClass, tpnme.WeakTypeTag) - def ExprClass = getMember(MacroContextClass, tpnme.Expr) - val cache = scala.collection.mutable.Map[Symbol, Symbol]() - val ctxParam = makeParam(nme.macroContext, macroDef.pos, MacroContextClass.tpe, SYNTHETIC) - val paramss = List(ctxParam) :: mmap(vparamss)(param) - val implReturnType = typeRef(singleType(NoPrefix, ctxParam), ExprClass, List(sigma(retTpe))) - - object SigmaTypeMap extends TypeMap { - def mapPrefix(pre: Type) = pre match { - case ThisType(sym) if sym == macroDef.owner => - singleType(singleType(singleType(NoPrefix, ctxParam), MacroContextPrefix), ExprValue) - case SingleType(NoPrefix, sym) => - mfind(vparamss)(_.symbol == sym).fold(pre)(p => singleType(singleType(NoPrefix, param(p)), ExprValue)) - case _ => - mapOver(pre) - } - def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) => - val pre1 = mapPrefix(pre) - val args1 = mapOverArgs(args, sym.typeParams) - if ((pre eq pre1) && (args eq args1)) tp - else typeRef(pre1, sym, args1) - case _ => - mapOver(tp) - } - } - def sigma(tpe: Type): Type = SigmaTypeMap(tpe) - - def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) = - macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe - def implType(isType: Boolean, origTpe: Type): Type = { - def tsym = if (isType) WeakTagClass else ExprClass - def targ = origTpe.typeArgs.headOption getOrElse NoType - - if (isRepeatedParamType(origTpe)) - scalaRepeatedType(implType(isType, sigma(targ))) - else - typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(origTpe))) - } - def param(tree: Tree): Symbol = ( - cache.getOrElseUpdate(tree.symbol, { - val sym = tree.symbol - makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe), sym.flags) - }) - ) + unsigma(runtimeType) + case _ => + ErrorType } - - import SigGenerator._ - macroLogVerbose(sm""" - |generating macroImplSigs for: $macroDef - |tparams are: $tparams - |vparamss are: $vparamss - |retTpe is: $retTpe - |macroImplSig is: $paramss, $implReturnType - """.trim) - (paramss, implReturnType) } - /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method, + /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method or a top-level macro bundle, * and that that method is signature-wise compatible with the given macro definition. * - * @return Typechecked rhs of the given macro definition if everything is okay. + * @return Macro impl reference for the given macro definition if everything is okay. * EmptyTree if an error occurs. */ - def typedMacroBody(typer: Typer, macroDdef: DefDef): Tree = - try new MacroTyper(typer, macroDdef).typed - catch { case MacroBodyTypecheckException => EmptyTree } - - class MacroTyper(val typer: Typer, val macroDdef: DefDef) extends MacroErrors { - private def typed1Expr(tree: Tree) = typer.typed1(tree, EXPRmode, WildcardType) - - // Phase I: sanity checks + def typedMacroBody(typer: Typer, macroDdef: DefDef): Tree = { val macroDef = macroDdef.symbol - macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos)) assert(macroDef.isMacro, macroDdef) - if (fastTrack contains macroDef) MacroDefIsFastTrack() - if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) MacroFeatureNotEnabled() - - // we use typed1 instead of typed, because otherwise adapt is going to mess us up - // if adapt sees <qualifier>.<method>, it will want to perform eta-expansion and will fail - // unfortunately, this means that we have to manually trigger macro expansion - // because it's adapt which is responsible for automatic expansion during typechecking - def typecheckRhs(rhs: Tree): Tree = { - try { - // interestingly enough, just checking isErroneous doesn't cut it - // e.g. a "type arguments [U] do not conform to method foo's type parameter bounds" error - // doesn't manifest itself as an error in the resulting tree - val prevNumErrors = reporter.ERROR.count - var rhs1 = typed1Expr(rhs) - def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous - while (rhsNeedsMacroExpansion) { - rhs1 = macroExpand1(typer, rhs1) match { - case Success(expanded) => - try { - val typechecked = typed1Expr(expanded) - macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) - typechecked - } finally { - popMacroContext() - } - case Fallback(fallback) => - typed1Expr(fallback) - case Delayed(delayed) => - typer.instantiate(delayed, EXPRmode, WildcardType) - case Skipped(skipped) => - skipped - case Failure(failure) => - failure - } - } - val typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors - if (typecheckedWithErrors) MacroDefUntypeableBodyError() - rhs1 - } catch { - case ex: TypeError => - typer.reportTypeError(context, rhs.pos, ex) - MacroDefUntypeableBodyError() - } - } - - // Phase II: typecheck the right-hand side of the macro def - val typed = typecheckRhs(macroDdef.rhs) - typed match { - case MacroImplReference(_, meth, _) if meth == Predef_??? => - bindMacroImpl(macroDef, typed) - MacroDefIsQmarkQmarkQmark() - case MacroImplReference(owner, meth, targs) => - if (!meth.isMethod) MacroDefInvalidBodyError() - if (!meth.isPublic) MacroImplNotPublicError() - if (meth.isOverloaded) MacroImplOverloadedError() - if (!owner.isStaticOwner && !owner.moduleClass.isStaticOwner) MacroImplNotStaticError() - if (meth.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError(typed) - bindMacroImpl(macroDef, typed) - case _ => - MacroDefInvalidBodyError() - } - - // Phase III: check compatibility between the macro def and its macro impl - // this check ignores type tag evidence parameters, because type tag context bounds are optional - // aXXX (e.g. aparamss) => characteristics of the macro impl ("a" stands for "actual") - // rXXX (e.g. rparamss) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference") - val macroImpl = typed.symbol - val aparamss = transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) - val aret = macroImpl.tpe.finalResultType - val macroDefRet = - if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe - else computeMacroDefTypeFromMacroImpl(macroDdef, macroImpl) - val (rparamss, rret) = macroImplSig(macroDef, macroDdef.tparams, macroDdef.vparamss, macroDefRet) - - val implicitParams = aparamss.flatten filter (_.isImplicit) - if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams) - if (aparamss.length != rparamss.length) MacroImplParamssMismatchError() - - val atparams = macroImpl.typeParams - val atvars = atparams map freshVar - def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars) - - try { - map2(aparamss, rparamss)((aparams, rparams) => { - if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams) - if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams) - }) - - // cannot fuse these loops because if aparamss.flatten != rparamss.flatten - // then `atpeToRtpe` is going to fail with an unsound substitution - map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => { - if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam) - if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam) - val aparamtpe = aparam.tpe.dealias match { - case RefinedType(List(tpe), Scope(sym)) if tpe =:= MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe - case tpe => tpe - } - checkMacroImplParamTypeMismatch(atpeToRtpe(aparamtpe), rparam) - }) - - checkMacroImplResultTypeMismatch(atpeToRtpe(aret), rret) - - val maxLubDepth = lubDepth(aparamss.flatten map (_.tpe)) max lubDepth(rparamss.flatten map (_.tpe)) - val atargs = solvedTypes(atvars, atparams, atparams map varianceInType(aret), upper = false, depth = maxLubDepth) - val boundsOk = typer.silent(_.infer.checkBounds(macroDdef, NoPrefix, NoSymbol, atparams, atargs, "")) - boundsOk match { - case SilentResultValue(true) => // do nothing, success - case SilentResultValue(false) | SilentTypeError(_) => MacroImplTargMismatchError(atargs, atparams) - } - } catch { - case ex: NoInstance => MacroImplTparamInstantiationError(atparams, ex) - } - } - - /** Macro classloader that is used to resolve and run macro implementations. - * Loads classes from from -cp (aka the library classpath). - * Is also capable of detecting REPL and reusing its classloader. - */ - lazy val macroClassloader: ClassLoader = findMacroClassLoader() - /** Produces a function that can be used to invoke macro implementation for a given macro definition: - * 1) Looks up macro implementation symbol in this universe. - * 2) Loads its enclosing class from the macro classloader. - * 3) Loads the companion of that enclosing class from the macro classloader. - * 4) Resolves macro implementation within the loaded companion. - * - * @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors, - * `null` otherwise. - */ - type MacroRuntime = MacroArgs => Any - private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime]() - private def macroRuntime(macroDef: Symbol): MacroRuntime = { - macroLogVerbose(s"looking for macro implementation: $macroDef") + macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos)) if (fastTrack contains macroDef) { - macroLogVerbose("macro expansion is serviced by a fast track") - fastTrack(macroDef) + macroLogVerbose("typecheck terminated unexpectedly: macro is fast track") + assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type") + EmptyTree } else { - macroRuntimesCache.getOrElseUpdate(macroDef, { - val binding = loadMacroImplBinding(macroDef) - val className = binding.className - val methName = binding.methName - macroLogVerbose(s"resolved implementation as $className.$methName") - - if (binding.className == Predef_???.owner.fullName.toString && binding.methName == Predef_???.name.encoded) { - args => throw new AbortMacroException(args.c.enclosingPosition, "macro implementation is missing") - } else { - // I don't use Scala reflection here, because it seems to interfere with JIT magic - // whenever you instantiate a mirror (and not do anything with in, just instantiate), performance drops by 15-20% - // I'm not sure what's the reason - for me it's pure voodoo - // upd. my latest experiments show that everything's okay - // it seems that in 2.10.1 we can easily switch to Scala reflection - try { - macroLogVerbose(s"loading implementation class: $className") - macroLogVerbose(s"classloader is: ${ReflectionUtils.show(macroClassloader)}") - val implObj = ReflectionUtils.staticSingletonInstance(macroClassloader, className) - // relies on the fact that macro impls cannot be overloaded - // so every methName can resolve to at maximum one method - val implMeths = implObj.getClass.getDeclaredMethods.find(_.getName == methName) - val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") } - macroLogVerbose(s"successfully loaded macro impl as ($implObj, $implMeth)") - args => implMeth.invoke(implObj, ((args.c +: args.others) map (_.asInstanceOf[AnyRef])): _*) - } catch { - case ex: Exception => - macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") - macroDef setFlag IS_ERROR - null - } - } - }) + def fail() = { if (macroDef != null) macroDef setFlag IS_ERROR; macroDdef setType ErrorType; EmptyTree } + def success(macroImplRef: Tree) = { bindMacroImpl(macroDef, macroImplRef); macroImplRef } + + if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) { + macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled") + fail() + } else { + val macroDdef1: macroDdef.type = macroDdef + val typer1: typer.type = typer + val macroCompiler = new { + val global: self.global.type = self.global + val typer: self.global.analyzer.Typer = typer1.asInstanceOf[self.global.analyzer.Typer] + val macroDdef: self.global.DefDef = macroDdef1 + } with DefaultMacroCompiler + val macroImplRef = macroCompiler.resolveMacroImpl + if (macroImplRef.isEmpty) fail() else success(macroImplRef) + } } } - private def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = { + def macroContext(typer: Typer, prefixTree: Tree, expandeeTree: Tree): MacroContext = { new { val universe: self.global.type = self.global val callsiteTyper: universe.analyzer.Typer = typer.asInstanceOf[global.analyzer.Typer] @@ -560,92 +343,111 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { case class MacroArgs(c: MacroContext, others: List[Any]) private def macroArgs(typer: Typer, expandee: Tree): MacroArgs = { - val macroDef = expandee.symbol - val prefixTree = expandee.collect{ case Select(qual, name) => qual }.headOption.getOrElse(EmptyTree) - val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee)) - var typeArgs = List[Tree]() - val exprArgs = ListBuffer[List[Expr[_]]]() - def collectMacroArgs(tree: Tree): Unit = tree match { - case Apply(fn, args) => - // todo. infer precise typetag for this Expr, namely the declared type of the corresponding macro impl argument - exprArgs.prepend(args map (arg => context.Expr[Nothing](arg)(TypeTag.Nothing))) - collectMacroArgs(fn) - case TypeApply(fn, args) => - typeArgs = args - collectMacroArgs(fn) - case _ => - } - collectMacroArgs(expandee) + val macroDef = expandee.symbol + val paramss = macroDef.paramss + val treeInfo.Applied(core, targs, argss) = expandee + val prefix = core match { case Select(qual, _) => qual; case _ => EmptyTree } + val context = expandee.attachments.get[MacroRuntimeAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefix, expandee)) - val argcDoesntMatch = macroDef.paramss.length != exprArgs.length - val nullaryArgsEmptyParams = exprArgs.isEmpty && macroDef.paramss == ListOfNil - if (argcDoesntMatch && !nullaryArgsEmptyParams) { typer.TyperErrorGen.MacroPartialApplicationError(expandee) } + macroLogVerbose(sm""" + |context: $context + |prefix: $prefix + |targs: $targs + |argss: $argss + |paramss: $paramss + """.trim) - val argss: List[List[Any]] = exprArgs.toList - macroLogVerbose(s"context: $context") - macroLogVerbose(s"argss: $argss") + import typer.TyperErrorGen._ + val isNullaryArgsEmptyParams = argss.isEmpty && paramss == ListOfNil + if (paramss.length < argss.length) MacroTooManyArgumentListsError(expandee) + if (paramss.length > argss.length && !isNullaryArgsEmptyParams) MacroTooFewArgumentListsError(expandee) - val preparedArgss: List[List[Any]] = + val macroImplArgs: List[Any] = if (fastTrack contains macroDef) { // Take a dry run of the fast track implementation - if (fastTrack(macroDef) validate expandee) argss - else typer.TyperErrorGen.MacroPartialApplicationError(expandee) + if (fastTrack(macroDef) validate expandee) argss.flatten + else MacroTooFewArgumentListsError(expandee) } else { - // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences - // consider the following example: - // - // class D[T] { - // class C[U] { - // def foo[V] = macro Impls.foo[T, U, V] - // } - // } - // - // val outer1 = new D[Int] - // val outer2 = new outer1.C[String] - // outer2.foo[Boolean] - // - // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` - // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node - // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim - val binding = loadMacroImplBinding(macroDef) - macroLogVerbose(s"binding: $binding") - val tags = binding.signature filter (_ != -1) map (paramPos => { - val targ = binding.targs(paramPos).tpe.typeSymbol - val tpe = if (targ.isTypeParameterOrSkolem) { - if (targ.owner == macroDef) { - // doesn't work when macro def is compiled separately from its usages - // then targ is not a skolem and isn't equal to any of macroDef.typeParams - // val argPos = targ.deSkolemize.paramPos - val argPos = macroDef.typeParams.indexWhere(_.name == targ.name) - typeArgs(argPos).tpe + def calculateMacroArgs(binding: MacroImplBinding) = { + val signature = if (binding.isBundle) binding.signature else binding.signature.tail + macroLogVerbose(s"binding: $binding") + + // STEP I: prepare value arguments of the macro expansion + // wrap argss in c.Expr if necessary (i.e. if corresponding macro impl param is of type c.Expr[T]) + // expand varargs (nb! varargs can apply to any parameter section, not necessarily to the last one) + val trees = map3(argss, paramss, signature)((args, defParams, implParams) => { + val isVarargs = isVarArgsList(defParams) + if (isVarargs) { + if (defParams.length > args.length + 1) MacroTooFewArgumentsError(expandee) + } else { + if (defParams.length < args.length) MacroTooManyArgumentsError(expandee) + if (defParams.length > args.length) MacroTooFewArgumentsError(expandee) + } + + val wrappedArgs = mapWithIndex(args)((arg, j) => { + val fingerprint = implParams(min(j, implParams.length - 1)) + fingerprint match { + case Lifted => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752 + case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " + + s"corresponding to arg $arg in $argss") + } + }) + + if (isVarargs) { + val (normal, varargs) = wrappedArgs splitAt (defParams.length - 1) + normal :+ varargs // pack all varargs into a single Seq argument (varargs Scala style) + } else wrappedArgs + }) + macroLogVerbose(s"trees: $trees") + + // STEP II: prepare type arguments of the macro expansion + // if paramss have typetag context bounds, add an arglist to argss if necessary and instantiate the corresponding evidences + // consider the following example: + // + // class D[T] { + // class C[U] { + // def foo[V] = macro Impls.foo[T, U, V] + // } + // } + // + // val outer1 = new D[Int] + // val outer2 = new outer1.C[String] + // outer2.foo[Boolean] + // + // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom` + // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node + // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim + val tags = signature.flatten collect { case f if f.isTag => f.paramPos } map (paramPos => { + val targ = binding.targs(paramPos).tpe.typeSymbol + val tpe = if (targ.isTypeParameterOrSkolem) { + if (targ.owner == macroDef) { + // doesn't work when macro def is compiled separately from its usages + // then targ is not a skolem and isn't equal to any of macroDef.typeParams + // val argPos = targ.deSkolemize.paramPos + val argPos = macroDef.typeParams.indexWhere(_.name == targ.name) + targs(argPos).tpe + } else + targ.tpe.asSeenFrom( + if (prefix == EmptyTree) macroDef.owner.tpe else prefix.tpe, + macroDef.owner) } else - targ.tpe.asSeenFrom( - if (prefixTree == EmptyTree) macroDef.owner.tpe else prefixTree.tpe, - macroDef.owner) - } else - targ.tpe - context.WeakTypeTag(tpe) - }) - macroLogVerbose(s"tags: $tags") - - // transforms argss taking into account varargness of paramss - // note that typetag context bounds are only declared on macroImpls - // so this optional arglist might not match macroDef's paramlist - // nb! varargs can apply to any parameter section, not necessarily to the last one - mapWithIndex(argss :+ tags)((as, i) => { - val mapsToParamss = macroDef.paramss.indices contains i - if (mapsToParamss) { - val ps = macroDef.paramss(i) - if (isVarArgsList(ps)) { - val (normal, varargs) = as splitAt (ps.length - 1) - normal :+ varargs // pack all varargs into a single List argument - } else as - } else as - }) + targ.tpe + context.WeakTypeTag(tpe) + }) + macroLogVerbose(s"tags: $tags") + + // if present, tags always come in a separate parameter/argument list + // that's because macro impls can't have implicit parameters other than c.WeakTypeTag[T] + (trees :+ tags).flatten + } + + val binding = loadMacroImplBinding(macroDef) + if (binding.is_???) Nil + else calculateMacroArgs(binding) } - macroLogVerbose(s"preparedArgss: $preparedArgss") - MacroArgs(context, preparedArgss.flatten) + macroLogVerbose(s"macroImplArgs: $macroImplArgs") + MacroArgs(context, macroImplArgs) } /** Keeps track of macros in-flight. @@ -680,7 +482,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { * 1) If necessary desugars the `expandee` to fit into `macroExpand1` * * Then `macroExpand1`: - * 2) Checks whether the expansion needs to be delayed (see `mustDelayMacroExpansion`) + * 2) Checks whether the expansion needs to be delayed * 3) Loads macro implementation using `macroMirror` * 4) Synthesizes invocation arguments for the macro implementation * 5) Checks that the result is a tree or an expr bound to this universe @@ -997,3 +799,21 @@ object MacrosStats { val macroExpandCount = Statistics.newCounter ("#macro expansions", "typer") val macroExpandNanos = Statistics.newSubTimer("time spent in macroExpand", typerNanos) } + +class Fingerprint(val value: Int) extends AnyVal { + def paramPos = { assert(isTag, this); value } + def isTag = value >= 0 + def isOther = this == Other + def isExpr = this == Lifted + override def toString = this match { + case Other => "Other" + case Lifted => "Expr" + case _ => s"Tag($value)" + } +} + +object Fingerprint { + def Tagged(tparamPos: Int) = new Fingerprint(tparamPos) + val Other = new Fingerprint(-1) + val Lifted = new Fingerprint(-2) +} diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 03ad127498..8e9933f734 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -282,11 +282,13 @@ trait NamesDefaults { self: Analyzer => case WildcardStarArg(expr) => expr.tpe case _ => seqType(arg.tpe) } - else - // Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter. - gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe) - // We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala. - ).deconst + else { + // TODO In 83c9c764b, we tried to a stable type here to fix SI-7234. But the resulting TypeTree over a + // singleton type without an original TypeTree fails to retypecheck after a resetLocalAttrs (SI-7516), + // which is important for (at least) macros. + arg.tpe + } + ).widen // have to widen or types inferred from literal defaults will be singletons val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo ( if (byName) functionType(Nil, argTpe) else argTpe ) @@ -328,9 +330,12 @@ trait NamesDefaults { self: Analyzer => // type the application without names; put the arguments in definition-site order val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt) typedApp match { - // Extract the typed arguments, restore the call-site evaluation order (using - // ValDef's in the block), change the arguments to these local values. - case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238 + case Apply(expr, typedArgs) if (typedApp :: typedArgs).exists(_.isErrorTyped) => + setError(tree) // bail out with and erroneous Apply *or* erroneous arguments, see SI-7238, SI-7509 + case Apply(expr, typedArgs) => + // Extract the typed arguments, restore the call-site evaluation order (using + // ValDef's in the block), change the arguments to these local values. + // typedArgs: definition-site order val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) // valDefs: call-site order diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 4ccfb31878..c9849eebb5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -126,7 +126,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) defaultMethodNames.toList.distinct foreach { name => - val methods = clazz.info.findMember(name, 0L, METHOD, false).alternatives + val methods = clazz.info.findMember(name, 0L, METHOD, stableOnly = false).alternatives def hasDefaultParam(tpe: Type): Boolean = tpe match { case MethodType(params, restpe) => (params exists (_.hasDefault)) || hasDefaultParam(restpe) case _ => false diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 64fcda3b80..c616ded704 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -10,7 +10,7 @@ trait StdAttachments { * At times we need to store this info, because macro expansion can be delayed until its targs are inferred. * After a macro application has been successfully expanded, this attachment is destroyed. */ - type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context + type UnaffiliatedMacroContext = scala.reflect.macros.contexts.Context type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type } case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext]) @@ -127,4 +127,31 @@ trait StdAttachments { /** Determines whether the given tree has an associated SuperArgsAttachment. */ def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty + + /** @see markMacroImplRef + */ + case object MacroImplRefAttachment + + /** Marks the tree as a macro impl reference, which is a naked reference to a method. + * + * This is necessary for typechecking macro impl references (see `DefaultMacroCompiler.defaultResolveMacroImpl`), + * because otherwise typing a naked reference will result in the "follow this method with `_' if you want to + * treat it as a partially applied function" errors. + * + * This mark suppresses adapt except for when the annottee is a macro application. + */ + def markMacroImplRef(tree: Tree): Tree = tree.updateAttachment(MacroImplRefAttachment) + + /** Unmarks the tree as a macro impl reference (see `markMacroImplRef` for more information). + * + * This is necessary when a tree that was previously deemed to be a macro impl reference, + * typechecks to be a macro application. Then we need to unmark it, expand it and try to treat + * its expansion as a macro impl reference. + */ + def unmarkMacroImplRef(tree: Tree): Tree = tree.removeAttachment[MacroImplRefAttachment.type] + + /** Determines whether a tree should or should not be adapted, + * because someone has put MacroImplRefAttachment on it. + */ + def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined }
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 238727d2e9..ec6b78f2de 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -602,10 +602,8 @@ trait Typers extends Adaptations with Tags { // type of the qualifier is inaccessible, we can cause private types to // escape scope here, e.g. pos/t1107. I'm not sure how to properly handle // this so for now it requires the type symbol be public. - def isGetClassCall = ( - (sym == Any_getClass || sym == Object_getClass) - && pre.typeSymbol.isPublic - ) + def isGetClassCall = isGetClass(sym) && pre.typeSymbol.isPublic + def narrowIf(tree: Tree, condition: Boolean) = if (condition) tree setType singleType(pre, sym) else tree @@ -1234,7 +1232,10 @@ trait Typers extends Adaptations with Tags { } // begin adapt - tree.tpe match { + if (isMacroImplRef(tree)) { + if (treeInfo.isMacroApplication(tree)) adapt(unmarkMacroImplRef(tree), mode, pt, original) + else tree + } else tree.tpe match { case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1) adaptAnnotations(tree, this, mode, pt) case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral => // (0) @@ -5534,7 +5535,7 @@ trait Typers extends Adaptations with Tags { val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous)) && tree1 != EmptyTree val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty - if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, tree1.symbol) else AnyTpe + if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImplRef(ddef, tree1) else AnyTpe } def transformedOr(tree: Tree, op: => Tree): Tree = transformed remove tree match { diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala index 536a281e6c..7f9b81e1ec 100644 --- a/src/compiler/scala/tools/nsc/util/ClassPath.scala +++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala @@ -211,8 +211,6 @@ abstract class ClassPath[T] { def validPackage(name: String) = (name != "META-INF") && (name != "") && (name.charAt(0) != '.') def validSourceFile(name: String) = endsScala(name) || endsJava(name) - def isEmptyOfClassfiles: Boolean = classes.isEmpty && packages.forall(_.isEmptyOfClassfiles) - /** * Find a ClassRep given a class name of the form "package.subpackage.ClassName". * Does not support nested classes on .NET diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 3cf19396ee..5a0ff4f6db 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -5,6 +5,7 @@ import scala.reflect.reify.Taggers import scala.tools.nsc.typechecker.{ Analyzer, Macros } import scala.reflect.runtime.Macros.currentMirror import scala.reflect.api.Universe +import scala.reflect.macros.compiler.DefaultMacroCompiler /** Optimizes system macro expansions by hardwiring them directly to their implementations * bypassing standard reflective load and invoke to avoid the overhead of Java/Scala reflection. diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala index 109c148b7e..8e1bcb5f87 100644 --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala @@ -1,6 +1,6 @@ package scala.tools.reflect -import scala.reflect.macros.runtime.Context +import scala.reflect.macros.contexts.Context import scala.collection.mutable.ListBuffer import scala.collection.mutable.Stack import scala.reflect.internal.util.OffsetPosition diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 6145e61c4f..c53d10bd87 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -165,7 +165,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( (currentTyper, expr) => { trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) - currentTyper.silent(_.typed(expr, pt)) match { + currentTyper.silent(_.typed(expr, pt), reportAmbiguousErrors = false) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) result diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 1b5fd6c8d3..42fb2f36e8 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -162,7 +162,7 @@ case class StringContext(parts: String*) { */ // The implementation is hardwired to `scala.tools.reflect.MacroImplementations.macro_StringInterpolation_f` // Using the mechanism implemented in `scala.tools.reflect.FastTrack` - def f(args: Any*): String = ??? // macro + def f(args: Any*): String = macro ??? } object StringContext { diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index ed04293e0d..479720287c 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -57,19 +57,19 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: def createExecutorService: ExecutorService = { - def getInt(name: String, f: String => Int): Int = - try f(System.getProperty(name)) catch { case e: Exception => Runtime.getRuntime.availableProcessors } - def range(floor: Int, desired: Int, ceiling: Int): Int = - if (ceiling < floor) range(ceiling, desired, floor) else scala.math.min(scala.math.max(desired, floor), ceiling) + def getInt(name: String, default: String) = (try System.getProperty(name, default) catch { + case e: SecurityException => default + }) match { + case s if s.charAt(0) == 'x' => (Runtime.getRuntime.availableProcessors * s.substring(1).toDouble).ceil.toInt + case other => other.toInt + } + + def range(floor: Int, desired: Int, ceiling: Int) = scala.math.min(scala.math.max(floor, desired), ceiling) val desiredParallelism = range( - getInt("scala.concurrent.context.minThreads", _.toInt), - getInt("scala.concurrent.context.numThreads", { - case null | "" => Runtime.getRuntime.availableProcessors - case s if s.charAt(0) == 'x' => (Runtime.getRuntime.availableProcessors * s.substring(1).toDouble).ceil.toInt - case other => other.toInt - }), - getInt("scala.concurrent.context.maxThreads", _.toInt)) + getInt("scala.concurrent.context.minThreads", "1"), + getInt("scala.concurrent.context.numThreads", "x1"), + getInt("scala.concurrent.context.maxThreads", "x1")) val threadFactory = new DefaultThreadFactory(daemonic = true) diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 7af70400ef..ffaea8de96 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -8,11 +8,14 @@ package scala.concurrent.impl -import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException } +import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException, blocking } +import scala.concurrent.Future.InternalCallbackExecutor import scala.concurrent.duration.{ Duration, Deadline, FiniteDuration, NANOSECONDS } import scala.annotation.tailrec import scala.util.control.NonFatal import scala.util.{ Try, Success, Failure } +import java.io.ObjectInputStream +import java.util.concurrent.locks.AbstractQueuedSynchronizer private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] { def future: this.type = this @@ -53,69 +56,68 @@ private[concurrent] object Promise { case t => Failure(t) } + /* + * Inspired by: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/locks/AbstractQueuedSynchronizer.java + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + private final class CompletionLatch[T] extends AbstractQueuedSynchronizer with (Try[T] => Unit) { + override protected def tryAcquireShared(ignored: Int): Int = if (getState != 0) 1 else -1 + override protected def tryReleaseShared(ignore: Int): Boolean = { + setState(1) + true + } + override def apply(ignored: Try[T]): Unit = releaseShared(1) + } + + /** Default promise implementation. */ class DefaultPromise[T] extends AbstractPromise with Promise[T] { self => updateState(null, Nil) // Start at "No callbacks" - protected final def tryAwait(atMost: Duration): Boolean = { - @tailrec - def awaitUnsafe(deadline: Deadline, nextWait: FiniteDuration): Boolean = { - if (!isCompleted && nextWait > Duration.Zero) { - val ms = nextWait.toMillis - val ns = (nextWait.toNanos % 1000000l).toInt // as per object.wait spec - - synchronized { if (!isCompleted) wait(ms, ns) } - - awaitUnsafe(deadline, deadline.timeLeft) - } else - isCompleted - } - @tailrec - def awaitUnbounded(): Boolean = { - if (isCompleted) true - else { - synchronized { if (!isCompleted) wait() } - awaitUnbounded() - } - } - + protected final def tryAwait(atMost: Duration): Boolean = if (!isCompleted) { import Duration.Undefined + import scala.concurrent.Future.InternalCallbackExecutor atMost match { - case u if u eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period") - case Duration.Inf => awaitUnbounded() - case Duration.MinusInf => isCompleted - case f: FiniteDuration => if (f > Duration.Zero) awaitUnsafe(f.fromNow, f) else isCompleted + case e if e eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period") + case Duration.Inf => + val l = new CompletionLatch[T]() + onComplete(l)(InternalCallbackExecutor) + l.acquireSharedInterruptibly(1) + case Duration.MinusInf => // Drop out + case f: FiniteDuration => + if (f > Duration.Zero) { + val l = new CompletionLatch[T]() + onComplete(l)(InternalCallbackExecutor) + l.tryAcquireSharedNanos(1, f.toNanos) + } } - } + + isCompleted + } else true // Already completed @throws(classOf[TimeoutException]) @throws(classOf[InterruptedException]) def ready(atMost: Duration)(implicit permit: CanAwait): this.type = - if (isCompleted || tryAwait(atMost)) this + if (tryAwait(atMost)) this else throw new TimeoutException("Futures timed out after [" + atMost + "]") @throws(classOf[Exception]) def result(atMost: Duration)(implicit permit: CanAwait): T = - ready(atMost).value.get match { - case Failure(e) => throw e - case Success(r) => r - } + ready(atMost).value.get.get // ready throws TimeoutException if timeout so value.get is safe here def value: Option[Try[T]] = getState match { case c: Try[_] => Some(c.asInstanceOf[Try[T]]) case _ => None } - override def isCompleted: Boolean = getState match { // Cheaper than boxing result into Option due to "def value" - case _: Try[_] => true - case _ => false - } + override def isCompleted: Boolean = getState.isInstanceOf[Try[_]] def tryComplete(value: Try[T]): Boolean = { val resolved = resolveTry(value) - (try { - @tailrec + @tailrec def tryComplete(v: Try[T]): List[CallbackRunnable[T]] = { getState match { case raw: List[_] => @@ -124,10 +126,7 @@ private[concurrent] object Promise { case _ => null } } - tryComplete(resolved) - } finally { - synchronized { notifyAll() } //Notify any evil blockers - }) match { + tryComplete(resolved) match { case null => false case rs if rs.isEmpty => true case rs => rs.foreach(r => r.executeWithValue(resolved)); true diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala index fc85bfdc28..af5dad5c38 100644 --- a/src/library/scala/math/package.scala +++ b/src/library/scala/math/package.scala @@ -16,12 +16,12 @@ package object math { /** The `double` value that is closer than any other to `e`, the base of * the natural logarithms. */ - val E = java.lang.Math.E + @inline final val E = java.lang.Math.E /** The `double` value that is closer than any other to `pi`, the ratio of * the circumference of a circle to its diameter. */ - val Pi = java.lang.Math.PI + @inline final val Pi = java.lang.Math.PI /** Returns a `double` value with a positive sign, greater than or equal * to `0.0` and less than `1.0`. diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 97d7da3f2d..74c1f2172c 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -60,7 +60,7 @@ package object reflect { // implementation is hardwired into `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` // todo. once we have implicit macros for tag generation, we can remove this anchor - private[scala] def materializeClassTag[T](): ClassTag[T] = ??? // macro + private[scala] def materializeClassTag[T](): ClassTag[T] = macro ??? @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index ea1f392e2b..3a85207235 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -350,4 +350,17 @@ object ScalaRunTime { } } } + + def box[T](clazz: jClass[T]): jClass[_] = clazz match { + case java.lang.Byte.TYPE => classOf[java.lang.Byte] + case java.lang.Short.TYPE => classOf[java.lang.Short] + case java.lang.Character.TYPE => classOf[java.lang.Character] + case java.lang.Integer.TYPE => classOf[java.lang.Integer] + case java.lang.Long.TYPE => classOf[java.lang.Long] + case java.lang.Float.TYPE => classOf[java.lang.Float] + case java.lang.Double.TYPE => classOf[java.lang.Double] + case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] + case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] + case _ => clazz + } } diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 73469a955d..2240dde360 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -122,8 +122,7 @@ private[scala] trait PropertiesTrait { */ def lineSeparator = propOrElse("line.separator", "\n") - /** Various well-known properties. - */ + /* Various well-known properties. */ def javaClassPath = propOrEmpty("java.class.path") def javaHome = propOrEmpty("java.home") def javaVendor = propOrEmpty("java.vendor") @@ -139,10 +138,13 @@ private[scala] trait PropertiesTrait { def userHome = propOrEmpty("user.home") def userName = propOrEmpty("user.name") - /** Some derived values. - */ + /* Some derived values. */ + /** Returns `true` iff the underlying operating system is a version of Microsoft Windows. */ def isWin = osName startsWith "Windows" - def isMac = javaVendor startsWith "Apple" + // See http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-November/005148.html for + // the reason why we don't follow developer.apple.com/library/mac/#technotes/tn2002/tn2110. + /** Returns `true` iff the underlying operating system is a version of Apple Mac OSX. */ + def isMac = osName startsWith "Mac OS X" // This is looking for javac, tools.jar, etc. // Tries JDK_HOME first, then the more common but likely jre JAVA_HOME, diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index f4ada814af..f7a6a68946 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -296,6 +296,20 @@ trait Trees { self: Universe => def name: Name } + /** The constructor/extractor for `RefTree` instances. + * @group Extractors + */ + val RefTree: RefTreeExtractor + + /** An extractor class to create and pattern match with syntax `RefTree(qual, name)`. + * This AST node corresponds to either Ident, Select or SelectFromTypeTree. + * @group Extractors + */ + abstract class RefTreeExtractor { + def apply(qualifier: Tree, name: Name): RefTree + def unapply(refTree: RefTree): Option[(Tree, Name)] + } + /** A tree which defines a symbol-carrying entity. * @group Trees * @template diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index 799fbd0dfb..cb629f9c5a 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -94,5 +94,5 @@ abstract class Universe extends Symbols */ // implementation is hardwired to `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` - def reify[T](expr: T): Expr[T] = ??? // macro + def reify[T](expr: T): Expr[T] = macro ??? } diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala index 14dcc9247f..a8f409e123 100644 --- a/src/reflect/scala/reflect/api/package.scala +++ b/src/reflect/scala/reflect/api/package.scala @@ -43,6 +43,6 @@ package object api { // implementation is hardwired into `scala.reflect.reify.Taggers` // using the mechanism implemented in `scala.tools.reflect.FastTrack` // todo. once we have implicit macros for tag generation, we can remove these anchors - private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = ??? // macro - private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = ??? // macro + private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = macro ??? + private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = macro ??? }
\ No newline at end of file diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 5cd86b7eed..851fc98a32 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -111,8 +111,10 @@ trait Definitions extends api.StandardDefinitions { /** Is symbol a numeric value class? */ def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym - def isGetClass(sym: Symbol) = - (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) + def isGetClass(sym: Symbol) = ( + sym.name == nme.getClass_ // this condition is for performance only, this is called from `Typer#stabliize`. + && getClassMethods(sym) + ) lazy val UnitClass = valueClassSymbol(tpnme.Unit) lazy val ByteClass = valueClassSymbol(tpnme.Byte) @@ -491,8 +493,8 @@ trait Definitions extends api.StandardDefinitions { lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type] lazy val ReflectApiPackage = getPackageObjectIfDefined("scala.reflect.api") // defined in scala-reflect.jar, so we need to be careful lazy val ReflectRuntimePackage = getPackageObjectIfDefined("scala.reflect.runtime") // defined in scala-reflect.jar, so we need to be careful - def ReflectRuntimeUniverse = if (ReflectRuntimePackage != NoSymbol) getMemberValue(ReflectRuntimePackage, nme.universe) else NoSymbol - def ReflectRuntimeCurrentMirror = if (ReflectRuntimePackage != NoSymbol) getMemberMethod(ReflectRuntimePackage, nme.currentMirror) else NoSymbol + def ReflectRuntimeUniverse = ReflectRuntimePackage.map(sym => getMemberValue(sym, nme.universe)) + def ReflectRuntimeCurrentMirror = ReflectRuntimePackage.map(sym => getMemberMethod(sym, nme.currentMirror)) lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest) lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifestFactory.type] @@ -501,24 +503,38 @@ trait Definitions extends api.StandardDefinitions { lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]] lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] + lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful + lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) + object TreeType { + def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol) + def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType + } + lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful - lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol - def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol - def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol + lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) + def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice)) + def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value)) + object ExprClassOf { + def unapply(tpe: Type): Option[Type] = tpe.dealias match { + case ExistentialType(_, underlying) => unapply(underlying) + case TypeRef(_, ExprClass, t :: Nil) => Some(t) + case _ => None + } + } lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] lazy val TypeTagsClass = getClassIfDefined("scala.reflect.api.TypeTags") // defined in scala-reflect.jar, so we need to be careful - lazy val WeakTypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.WeakTypeTag) else NoSymbol - lazy val WeakTypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.WeakTypeTag) else NoSymbol - lazy val TypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.TypeTag) else NoSymbol - lazy val TypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.TypeTag) else NoSymbol + lazy val WeakTypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag)) + lazy val WeakTypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag)) + lazy val TypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag)) + lazy val TypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.TypeTag)) def materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag) - def materializeWeakTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeWeakTypeTag) else NoSymbol - def materializeTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeTypeTag) else NoSymbol + def materializeWeakTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag)) + def materializeTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag)) lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful - def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol + def ApiUniverseReify = ApiUniverseClass.map(sym => getMemberMethod(sym, nme.reify)) lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful @@ -526,14 +542,18 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful - lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful - def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol - def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.PrefixType) else NoSymbol - def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol - lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] + lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful + lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful + def MacroContextPrefix = MacroContextClass.map(sym => getMemberMethod(sym, nme.prefix)) + def MacroContextPrefixType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType)) + def MacroContextUniverse = MacroContextClass.map(sym => getMemberMethod(sym, nme.universe)) + def MacroContextExprClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Expr)) + def MacroContextWeakTypeTagClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.WeakTypeTag)) + def MacroContextTreeType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Tree)) + lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] - lazy val StringContextClass = requiredClass[scala.StringContext] - def StringContext_f = getMemberMethod(StringContextClass, nme.f) + lazy val StringContextClass = requiredClass[scala.StringContext] + def StringContext_f = getMemberMethod(StringContextClass, nme.f) lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature] lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature] @@ -640,6 +660,12 @@ trait Definitions extends api.StandardDefinitions { } def isTupleType(tp: Type) = isTupleTypeDirect(tp.dealiasWiden) + def isMacroBundleType(tp: Type) = { + val isNonTrivial = tp != ErrorType && tp != NothingTpe && tp != NullTpe + val isMacroCompatible = MacroClass != NoSymbol && tp <:< MacroClass.tpe + isNonTrivial && isMacroCompatible + } + lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product] def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity) def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement) @@ -753,6 +779,12 @@ trait Definitions extends api.StandardDefinitions { lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => BooleanTpe) lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) + lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( + ScalaValueClasses map (_.tpe member nme.getClass_) + ) + + lazy val getClassMethods: Set[Symbol] = primitiveGetClassMethods + Object_getClass + // A type function from T => Class[U], used to determine the return // type of getClass calls. The returned type is: // diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index b0d3cda629..f8584ac9b0 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -6,17 +6,17 @@ import scala.collection.mutable.WeakHashMap import scala.ref.WeakReference // SI-6241: move importers to a mirror -trait Importers extends api.Importers { self: SymbolTable => +trait Importers extends api.Importers { to: SymbolTable => def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( - if (self eq from0) { + if (to eq from0) { new Importer { val from = from0 - val reverse = this.asInstanceOf[from.Importer{ val from: self.type }] - def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] - def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] - def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] - def importPosition(pos: from.Position) = pos.asInstanceOf[self.Position] + val reverse = this.asInstanceOf[from.Importer{ val from: to.type }] + def importSymbol(their: from.Symbol) = their.asInstanceOf[to.Symbol] + def importType(their: from.Type) = their.asInstanceOf[to.Type] + def importTree(their: from.Tree) = their.asInstanceOf[to.Tree] + def importPosition(their: from.Position) = their.asInstanceOf[to.Position] } } else { // todo. fix this loophole @@ -29,8 +29,8 @@ trait Importers extends api.Importers { self: SymbolTable => val from: SymbolTable - protected lazy val symMap = new Cache[from.Symbol, Symbol]() - protected lazy val tpeMap = new Cache[from.Type, Type]() + protected lazy val symMap = new Cache[from.Symbol, to.Symbol]() + protected lazy val tpeMap = new Cache[from.Type, to.Type]() protected class Cache[K <: AnyRef, V <: AnyRef] extends WeakHashMap[K, WeakReference[V]] { def weakGet(key: K): Option[V] = this get key flatMap WeakReference.unapply def weakUpdate(key: K, value: V) = this.update(key, WeakReference(value)) @@ -50,158 +50,162 @@ trait Importers extends api.Importers { self: SymbolTable => } object reverse extends from.StandardImporter { - val from: self.type = self + val from: to.type = to // FIXME this and reverse should be constantly kept in sync // not just synced once upon the first usage of reverse - for ((fromsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(fromsym))) - for ((fromtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(fromtpe))) + for ((theirsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(theirsym))) + for ((theirtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(theirtpe))) } - // todo. careful import of positions - def importPosition(pos: from.Position): Position = - pos.asInstanceOf[Position] + // ============== SYMBOLS ============== + + protected def recreatedSymbolCompleter(my: to.Symbol, their: from.Symbol) = { + // we lock the symbol that is imported for a very short period of time + // i.e. only for when type parameters of the symbol are being imported + // the lock is used to communicate to the recursive importSymbol calls + // that type parameters need to be created from scratch + // because otherwise type parameters are imported by looking into owner.typeParams + // which is obviously unavailable while the completer is being created + try { + my setFlag Flags.LOCKED + val mytypeParams = their.typeParams map importSymbol + new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { + override def complete(my: to.Symbol): Unit = { + val theirCore = their.info match { + case from.PolyType(_, core) => core + case core => core + } + my setInfo GenPolyType(mytypeParams, importType(theirCore)) + my setAnnotations (their.annotations map importAnnotationInfo) + } + } + } finally { + my resetFlag Flags.LOCKED + } + } + + protected def recreateSymbol(their: from.Symbol): to.Symbol = { + val myowner = importSymbol(their.owner) + val mypos = importPosition(their.pos) + val myname = importName(their.name) + val myflags = their.flags + def linkReferenced(my: TermSymbol, their: from.TermSymbol, op: from.Symbol => Symbol): Symbol = { + symMap.weakUpdate(their, my) + my.referenced = op(their.referenced) + my + } + val my = their match { + case their: from.MethodSymbol => + linkReferenced(myowner.newMethod(myname.toTermName, mypos, myflags), their, importSymbol) + case their: from.ModuleSymbol => + val ret = linkReferenced(myowner.newModuleSymbol(myname.toTermName, mypos, myflags), their, importSymbol) + ret.associatedFile = their.associatedFile + ret + case their: from.FreeTermSymbol => + newFreeTermSymbol(myname.toTermName, their.value, their.flags, their.origin) setInfo importType(their.info) + case their: from.FreeTypeSymbol => + newFreeTypeSymbol(myname.toTypeName, their.flags, their.origin) + case their: from.TermSymbol => + linkReferenced(myowner.newValue(myname.toTermName, mypos, myflags), their, importSymbol) + case their: from.TypeSkolem => + val origin = their.unpackLocation match { + case null => null + case theirloc: from.Tree => importTree(theirloc) + case theirloc: from.Symbol => importSymbol(theirloc) + } + myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) + case their: from.ModuleClassSymbol => + val my = myowner.newModuleClass(myname.toTypeName, mypos, myflags) + symMap.weakUpdate(their, my) + my.sourceModule = importSymbol(their.sourceModule) + my + case their: from.ClassSymbol => + val my = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) + symMap.weakUpdate(their, my) + if (their.thisSym != their) { + my.typeOfThis = importType(their.typeOfThis) + my.thisSym setName importName(their.thisSym.name) + } + my.associatedFile = their.associatedFile + my + case their: from.TypeSymbol => + myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) + } + symMap.weakUpdate(their, my) + my setInfo recreatedSymbolCompleter(my, their) + } - def importSymbol(sym0: from.Symbol): Symbol = { - def doImport(sym: from.Symbol): Symbol = - symMap weakGet sym match { + def importSymbol(their0: from.Symbol): Symbol = { + def cachedRecreateSymbol(their: from.Symbol): Symbol = + symMap weakGet their match { case Some(result) => result - case _ => - val myowner = importSymbol(sym.owner) - val mypos = importPosition(sym.pos) - val myname = importName(sym.name).toTermName - val myflags = sym.flags - def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = { - symMap.weakUpdate(x, mysym) - mysym.referenced = op(x.referenced) - mysym - } - val mysym = sym match { - case x: from.MethodSymbol => - linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) - case x: from.ModuleSymbol => - linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) - case x: from.FreeTermSymbol => - newFreeTermSymbol(importName(x.name).toTermName, x.value, x.flags, x.origin) setInfo importType(x.info) - case x: from.FreeTypeSymbol => - newFreeTypeSymbol(importName(x.name).toTypeName, x.flags, x.origin) - case x: from.TermSymbol => - linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol) - case x: from.TypeSkolem => - val origin = x.unpackLocation match { - case null => null - case y: from.Tree => importTree(y) - case y: from.Symbol => importSymbol(y) - } - myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) - case x: from.ModuleClassSymbol => - val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags) - symMap.weakUpdate(x, mysym) - mysym.sourceModule = importSymbol(x.sourceModule) - mysym - case x: from.ClassSymbol => - val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) - symMap.weakUpdate(x, mysym) - if (sym.thisSym != sym) { - mysym.typeOfThis = importType(sym.typeOfThis) - mysym.thisSym setName importName(sym.thisSym.name) - } - mysym - case x: from.TypeSymbol => - myowner.newTypeSymbol(myname.toTypeName, mypos, myflags) - } - symMap.weakUpdate(sym, mysym) - mysym setFlag Flags.LOCKED - mysym setInfo { - val mytypeParams = sym.typeParams map importSymbol - new LazyPolyType(mytypeParams) with FlagAgnosticCompleter { - override def complete(s: Symbol) { - val result = sym.info match { - case from.PolyType(_, res) => res - case result => result - } - s setInfo GenPolyType(mytypeParams, importType(result)) - s setAnnotations (sym.annotations map importAnnotationInfo) - } - } - } - mysym resetFlag Flags.LOCKED - } // end doImport + case _ => recreateSymbol(their) + } - def importOrRelink: Symbol = { - val sym = sym0 // makes sym visible in the debugger - if (sym == null) + def recreateOrRelink: Symbol = { + val their = their0 // makes their visible in the debugger + if (their == null) null - else if (sym == from.NoSymbol) + else if (their == from.NoSymbol) NoSymbol - else if (sym.isRoot) + else if (their.isRoot) rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror else { - val name = sym.name - val owner = sym.owner - var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType - var existing = scope.decl(name) - if (sym.isModuleClass) - existing = existing.moduleClass - - if (!existing.exists) scope = from.NoType - - val myname = importName(name) - val myowner = importSymbol(owner) - val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType - var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods - if (sym.isModuleClass) - myexisting = importSymbol(sym.sourceModule).moduleClass - - if (!sym.isOverloaded && myexisting.isOverloaded) { - myexisting = - if (sym.isMethod) { - val localCopy = doImport(sym) - myexisting filter (_.tpe matches localCopy.tpe) - } else { - myexisting filter (!_.isMethod) + val isModuleClass = their.isModuleClass + val isTparam = their.isTypeParameter && their.paramPos >= 0 + val isOverloaded = their.isOverloaded + + var theirscope = if (their.owner.isClass && !their.owner.isRefinementClass) their.owner.info else from.NoType + val theirexisting = if (isModuleClass) theirscope.decl(their.name).moduleClass else theirscope.decl(their.name) + if (!theirexisting.exists) theirscope = from.NoType + + val myname = importName(their.name) + val myowner = importSymbol(their.owner) + val myscope = if (theirscope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType + val myexisting = { + if (isModuleClass) importSymbol(their.sourceModule).moduleClass + else if (isTparam) (if (myowner hasFlag Flags.LOCKED) NoSymbol else myowner.typeParams(their.paramPos)) + else if (isOverloaded) myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol) + else { + def disambiguate(my: Symbol) = { + val result = + if (their.isMethod) { + val localCopy = cachedRecreateSymbol(their) + my filter (_.tpe matches localCopy.tpe) + } else { + my filter (!_.isMethod) + } + assert(!result.isOverloaded, + "import failure: cannot determine unique overloaded method alternative from\n "+ + (result.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe) + result } - assert(!myexisting.isOverloaded, - "import failure: cannot determine unique overloaded method alternative from\n "+ - (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe) - } - val mysym = { - if (sym.isOverloaded) { - myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol) - } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { - assert(myowner.typeParams.length > sym.paramPos, - "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+ - myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ - sym.owner+from.typeParamsString(sym.owner.info)) - myowner.typeParams(sym.paramPos) - } else { - if (myexisting != NoSymbol) { - myexisting - } else { - val mysym = doImport(sym) - - if (myscope != NoType) { - assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+myexisting) - myowner.info.decls enter mysym - } - - mysym - } + val myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol + if (myexisting.isOverloaded) disambiguate(myexisting) + else myexisting } } - mysym + myexisting.orElse { + val my = cachedRecreateSymbol(their) + if (myscope != NoType) { + assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting) + myscope.decls enter my + } + my + } } - } // end importOrRelink + } // end recreateOrRelink - val sym = sym0 - symMap.weakGet(sym) match { + val their = their0 + symMap.weakGet(their) match { case Some(result) => result case None => pendingSyms += 1 try { - val result = importOrRelink - symMap.weakUpdate(sym, result) + val result = recreateOrRelink + symMap.weakUpdate(their, result) result } finally { pendingSyms -= 1 @@ -210,69 +214,70 @@ trait Importers extends api.Importers { self: SymbolTable => } } - def importType(tpe: from.Type): Type = { - def doImport(tpe: from.Type): Type = tpe match { - case from.TypeRef(pre, sym, args) => - TypeRef(importType(pre), importSymbol(sym), args map importType) - case from.ThisType(clazz) => - ThisType(importSymbol(clazz)) - case from.SingleType(pre, sym) => - SingleType(importType(pre), importSymbol(sym)) - case from.MethodType(params, restpe) => - MethodType(params map importSymbol, importType(restpe)) - case from.PolyType(tparams, restpe) => - PolyType(tparams map importSymbol, importType(restpe)) - case from.NullaryMethodType(restpe) => - NullaryMethodType(importType(restpe)) - case from.ConstantType(constant @ from.Constant(_)) => - ConstantType(importConstant(constant)) - case from.SuperType(thistpe, supertpe) => - SuperType(importType(thistpe), importType(supertpe)) - case from.TypeBounds(lo, hi) => - TypeBounds(importType(lo), importType(hi)) - case from.BoundedWildcardType(bounds) => - BoundedWildcardType(importTypeBounds(bounds)) - case from.ClassInfoType(parents, decls, clazz) => - val myclazz = importSymbol(clazz) - val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope - val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) - myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope - decls foreach importSymbol // will enter itself into myclazz - myclazzTpe - case from.RefinedType(parents, decls) => - RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol)) - case from.ExistentialType(tparams, restpe) => - newExistentialType(tparams map importSymbol, importType(restpe)) - case from.OverloadedType(pre, alts) => - OverloadedType(importType(pre), alts map importSymbol) - case from.AntiPolyType(pre, targs) => - AntiPolyType(importType(pre), targs map importType) - case x: from.TypeVar => - TypeVar(importType(x.origin), importTypeConstraint(x.constr), x.typeArgs map importType, x.params map importSymbol) - case from.AnnotatedType(annots, tpe, selfsym) => - AnnotatedType(annots map importAnnotationInfo, importType(tpe), importSymbol(selfsym)) - case from.ErrorType => - ErrorType - case from.WildcardType => - WildcardType - case from.NoType => - NoType - case from.NoPrefix => - NoPrefix - case null => - null - } // end doImport - - def importOrRelink: Type = - doImport(tpe) + // ============== TYPES ============== + + def recreateType(their: from.Type): Type = their match { + case from.TypeRef(pre, sym, args) => + TypeRef(importType(pre), importSymbol(sym), args map importType) + case from.ThisType(clazz) => + ThisType(importSymbol(clazz)) + case from.SingleType(pre, sym) => + SingleType(importType(pre), importSymbol(sym)) + case from.MethodType(params, result) => + MethodType(params map importSymbol, importType(result)) + case from.PolyType(tparams, result) => + PolyType(tparams map importSymbol, importType(result)) + case from.NullaryMethodType(result) => + NullaryMethodType(importType(result)) + case from.ConstantType(constant @ from.Constant(_)) => + ConstantType(importConstant(constant)) + case from.SuperType(thistpe, supertpe) => + SuperType(importType(thistpe), importType(supertpe)) + case from.TypeBounds(lo, hi) => + TypeBounds(importType(lo), importType(hi)) + case from.BoundedWildcardType(bounds) => + BoundedWildcardType(importType(bounds).asInstanceOf[TypeBounds]) + case from.ClassInfoType(parents, decls, clazz) => + val myclazz = importSymbol(clazz) + val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope + val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) + myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope + decls foreach importSymbol // will enter itself into myclazz + myclazzTpe + case from.RefinedType(parents, decls) => + RefinedType(parents map importType, importScope(decls), importSymbol(their.typeSymbol)) + case from.ExistentialType(tparams, result) => + newExistentialType(tparams map importSymbol, importType(result)) + case from.OverloadedType(pre, alts) => + OverloadedType(importType(pre), alts map importSymbol) + case from.AntiPolyType(pre, targs) => + AntiPolyType(importType(pre), targs map importType) + case their: from.TypeVar => + val myconstr = new TypeConstraint(their.constr.loBounds map importType, their.constr.hiBounds map importType) + myconstr.inst = importType(their.constr.inst) + TypeVar(importType(their.origin), myconstr, their.typeArgs map importType, their.params map importSymbol) + case from.AnnotatedType(annots, result, selfsym) => + AnnotatedType(annots map importAnnotationInfo, importType(result), importSymbol(selfsym)) + case from.ErrorType => + ErrorType + case from.WildcardType => + WildcardType + case from.NoType => + NoType + case from.NoPrefix => + NoPrefix + case null => + null + } - tpeMap.weakGet(tpe) match { + def importType(their: from.Type): Type = { + tpeMap.weakGet(their) match { case Some(result) => result case None => pendingTpes += 1 try { - val result = importOrRelink - tpeMap.weakUpdate(tpe, result) + val result = recreateType(their) + tpeMap.weakUpdate(their, result) result } finally { pendingTpes -= 1 @@ -281,7 +286,136 @@ trait Importers extends api.Importers { self: SymbolTable => } } - def importTypeBounds(bounds: from.TypeBounds) = importType(bounds).asInstanceOf[TypeBounds] + // ============== TREES ============== + + def recreatedTreeCompleter(their: from.Tree, my: to.Tree): Unit = { + if (their.canHaveAttrs) { + if (my.hasSymbolField) my.symbol = importSymbol(their.symbol) + my.pos = importPosition(their.pos) + (their, my) match { + case (their: from.TypeTree, my: to.TypeTree) => + if (their.wasEmpty) my.defineType(importType(their.tpe)) else my.setType(importType(their.tpe)) + case (_, _) => + my.tpe = importType(their.tpe) + } + } + } + + def recreateTree(their: from.Tree): to.Tree = their match { + case from.ClassDef(mods, name, tparams, impl) => + new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) + case from.PackageDef(pid, stats) => + new PackageDef(importRefTree(pid), stats map importTree) + case from.ModuleDef(mods, name, impl) => + new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) + case from.emptyValDef => + emptyValDef + case from.pendingSuperCall => + pendingSuperCall + case from.ValDef(mods, name, tpt, rhs) => + new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) + case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => + new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) + case from.TypeDef(mods, name, tparams, rhs) => + new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) + case from.LabelDef(name, params, rhs) => + new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs)) + case from.Import(expr, selectors) => + new Import(importTree(expr), selectors map importImportSelector) + case from.Template(parents, self, body) => + new Template(parents map importTree, importValDef(self), body map importTree) + case from.Block(stats, expr) => + new Block(stats map importTree, importTree(expr)) + case from.CaseDef(pat, guard, body) => + new CaseDef(importTree(pat), importTree(guard), importTree(body)) + case from.Alternative(trees) => + new Alternative(trees map importTree) + case from.Star(elem) => + new Star(importTree(elem)) + case from.Bind(name, body) => + new Bind(importName(name), importTree(body)) + case from.UnApply(fun, args) => + new UnApply(importTree(fun), args map importTree) + case from.ArrayValue(elemtpt ,elems) => + new ArrayValue(importTree(elemtpt), elems map importTree) + case from.Function(vparams, body) => + new Function(vparams map importValDef, importTree(body)) + case from.Assign(lhs, rhs) => + new Assign(importTree(lhs), importTree(rhs)) + case from.AssignOrNamedArg(lhs, rhs) => + new AssignOrNamedArg(importTree(lhs), importTree(rhs)) + case from.If(cond, thenp, elsep) => + new If(importTree(cond), importTree(thenp), importTree(elsep)) + case from.Match(selector, cases) => + new Match(importTree(selector), cases map importCaseDef) + case from.Return(expr) => + new Return(importTree(expr)) + case from.Try(block, catches, finalizer) => + new Try(importTree(block), catches map importCaseDef, importTree(finalizer)) + case from.Throw(expr) => + new Throw(importTree(expr)) + case from.New(tpt) => + new New(importTree(tpt)) + case from.Typed(expr, tpt) => + new Typed(importTree(expr), importTree(tpt)) + case from.TypeApply(fun, args) => + new TypeApply(importTree(fun), args map importTree) + case from.Apply(fun, args) => their match { + case _: from.ApplyToImplicitArgs => + new ApplyToImplicitArgs(importTree(fun), args map importTree) + case _: from.ApplyImplicitView => + new ApplyImplicitView(importTree(fun), args map importTree) + case _ => + new Apply(importTree(fun), args map importTree) + } + case from.ApplyDynamic(qual, args) => + new ApplyDynamic(importTree(qual), args map importTree) + case from.Super(qual, mix) => + new Super(importTree(qual), importName(mix).toTypeName) + case from.This(qual) => + new This(importName(qual).toTypeName) + case from.Select(qual, name) => + new Select(importTree(qual), importName(name)) + case from.Ident(name) => + new Ident(importName(name)) + case from.ReferenceToBoxed(ident) => + new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) + case from.Literal(constant @ from.Constant(_)) => + new Literal(importConstant(constant)) + case theirtt @ from.TypeTree() => + val mytt = TypeTree() + if (theirtt.original != null) mytt.setOriginal(importTree(theirtt.original)) + mytt + case from.Annotated(annot, arg) => + new Annotated(importTree(annot), importTree(arg)) + case from.SingletonTypeTree(ref) => + new SingletonTypeTree(importTree(ref)) + case from.SelectFromTypeTree(qual, name) => + new SelectFromTypeTree(importTree(qual), importName(name).toTypeName) + case from.CompoundTypeTree(templ) => + new CompoundTypeTree(importTemplate(templ)) + case from.AppliedTypeTree(tpt, args) => + new AppliedTypeTree(importTree(tpt), args map importTree) + case from.TypeBoundsTree(lo, hi) => + new TypeBoundsTree(importTree(lo), importTree(hi)) + case from.ExistentialTypeTree(tpt, whereClauses) => + new ExistentialTypeTree(importTree(tpt), whereClauses map importTree) + case from.EmptyTree => + EmptyTree + case null => + null + } + + def importTree(their: from.Tree): Tree = { + val my = recreateTree(their) + if (my != null) { + addFixup(recreatedTreeCompleter(their, my)) + tryFixup() + } + my + } + + // ============== MISCELLANEOUS ============== def importAnnotationInfo(ann: from.AnnotationInfo): AnnotationInfo = { val atp1 = importType(ann.atp) @@ -302,11 +436,9 @@ trait Importers extends api.Importers { self: SymbolTable => NestedAnnotArg(importAnnotationInfo(annInfo)) } - def importTypeConstraint(constr: from.TypeConstraint): TypeConstraint = { - val result = new TypeConstraint(constr.loBounds map importType, constr.hiBounds map importType) - result.inst = importType(constr.inst) - result - } + // todo. careful import of positions + def importPosition(their: from.Position): to.Position = + their.asInstanceOf[Position] // !!! todo: override to cater for PackageScopes def importScope(decls: from.Scope): Scope = @@ -314,138 +446,12 @@ trait Importers extends api.Importers { self: SymbolTable => def importName(name: from.Name): Name = if (name.isTypeName) newTypeName(name.toString) else newTermName(name.toString) - def importTypeName(name: from.TypeName): TypeName = importName(name).toTypeName def importModifiers(mods: from.Modifiers): Modifiers = new Modifiers(mods.flags, importName(mods.privateWithin), mods.annotations map importTree) def importImportSelector(sel: from.ImportSelector): ImportSelector = new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos) - - def importTree(tree: from.Tree): Tree = { - val mytree = tree match { - case from.ClassDef(mods, name, tparams, impl) => - new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) - case from.PackageDef(pid, stats) => - new PackageDef(importRefTree(pid), stats map importTree) - case from.ModuleDef(mods, name, impl) => - new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) - case from.emptyValDef => - emptyValDef - case from.pendingSuperCall => - pendingSuperCall - case from.ValDef(mods, name, tpt, rhs) => - new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) - case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => - new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs)) - case from.TypeDef(mods, name, tparams, rhs) => - new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs)) - case from.LabelDef(name, params, rhs) => - new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs)) - case from.Import(expr, selectors) => - new Import(importTree(expr), selectors map importImportSelector) - case from.Template(parents, self, body) => - new Template(parents map importTree, importValDef(self), body map importTree) - case from.Block(stats, expr) => - new Block(stats map importTree, importTree(expr)) - case from.CaseDef(pat, guard, body) => - new CaseDef(importTree(pat), importTree(guard), importTree(body)) - case from.Alternative(trees) => - new Alternative(trees map importTree) - case from.Star(elem) => - new Star(importTree(elem)) - case from.Bind(name, body) => - new Bind(importName(name), importTree(body)) - case from.UnApply(fun, args) => - new UnApply(importTree(fun), args map importTree) - case from.ArrayValue(elemtpt ,elems) => - new ArrayValue(importTree(elemtpt), elems map importTree) - case from.Function(vparams, body) => - new Function(vparams map importValDef, importTree(body)) - case from.Assign(lhs, rhs) => - new Assign(importTree(lhs), importTree(rhs)) - case from.AssignOrNamedArg(lhs, rhs) => - new AssignOrNamedArg(importTree(lhs), importTree(rhs)) - case from.If(cond, thenp, elsep) => - new If(importTree(cond), importTree(thenp), importTree(elsep)) - case from.Match(selector, cases) => - new Match(importTree(selector), cases map importCaseDef) - case from.Return(expr) => - new Return(importTree(expr)) - case from.Try(block, catches, finalizer) => - new Try(importTree(block), catches map importCaseDef, importTree(finalizer)) - case from.Throw(expr) => - new Throw(importTree(expr)) - case from.New(tpt) => - new New(importTree(tpt)) - case from.Typed(expr, tpt) => - new Typed(importTree(expr), importTree(tpt)) - case from.TypeApply(fun, args) => - new TypeApply(importTree(fun), args map importTree) - case from.Apply(fun, args) => tree match { - case _: from.ApplyToImplicitArgs => - new ApplyToImplicitArgs(importTree(fun), args map importTree) - case _: from.ApplyImplicitView => - new ApplyImplicitView(importTree(fun), args map importTree) - case _ => - new Apply(importTree(fun), args map importTree) - } - case from.ApplyDynamic(qual, args) => - new ApplyDynamic(importTree(qual), args map importTree) - case from.Super(qual, mix) => - new Super(importTree(qual), importTypeName(mix)) - case from.This(qual) => - new This(importName(qual).toTypeName) - case from.Select(qual, name) => - new Select(importTree(qual), importName(name)) - case from.Ident(name) => - new Ident(importName(name)) - case from.ReferenceToBoxed(ident) => - new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident }) - case from.Literal(constant @ from.Constant(_)) => - new Literal(importConstant(constant)) - case from.TypeTree() => - new TypeTree() - case from.Annotated(annot, arg) => - new Annotated(importTree(annot), importTree(arg)) - case from.SingletonTypeTree(ref) => - new SingletonTypeTree(importTree(ref)) - case from.SelectFromTypeTree(qual, name) => - new SelectFromTypeTree(importTree(qual), importName(name).toTypeName) - case from.CompoundTypeTree(templ) => - new CompoundTypeTree(importTemplate(templ)) - case from.AppliedTypeTree(tpt, args) => - new AppliedTypeTree(importTree(tpt), args map importTree) - case from.TypeBoundsTree(lo, hi) => - new TypeBoundsTree(importTree(lo), importTree(hi)) - case from.ExistentialTypeTree(tpt, whereClauses) => - new ExistentialTypeTree(importTree(tpt), whereClauses map importTree) - case from.EmptyTree => - EmptyTree - case null => - null - } - addFixup({ - if (mytree != null) { - val mysym = if (tree.hasSymbolField) importSymbol(tree.symbol) else NoSymbol - val mytpe = importType(tree.tpe) - - mytree match { - case mytt: TypeTree => - val tt = tree.asInstanceOf[from.TypeTree] - if (mytree.hasSymbolField) mytt.symbol = mysym - if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe) - if (tt.original != null) mytt.setOriginal(importTree(tt.original)) - case _ => - if (mytree.hasSymbolField) mytree.symbol = importSymbol(tree.symbol) - mytree setType importType(tree.tpe) - } - } - }) - tryFixup() - mytree - } - def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef] def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef] def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template] diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index a20307882d..81fffc833c 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -8,6 +8,7 @@ package reflect package internal import java.security.MessageDigest +import java.util.UUID.randomUUID import Chars.isOperatorPart import scala.annotation.switch import scala.language.implicitConversions @@ -290,6 +291,9 @@ trait StdNames { val FAKE_LOCAL_THIS: NameType = "this$" val LAZY_LOCAL: NameType = "$lzy" val LAZY_SLOW_SUFFIX: NameType = "$lzycompute" + val MACRO_INVOKER_PACKAGE: NameType = "scala.reflect.macros.synthetic" + // TODO: if I use dollars in MACRO_INVOKER_SUFFIX, as in "$Invoker$", then Scala reflection fails to load implementations + val MACRO_INVOKER_SUFFIX: NameType = "Invoker" val UNIVERSE_BUILD_PREFIX: NameType = "$u.build." val UNIVERSE_PREFIX: NameType = "$u." val UNIVERSE_SHORT: NameType = "$u" @@ -584,6 +588,7 @@ trait StdNames { val box: NameType = "box" val build : NameType = "build" val bytes: NameType = "bytes" + val c: NameType = "c" val canEqual_ : NameType = "canEqual" val checkInitialized: NameType = "checkInitialized" val classOf: NameType = "classOf" diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index e9ef9c7945..d1e8a04553 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -836,8 +836,17 @@ abstract class TreeInfo { } def unapply(tree: Tree) = refPart(tree) match { - case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, dissectApplied(tree).targs)) - case _ => None + case ref: RefTree => { + val isBundle = definitions.isMacroBundleType(ref.qualifier.tpe) + val owner = + if (isBundle) ref.qualifier.tpe.typeSymbol + else { + val sym = ref.qualifier.symbol + if (sym.isModule) sym.moduleClass else sym + } + Some((isBundle, owner, ref.symbol, dissectApplied(tree).targs)) + } + case _ => None } } diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 833adb99c7..8781423a6d 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -253,6 +253,19 @@ trait Trees extends api.Trees { self: SymbolTable => def name: Name } + object RefTree extends RefTreeExtractor { + def apply(qualifier: Tree, name: Name): RefTree = qualifier match { + case EmptyTree => + Ident(name) + case qual if qual.isTerm => + Select(qual, name) + case qual if qual.isType => + assert(name.isTypeName, s"qual = $qual, name = $name") + SelectFromTypeTree(qual, name.toTypeName) + } + def unapply(refTree: RefTree): Option[(Tree, Name)] = Some((refTree.qualifier, refTree.name)) + } + abstract class DefTree extends SymTree with NameTree with DefTreeApi { def name: Name override def isDef = true diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index a435292185..0a50eb8ecc 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1066,6 +1066,14 @@ trait Types continue = false val bcs0 = baseClasses var bcs = bcs0 + // omit PRIVATE LOCALS unless selector class is contained in class owning the def. + def admitPrivateLocal(owner: Symbol): Boolean = { + val selectorClass = this match { + case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class. + case _ => bcs0.head + } + selectorClass.hasTransOwner(owner) + } while (!bcs.isEmpty) { val decls = bcs.head.info.decls var entry = decls.lookupEntry(name) @@ -1075,10 +1083,10 @@ trait Types if ((flags & required) == required) { val excl = flags & excluded if (excl == 0L && - (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + ( (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || - (bcs0.head.hasTransOwner(bcs.head)))) { + admitPrivateLocal(bcs.head))) { if (name.isTypeName || (stableOnly && sym.isStable && !sym.hasVolatileType)) { if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start) return sym @@ -3118,10 +3126,9 @@ trait Types sameLength(typeArgs, tp.typeArgs) && { val lhs = if (isLowerBound) tp.typeArgs else typeArgs val rhs = if (isLowerBound) typeArgs else tp.typeArgs - // this is a higher-kinded type var with same arity as tp. - // side effect: adds the type constructor itself as a bound - addBound(tp.typeConstructor) - isSubArgs(lhs, rhs, params, AnyDepth) + // This is a higher-kinded type var with same arity as tp. + // If so (see SI-7517), side effect: adds the type constructor itself as a bound. + isSubArgs(lhs, rhs, params, AnyDepth) && { addBound(tp.typeConstructor); true } } } // The type with which we can successfully unify can be hidden diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala index 711a94d7bd..63f17dff34 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala @@ -4,7 +4,7 @@ package internal package tpe import scala.collection.{ mutable } -import util.Statistics +import util.{ Statistics, TriState } import scala.annotation.tailrec trait TypeComparers { @@ -118,30 +118,20 @@ trait TypeComparers { // if (subsametypeRecursions == 0) undoLog.clear() } - private def isSameType1(tp1: Type, tp2: Type): Boolean = { - if ((tp1 eq tp2) || - (tp1 eq ErrorType) || (tp1 eq WildcardType) || - (tp2 eq ErrorType) || (tp2 eq WildcardType)) - true - else if ((tp1 eq NoType) || (tp2 eq NoType)) - false - else if (tp1 eq NoPrefix) // !! I do not see how this would be warranted by the spec - tp2.typeSymbol.isPackageClass - else if (tp2 eq NoPrefix) // !! I do not see how this would be warranted by the spec - tp1.typeSymbol.isPackageClass - else if (tp1.isInstanceOf[AnnotatedType] || tp2.isInstanceOf[AnnotatedType]) - annotationsConform(tp1, tp2) && annotationsConform(tp2, tp1) && (tp1.withoutAnnotations =:= tp2.withoutAnnotations) - else { - // We flush out any AnnotatedTypes before calling isSameType2 because - // unlike most other subclasses of Type, we have to allow for equivalence of any - // combination of { tp1, tp2 } { is, is not } an AnnotatedType - this because the - // logic of "annotationsConform" is arbitrary and unknown. - isSameType2(tp1, tp2) || { - val tp1n = normalizePlus(tp1) - val tp2n = normalizePlus(tp2) - ((tp1n ne tp1) || (tp2n ne tp2)) && isSameType(tp1n, tp2n) - } - } + // @pre: at least one argument has annotations + private def sameAnnotatedTypes(tp1: Type, tp2: Type) = ( + annotationsConform(tp1, tp2) + && annotationsConform(tp2, tp1) + && (tp1.withoutAnnotations =:= tp2.withoutAnnotations) + ) + // We flush out any AnnotatedTypes before calling isSameType2 because + // unlike most other subclasses of Type, we have to allow for equivalence of any + // combination of { tp1, tp2 } { is, is not } an AnnotatedType - this because the + // logic of "annotationsConform" is arbitrary and unknown. + private def isSameType1(tp1: Type, tp2: Type): Boolean = typeRelationPreCheck(tp1, tp2) match { + case state if state.isKnown => state.booleanValue + case _ if typeHasAnnotations(tp1) || typeHasAnnotations(tp2) => sameAnnotatedTypes(tp1, tp2) + case _ => isSameType2(tp1, tp2) } private def isSameHKTypes(tp1: Type, tp2: Type) = ( @@ -186,6 +176,8 @@ trait TypeComparers { } def isSameType2(tp1: Type, tp2: Type): Boolean = { + def retry(lhs: Type, rhs: Type) = ((lhs ne tp1) || (rhs ne tp2)) && isSameType(lhs, rhs) + /* Here we highlight those unfortunate type-like constructs which * are hidden bundles of mutable state, cruising the type system picking * up any type constraints naive enough to get into their hot rods. @@ -236,6 +228,7 @@ trait TypeComparers { || sameSingletonType || mutateNonTypeConstructs(tp1, tp2) || mutateNonTypeConstructs(tp2, tp1) + || retry(normalizePlus(tp1), normalizePlus(tp2)) ) } @@ -276,12 +269,12 @@ trait TypeComparers { else try { pendingSubTypes += p - isSubType2(tp1, tp2, depth) + isSubType1(tp1, tp2, depth) } finally { pendingSubTypes -= p } } else { - isSubType2(tp1, tp2, depth) + isSubType1(tp1, tp2, depth) } } finally if (!result) undoLog.undoTo(before) @@ -294,6 +287,39 @@ trait TypeComparers { // if (subsametypeRecursions == 0) undoLog.clear() } + /** Check whether the subtype or type equivalence relationship + * between the argument is predetermined. Returns a tri-state + * value: True means the arguments are always sub/same types, + * False means they never are, and Unknown means the caller + * will have to figure things out. + */ + private def typeRelationPreCheck(tp1: Type, tp2: Type): TriState = { + def isTrue = ( + (tp1 eq tp2) + || isErrorOrWildcard(tp1) + || isErrorOrWildcard(tp2) + || (tp1 eq NoPrefix) && tp2.typeSymbol.isPackageClass // !! I do not see how this would be warranted by the spec + || (tp2 eq NoPrefix) && tp1.typeSymbol.isPackageClass // !! I do not see how this would be warranted by the spec + ) + // isFalse, assuming !isTrue + def isFalse = ( + (tp1 eq NoType) + || (tp2 eq NoType) + || (tp1 eq NoPrefix) + || (tp2 eq NoPrefix) + ) + + if (isTrue) TriState.True + else if (isFalse) TriState.False + else TriState.Unknown + } + + private def isSubType1(tp1: Type, tp2: Type, depth: Int): Boolean = typeRelationPreCheck(tp1, tp2) match { + case state if state.isKnown => state.booleanValue + case _ if typeHasAnnotations(tp1) || typeHasAnnotations(tp2) => annotationsConform(tp1, tp2) && (tp1.withoutAnnotations <:< tp2.withoutAnnotations) + case _ => isSubType2(tp1, tp2, depth) + } + private def isPolySubType(tp1: PolyType, tp2: PolyType): Boolean = { val PolyType(tparams1, res1) = tp1 val PolyType(tparams2, res2) = tp2 @@ -332,12 +358,13 @@ trait TypeComparers { /** Does type `tp1` conform to `tp2`? */ private def isSubType2(tp1: Type, tp2: Type, depth: Int): Boolean = { - if ((tp1 eq tp2) || isErrorOrWildcard(tp1) || isErrorOrWildcard(tp2)) return true - if ((tp1 eq NoType) || (tp2 eq NoType)) return false - if (tp1 eq NoPrefix) return (tp2 eq NoPrefix) || tp2.typeSymbol.isPackageClass // !! I do not see how the "isPackageClass" would be warranted by the spec - if (tp2 eq NoPrefix) return tp1.typeSymbol.isPackageClass - if (isSingleType(tp1) && isSingleType(tp2) || isConstantType(tp1) && isConstantType(tp2)) return tp1 =:= tp2 - if (tp1.isHigherKinded || tp2.isHigherKinded) return isHKSubType(tp1, tp2, depth) + def retry(lhs: Type, rhs: Type) = ((lhs ne tp1) || (rhs ne tp2)) && isSubType(lhs, rhs, depth) + + if (isSingleType(tp1) && isSingleType(tp2) || isConstantType(tp1) && isConstantType(tp2)) + return (tp1 =:= tp2) || retry(tp1.underlying, tp2) + + if (tp1.isHigherKinded || tp2.isHigherKinded) + return isHKSubType(tp1, tp2, depth) /* First try, on the right: * - unwrap Annotated types, BoundedWildcardTypes, diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index a9a1285de3..580ada8254 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -55,9 +55,13 @@ trait Erasure { } } + /** Arrays despite their finality may turn up as refined type parents, + * e.g. with "tagged types" like Array[Int] with T. + */ protected def unboundedGenericArrayLevel(tp: Type): Int = tp match { case GenericArray(level, core) if !(core <:< AnyRefTpe) => level - case _ => 0 + case RefinedType(ps, _) if ps.nonEmpty => logResult(s"Unbounded generic level for $tp is")(ps map unboundedGenericArrayLevel max) + case _ => 0 } // @M #2585 when generating a java generic signature that includes diff --git a/src/reflect/scala/reflect/internal/util/TriState.scala b/src/reflect/scala/reflect/internal/util/TriState.scala new file mode 100644 index 0000000000..c7a35d4637 --- /dev/null +++ b/src/reflect/scala/reflect/internal/util/TriState.scala @@ -0,0 +1,26 @@ +package scala +package reflect +package internal +package util + +import TriState._ + +/** A simple true/false/unknown value, for those days when + * true and false don't quite partition the space. + */ +final class TriState private (val value: Int) extends AnyVal { + def isKnown = this != Unknown + def booleanValue = this match { + case True => true + case False => false + case _ => sys.error("Not a Boolean value") + } +} + +object TriState { + implicit def booleanToTriState(b: Boolean): TriState = if (b) True else False + + val Unknown = new TriState(-1) + val False = new TriState(0) + val True = new TriState(1) +} diff --git a/src/reflect/scala/reflect/macros/Macro.scala b/src/reflect/scala/reflect/macros/Macro.scala new file mode 100644 index 0000000000..44bedf483d --- /dev/null +++ b/src/reflect/scala/reflect/macros/Macro.scala @@ -0,0 +1,39 @@ +package scala.reflect +package macros + +/** + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * + * Traditionally macro implementations are defined as methods, + * but this trait provides an alternative way of encoding macro impls as + * bundles, traits which extend `scala.reflect.macros.Macro`. + * + * Instead of: + * + * def impl[T: c.WeakTypeTag](c: Context)(x: c.Expr[Int]) = ... + * + * One can write: + * + * trait Impl extends Macro { + * def apply[T: c.WeakTypeTag](x: c.Expr[Int]) = ... + * } + * + * Without changing anything else at all. + * + * This language feature is useful in itself in cases when macro implementations + * are complex and need to be modularized. State of the art technique of addressing this need is quite heavyweight: + * http://docs.scala-lang.org/overviews/macros/overview.html#writing_bigger_macros. + * + * However utility of this approach to writing macros isn't limited to just convenience. + * When a macro implementation becomes not just a function, but a full-fledged module, + * it can define callbacks that will be called by the compiler upon interesting events. + * In subsequent commits I will add support for programmable type inference + */ +trait Macro { + /** The context to be used by the macro implementation. + * + * Vanilla macro implementations have to carry it in their signatures, however when a macro is a full-fledged module, + * it can define the context next to the implementation, makes implementation signature more lightweight. + */ + val c: Context +} diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index adee155db0..a3684f602f 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -972,8 +972,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni javaTypeToValueClass(jclazz) orElse lookupClass assert (cls.isType, - sm"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} - | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""") + (if (cls != NoSymbol) s"not a type: symbol $cls" else "no symbol could be") + + s" loaded from $jclazz in $owner with name $simpleName and classloader $classLoader") cls.asClass } diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala index 0354b424d2..41c1310e17 100644 --- a/src/reflect/scala/reflect/runtime/package.scala +++ b/src/reflect/scala/reflect/runtime/package.scala @@ -21,7 +21,7 @@ package object runtime { */ // implementation hardwired to the `currentMirror` method below // using the mechanism implemented in `scala.tools.reflect.FastTrack` - def currentMirror: universe.Mirror = ??? // macro + def currentMirror: universe.Mirror = macro ??? } package runtime { diff --git a/test/files/neg/macro-invalidimpl-a.check b/test/files/neg/macro-invalidimpl-a.check deleted file mode 100644 index 7f11f3b865..0000000000 --- a/test/files/neg/macro-invalidimpl-a.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-a/Impls_1.scala b/test/files/neg/macro-invalidimpl-a/Impls_1.scala deleted file mode 100644 index cfa1218038..0000000000 --- a/test/files/neg/macro-invalidimpl-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala deleted file mode 100644 index 2220ddae0c..0000000000 --- a/test/files/neg/macro-invalidimpl-a/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - val impls = new Impls - def foo(x: Any) = macro impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-b.check b/test/files/neg/macro-invalidimpl-b.check deleted file mode 100644 index 7f11f3b865..0000000000 --- a/test/files/neg/macro-invalidimpl-b.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:3: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala deleted file mode 100644 index 81e40837d2..0000000000 --- a/test/files/neg/macro-invalidimpl-b/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - val impls = Impls - def foo(x: Any) = macro impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c.check b/test/files/neg/macro-invalidimpl-c.check deleted file mode 100644 index 9e0181c0a3..0000000000 --- a/test/files/neg/macro-invalidimpl-c.check +++ /dev/null @@ -1,4 +0,0 @@ -Impls_Macros_1.scala:8: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro Impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala b/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala deleted file mode 100644 index 67a0eb348b..0000000000 --- a/test/files/neg/macro-invalidimpl-c/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class Macros { - object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? - } - - def foo(x: Any) = macro Impls.foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d.check b/test/files/neg/macro-invalidimpl-d.check deleted file mode 100644 index 76a5ba9c8c..0000000000 --- a/test/files/neg/macro-invalidimpl-d.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation must be in statically accessible object - def foo(x: Any) = macro Impls.foo - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-d/Impls_1.scala b/test/files/neg/macro-invalidimpl-d/Impls_1.scala deleted file mode 100644 index e0819c938c..0000000000 --- a/test/files/neg/macro-invalidimpl-d/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -trait MacroHelpers { - object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = x - } -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala deleted file mode 100644 index 067ab1ddec..0000000000 --- a/test/files/neg/macro-invalidimpl-d/Macros_Test_2.scala +++ /dev/null @@ -1,7 +0,0 @@ -class Macros extends MacroHelpers { - def foo(x: Any) = macro Impls.foo -} - -object Test extends App { - println(new Macros().foo(42)) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-e.check b/test/files/neg/macro-invalidimpl-e.check deleted file mode 100644 index e0910b2899..0000000000 --- a/test/files/neg/macro-invalidimpl-e.check +++ /dev/null @@ -1,13 +0,0 @@ -Macros_Test_2.scala:2: error: ambiguous reference to overloaded definition, -both method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing -and method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing -match expected type ? - def foo(x: Any) = macro Impls.foo - ^ -Macros_Test_2.scala:3: error: ambiguous reference to overloaded definition, -both method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing -and method foo in object Impls of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing -match expected type ? - def foo(x: Any, y: Any) = macro Impls.foo - ^ -two errors found diff --git a/test/files/neg/macro-invalidimpl-e/Impls_1.scala b/test/files/neg/macro-invalidimpl-e/Impls_1.scala deleted file mode 100644 index fd40119c31..0000000000 --- a/test/files/neg/macro-invalidimpl-e/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? - def foo(c: Ctx)(x: c.Expr[Any], y: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala deleted file mode 100644 index 6edde08167..0000000000 --- a/test/files/neg/macro-invalidimpl-e/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo - def foo(x: Any, y: Any) = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f.check b/test/files/neg/macro-invalidimpl-f.check deleted file mode 100644 index 4e5851f566..0000000000 --- a/test/files/neg/macro-invalidimpl-f.check +++ /dev/null @@ -1,7 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation has wrong shape: - required: (c: scala.reflect.macros.Context)(): c.Expr[Unit] - found : (c: scala.reflect.macros.Context): c.Expr[Unit] -number of parameter sections differ - def bar1() = macro Impls.fooNullary - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-f/Impls_1.scala b/test/files/neg/macro-invalidimpl-f/Impls_1.scala deleted file mode 100644 index 0e4da86d22..0000000000 --- a/test/files/neg/macro-invalidimpl-f/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def fooNullary(c: Ctx) = { - import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) - c.Expr[Unit](body) - } - - def fooEmpty(c: Ctx)() = fooNullary(c) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala deleted file mode 100644 index 493edf1df8..0000000000 --- a/test/files/neg/macro-invalidimpl-f/Macros_Test_2.scala +++ /dev/null @@ -1,9 +0,0 @@ -object Macros { - def bar1() = macro Impls.fooNullary -} - -object Test extends App { - Macros.bar1 - Macros.bar1() - println("kkthxbai") -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g.check b/test/files/neg/macro-invalidimpl-g.check deleted file mode 100644 index 7342f7336f..0000000000 --- a/test/files/neg/macro-invalidimpl-g.check +++ /dev/null @@ -1,7 +0,0 @@ -Macros_Test_2.scala:2: error: macro implementation has wrong shape: - required: (c: scala.reflect.macros.Context): c.Expr[Unit] - found : (c: scala.reflect.macros.Context)(): c.Expr[Unit] -number of parameter sections differ - def foo1 = macro Impls.fooEmpty - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-g/Impls_1.scala b/test/files/neg/macro-invalidimpl-g/Impls_1.scala deleted file mode 100644 index 0e4da86d22..0000000000 --- a/test/files/neg/macro-invalidimpl-g/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def fooNullary(c: Ctx) = { - import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) - c.Expr[Unit](body) - } - - def fooEmpty(c: Ctx)() = fooNullary(c) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala deleted file mode 100644 index 5561db9f9a..0000000000 --- a/test/files/neg/macro-invalidimpl-g/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo1 = macro Impls.fooEmpty -} - -object Test extends App { - Macros.foo1 - println("kkthxbai") -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-h.check b/test/files/neg/macro-invalidimpl-h.check deleted file mode 100644 index ea76e1aeac..0000000000 --- a/test/files/neg/macro-invalidimpl-h.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:2: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] - def foo = macro Impls.foo[String] - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-h/Impls_1.scala b/test/files/neg/macro-invalidimpl-h/Impls_1.scala deleted file mode 100644 index 427fd3d5c0..0000000000 --- a/test/files/neg/macro-invalidimpl-h/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: Int](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidimpl-i.check b/test/files/neg/macro-invalidimpl-i.check deleted file mode 100644 index 846ed8d134..0000000000 --- a/test/files/neg/macro-invalidimpl-i.check +++ /dev/null @@ -1,4 +0,0 @@ -Macros_Test_2.scala:4: error: macro implementation must be public - def foo = macro Impls.impl - ^ -one error found diff --git a/test/files/neg/macro-invalidimpl-i/Impls_1.scala b/test/files/neg/macro-invalidimpl-i/Impls_1.scala deleted file mode 100644 index c35d8ab3c1..0000000000 --- a/test/files/neg/macro-invalidimpl-i/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -package foo - -import scala.reflect.macros.Context - -object Impls { - private[foo] def impl(c: Context) = ??? -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala deleted file mode 100644 index fb129c70be..0000000000 --- a/test/files/neg/macro-invalidimpl-i/Macros_Test_2.scala +++ /dev/null @@ -1,5 +0,0 @@ -package foo - -object Test extends App { - def foo = macro Impls.impl -} diff --git a/test/files/neg/macro-invalidimpl.check b/test/files/neg/macro-invalidimpl.check new file mode 100644 index 0000000000..aaf4f88fc2 --- /dev/null +++ b/test/files/neg/macro-invalidimpl.check @@ -0,0 +1,51 @@ +Macros_Test_2.scala:5: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo(x: Any) = macro impls.foo + ^ +Macros_Test_2.scala:10: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo(x: Any) = macro impls.foo + ^ +Macros_Test_2.scala:18: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo(x: Any) = macro Impls3.foo + ^ +Macros_Test_2.scala:22: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo(x: Any) = macro Impls4.foo + ^ +Macros_Test_2.scala:26: error: ambiguous reference to overloaded definition, +both method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:27: error: ambiguous reference to overloaded definition, +both method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any], y: c.Expr[Any])Nothing +and method foo in object Impls5 of type (c: scala.reflect.macros.Context)(x: c.Expr[Any])Nothing +match expected type ? + def foo(x: Any, y: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:31: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Unit] + found : (c: scala.reflect.macros.Context)(): c.Expr[Unit] +number of parameter sections differ + def foo1 = macro Impls6.fooEmpty + ^ +Macros_Test_2.scala:32: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(): c.Expr[Unit] + found : (c: scala.reflect.macros.Context): c.Expr[Unit] +number of parameter sections differ + def bar1() = macro Impls6.fooNullary + ^ +Macros_Test_2.scala:36: error: type arguments [String] do not conform to method foo's type parameter bounds [U <: Int] + def foo = macro Impls7.foo[String] + ^ +Macros_Test_2.scala:53: error: macro implementation must be public + def foo = macro Impls8.impl + ^ +10 errors found diff --git a/test/files/neg/macro-invalidimpl-a.flags b/test/files/neg/macro-invalidimpl.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-a.flags +++ b/test/files/neg/macro-invalidimpl.flags diff --git a/test/files/neg/macro-invalidimpl/Impls_1.scala b/test/files/neg/macro-invalidimpl/Impls_1.scala new file mode 100644 index 0000000000..cf78ecc65a --- /dev/null +++ b/test/files/neg/macro-invalidimpl/Impls_1.scala @@ -0,0 +1,40 @@ +import scala.reflect.macros.Context + +class Impls1 { + def foo(c: Context)(x: c.Expr[Any]) = ??? +} + +object Impls2 { + def foo(c: Context)(x: c.Expr[Any]) = ??? +} + +trait MacroHelpers { + object Impls4 { + def foo(c: Context)(x: c.Expr[Any]) = x + } +} + +object Impls5 { + def foo(c: Context)(x: c.Expr[Any]) = ??? + def foo(c: Context)(x: c.Expr[Any], y: c.Expr[Any]) = ??? +} + +object Impls6 { + def fooNullary(c: Context) = { + import c.universe._ + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) + c.Expr[Unit](body) + } + + def fooEmpty(c: Context)() = fooNullary(c) +} + +object Impls7 { + def foo[U <: Int](c: Context) = ??? +} + +package foo { + object Impls8 { + private[foo] def impl(c: Context) = ??? + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl/Macros_Test_2.scala b/test/files/neg/macro-invalidimpl/Macros_Test_2.scala new file mode 100644 index 0000000000..8aae9553f5 --- /dev/null +++ b/test/files/neg/macro-invalidimpl/Macros_Test_2.scala @@ -0,0 +1,55 @@ +import scala.reflect.macros.Context + +object Macros1 { + val impls = new Impls1 + def foo(x: Any) = macro impls.foo +} + +object Macros2 { + val impls = Impls2 + def foo(x: Any) = macro impls.foo +} + +class Macros3 { + object Impls3 { + def foo(c: Context)(x: c.Expr[Any]) = ??? + } + + def foo(x: Any) = macro Impls3.foo +} + +class Macros4 extends MacroHelpers { + def foo(x: Any) = macro Impls4.foo +} + +object Macros5 { + def foo(x: Any) = macro Impls5.foo + def foo(x: Any, y: Any) = macro Impls5.foo +} + +object Macros6 { + def foo1 = macro Impls6.fooEmpty + def bar1() = macro Impls6.fooNullary +} + +object Macros7 { + def foo = macro Impls7.foo[String] +} + +object Test extends App { + println(Macros1.foo(42)) + println(Macros2.foo(42)) + println(new Macros3().foo(42)) + println(new Macros4().foo(42)) + println(Macros5.foo(42)) + println(Macros6.foo1) + println(Macros6.bar1) + println(Macros6.bar1()) + println(Macros7.foo) +} + +package foo { + object Test extends App { + def foo = macro Impls8.impl + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nontree/Impls_1.scala b/test/files/neg/macro-invalidret-nontree/Impls_1.scala deleted file mode 100644 index ef19b1b405..0000000000 --- a/test/files/neg/macro-invalidret-nontree/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = 2 -} diff --git a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidret-nontree/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala deleted file mode 100644 index f98376a2ba..0000000000 --- a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} -import scala.reflect.runtime.{universe => ru} - -object Impls { - def foo(c: Ctx) = ru.Literal(ru.Constant(42)) -} diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala b/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidret-nonuniversetree/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check new file mode 100644 index 0000000000..8c6ed4eb45 --- /dev/null +++ b/test/files/neg/macro-invalidret.check @@ -0,0 +1,13 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context): Int +type mismatch for return type: Int does not conform to c.Expr[Any] + def foo1 = macro Impls.foo1 + ^ +Macros_Test_2.scala:3: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context): reflect.runtime.universe.Literal +type mismatch for return type: reflect.runtime.universe.Literal does not conform to c.Expr[Any] + def foo2 = macro Impls.foo2 + ^ +two errors found diff --git a/test/files/neg/macro-invalidimpl-b.flags b/test/files/neg/macro-invalidret.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-b.flags +++ b/test/files/neg/macro-invalidret.flags diff --git a/test/files/neg/macro-invalidret/Impls_1.scala b/test/files/neg/macro-invalidret/Impls_1.scala new file mode 100644 index 0000000000..a58af1a23c --- /dev/null +++ b/test/files/neg/macro-invalidret/Impls_1.scala @@ -0,0 +1,7 @@ +import scala.reflect.macros.Context +import scala.reflect.runtime.{universe => ru} + +object Impls { + def foo1(c: Context) = 2 + def foo2(c: Context) = ru.Literal(ru.Constant(42)) +} diff --git a/test/files/neg/macro-invalidret/Macros_Test_2.scala b/test/files/neg/macro-invalidret/Macros_Test_2.scala new file mode 100644 index 0000000000..f8880fa023 --- /dev/null +++ b/test/files/neg/macro-invalidret/Macros_Test_2.scala @@ -0,0 +1,10 @@ +object Macros { + def foo1 = macro Impls.foo1 + def foo2 = macro Impls.foo2 +} + +object Test extends App { + import Macros._ + foo1 + foo2 +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-a.check b/test/files/neg/macro-invalidshape-a.check deleted file mode 100644 index f38a90819e..0000000000 --- a/test/files/neg/macro-invalidshape-a.check +++ /dev/null @@ -1,5 +0,0 @@ -Macros_Test_2.scala:2: error: macro body has wrong shape: - required: macro [<implementation object>].<method name>[[<type args>]] - def foo(x: Any) = macro 2 - ^ -one error found diff --git a/test/files/neg/macro-invalidshape-a/Impls_1.scala b/test/files/neg/macro-invalidshape-a/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala deleted file mode 100644 index ffff17d1e7..0000000000 --- a/test/files/neg/macro-invalidshape-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro 2 -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-b.check b/test/files/neg/macro-invalidshape-b.check deleted file mode 100644 index 976685c6bd..0000000000 --- a/test/files/neg/macro-invalidshape-b.check +++ /dev/null @@ -1,5 +0,0 @@ -Macros_Test_2.scala:2: error: macro body has wrong shape: - required: macro [<implementation object>].<method name>[[<type args>]] - def foo(x: Any) = macro Impls.foo(null)(null) - ^ -one error found diff --git a/test/files/neg/macro-invalidshape-b/Impls_1.scala b/test/files/neg/macro-invalidshape-b/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-b/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala deleted file mode 100644 index b67cd32a6e..0000000000 --- a/test/files/neg/macro-invalidshape-b/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo(null)(null) -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.check b/test/files/neg/macro-invalidshape-c.check deleted file mode 100644 index 0b2e9cfe4f..0000000000 --- a/test/files/neg/macro-invalidshape-c.check +++ /dev/null @@ -1,9 +0,0 @@ -Macros_Test_2.scala:2: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses - def foo(x: Any) = macro {2; Impls.foo} - ^ -Macros_Test_2.scala:2: error: missing arguments for method foo in object Impls; -follow this method with `_' if you want to treat it as a partially applied function - def foo(x: Any) = macro {2; Impls.foo} - ^ -one warning found -one error found diff --git a/test/files/neg/macro-invalidshape-c/Impls_1.scala b/test/files/neg/macro-invalidshape-c/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-c/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala deleted file mode 100644 index 552c3710c7..0000000000 --- a/test/files/neg/macro-invalidshape-c/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro {2; Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-d.check b/test/files/neg/macro-invalidshape-d.check deleted file mode 100644 index e43a2ca0ab..0000000000 --- a/test/files/neg/macro-invalidshape-d.check +++ /dev/null @@ -1,8 +0,0 @@ -Macros_Test_2.scala:2: warning: macro is now a reserved word; usage as an identifier is deprecated - def foo(x: Any) = {2; macro Impls.foo} - ^ -Macros_Test_2.scala:2: error: ';' expected but '.' found. - def foo(x: Any) = {2; macro Impls.foo} - ^ -one warning found -one error found diff --git a/test/files/neg/macro-invalidshape-d.flags b/test/files/neg/macro-invalidshape-d.flags deleted file mode 100644 index 83b7265eb9..0000000000 --- a/test/files/neg/macro-invalidshape-d.flags +++ /dev/null @@ -1 +0,0 @@ --deprecation -language:experimental.macros diff --git a/test/files/neg/macro-invalidshape-d/Impls_1.scala b/test/files/neg/macro-invalidshape-d/Impls_1.scala deleted file mode 100644 index 4467021545..0000000000 --- a/test/files/neg/macro-invalidshape-d/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Any]) = ??? -} diff --git a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala b/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala deleted file mode 100644 index bacd9a6e7c..0000000000 --- a/test/files/neg/macro-invalidshape-d/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = {2; macro Impls.foo} -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape.check b/test/files/neg/macro-invalidshape.check new file mode 100644 index 0000000000..40a2952569 --- /dev/null +++ b/test/files/neg/macro-invalidshape.check @@ -0,0 +1,15 @@ +Macros_Test_2.scala:2: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo1(x: Any) = macro 2 + ^ +Macros_Test_2.scala:3: error: macro implementation reference has wrong shape. required: +macro [<static object>].<method name>[[<type args>]] or +macro [<macro bundle>].<method name>[[<type args>]] + def foo2(x: Any) = macro Impls.foo(null)(null) + ^ +Macros_Test_2.scala:4: error: missing arguments for method foo in object Impls; +follow this method with `_' if you want to treat it as a partially applied function + def foo3(x: Any) = macro {2; Impls.foo} + ^ +three errors found diff --git a/test/files/neg/macro-invalidimpl-c.flags b/test/files/neg/macro-invalidshape.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-c.flags +++ b/test/files/neg/macro-invalidshape.flags diff --git a/test/files/neg/macro-invalidimpl-b/Impls_1.scala b/test/files/neg/macro-invalidshape/Impls_1.scala index 4467021545..4467021545 100644 --- a/test/files/neg/macro-invalidimpl-b/Impls_1.scala +++ b/test/files/neg/macro-invalidshape/Impls_1.scala diff --git a/test/files/neg/macro-invalidshape/Macros_Test_2.scala b/test/files/neg/macro-invalidshape/Macros_Test_2.scala new file mode 100644 index 0000000000..f39ad20c5d --- /dev/null +++ b/test/files/neg/macro-invalidshape/Macros_Test_2.scala @@ -0,0 +1,12 @@ +object Macros { + def foo1(x: Any) = macro 2 + def foo2(x: Any) = macro Impls.foo(null)(null) + def foo3(x: Any) = macro {2; Impls.foo} +} + +object Test extends App { + import Macros._ + foo1(42) + foo2(42) + foo3(42) +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala deleted file mode 100644 index c066c485b1..0000000000 --- a/test/files/neg/macro-invalidsig-context-bounds/Impls_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag: Numeric](c: Ctx) = { - import c.universe._ - Literal(Constant(42)) - } -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala b/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala deleted file mode 100644 index 5b4602f328..0000000000 --- a/test/files/neg/macro-invalidsig-context-bounds/Macros_Test_1.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - println(foo[String]) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala deleted file mode 100644 index 4d5d29158f..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badargc/Impls_1.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Impls { - def foo = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badargc/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala deleted file mode 100644 index cf1a4cf85c..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badtype/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.api.{Universe => Ctx} - -object Impls { - def foo(c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badtype/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala deleted file mode 100644 index c4ed8be91e..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badvarargs/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(cs: Ctx*) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-badvarargs/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala deleted file mode 100644 index 6904cfb1dc..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-noctx/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala deleted file mode 100644 index e053cf99df..0000000000 --- a/test/files/neg/macro-invalidsig-ctx-noctx/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo(x: Any) = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala deleted file mode 100644 index 8205694768..0000000000 --- a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo_targs[T, U: c.WeakTypeTag](c: Ctx)(implicit x: c.Expr[Int]) = { - import c.{prefix => prefix} - import c.universe._ - val body = Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("invoking foo_targs...")))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))), - Literal(Constant(()))) - c.Expr[Unit](body) - } -} - -class Macros[T] { - def foo_targs[U](x: Int) = macro Impls.foo_targs[T, U] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala b/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala deleted file mode 100644 index 90e850df21..0000000000 --- a/test/files/neg/macro-invalidsig-implicit-params/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - println("foo_targs:") - new Macros[Int]().foo_targs[String](42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala deleted file mode 100644 index ae16612b93..0000000000 --- a/test/files/neg/macro-invalidsig-params-badargc/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int], y: c.Expr[Int]) = ??? -} - -object Macros { - def foo(x: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala b/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala deleted file mode 100644 index cbd6232073..0000000000 --- a/test/files/neg/macro-invalidsig-params-badargc/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badtype.check b/test/files/neg/macro-invalidsig-params-badtype.check index 3ec40d7e5b..3cc1c9abf1 100644 --- a/test/files/neg/macro-invalidsig-params-badtype.check +++ b/test/files/neg/macro-invalidsig-params-badtype.check @@ -1,7 +1,7 @@ Impls_Macros_1.scala:8: error: macro implementation has wrong shape: required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] - found : (c: scala.reflect.macros.Context)(x: c.universe.Tree): Nothing -type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Tree + found : (c: scala.reflect.macros.Context)(x: Int): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to Int def foo(x: Int) = macro Impls.foo - ^ + ^ one error found diff --git a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala index ab90b85881..175683d6d3 100644 --- a/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala +++ b/test/files/neg/macro-invalidsig-params-badtype/Impls_Macros_1.scala @@ -1,7 +1,7 @@ import scala.reflect.macros.{Context => Ctx} object Impls { - def foo(c: Ctx)(x: c.universe.Tree) = ??? + def foo(c: Ctx)(x: Int) = ??? } object Macros { diff --git a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala b/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala deleted file mode 100644 index cbd6232073..0000000000 --- a/test/files/neg/macro-invalidsig-params-badtype/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala deleted file mode 100644 index b4c75ad0ba..0000000000 --- a/test/files/neg/macro-invalidsig-params-badvarargs/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(xs: c.Expr[Int]*) = ??? -} - -object Macros { - def foo(x: Int, y: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala b/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala deleted file mode 100644 index fa50ac4f73..0000000000 --- a/test/files/neg/macro-invalidsig-params-badvarargs/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42, 100) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala deleted file mode 100644 index c7cf0b06c4..0000000000 --- a/test/files/neg/macro-invalidsig-params-namemismatch/Impls_Macros_1.scala +++ /dev/null @@ -1,9 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(y: c.Expr[Int], x: c.Expr[Int]) = ??? -} - -object Macros { - def foo(x: Int, y: Int) = macro Impls.foo -} diff --git a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala b/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala deleted file mode 100644 index fa50ac4f73..0000000000 --- a/test/files/neg/macro-invalidsig-params-namemismatch/Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - import Macros._ - foo(42, 100) -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala deleted file mode 100644 index dbeca178a7..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-badtype/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U](c: Ctx)(U: c.universe.Type) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala deleted file mode 100644 index a82e813221..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-badtype/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala deleted file mode 100644 index 89020de7dd..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala deleted file mode 100644 index a82e813221..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala deleted file mode 100644 index 89020de7dd..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-b/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx) = ??? -} diff --git a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala deleted file mode 100644 index eed6369a16..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-bounds-b/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U <: Int] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[Int] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala deleted file mode 100644 index f8b3c92869..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-a/Impls_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag](c: Ctx) = ??? -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala deleted file mode 100644 index 96a8de2832..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala deleted file mode 100644 index baf3aab9e3..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Ctx)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { - println(implicitly[c.WeakTypeTag[T]]) - println(implicitly[c.WeakTypeTag[U]]) - println(V) - c.literalUnit - } -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala deleted file mode 100644 index 7d02bf613a..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-b/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala deleted file mode 100644 index 44b4ed6ab3..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c/Impls_1.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Ctx)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - println(implicitly[c.WeakTypeTag[T]]) - println(implicitly[c.WeakTypeTag[U]]) - println(V) - c.literalUnit - } -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala b/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala deleted file mode 100644 index 109e142e52..0000000000 --- a/test/files/neg/macro-invalidsig-tparams-notparams-c/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[V] - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig.check b/test/files/neg/macro-invalidsig.check new file mode 100644 index 0000000000..cbdaf51081 --- /dev/null +++ b/test/files/neg/macro-invalidsig.check @@ -0,0 +1,82 @@ +Macros_Test_2.scala:2: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(implicit evidence$2: Numeric[U]): c.universe.Literal +macro implementations cannot have implicit parameters other than WeakTypeTag evidences + def foo[U] = macro Impls1.foo[U] + ^ +Macros_Test_2.scala:6: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : : Nothing +number of parameter sections differ + def foo = macro Impls2.foo + ^ +Macros_Test_2.scala:10: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.api.Universe): Nothing +type mismatch for parameter c: scala.reflect.macros.Context does not conform to scala.reflect.api.Universe + def foo = macro Impls3.foo + ^ +Macros_Test_2.scala:14: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (cs: scala.reflect.macros.Context*): Nothing +types incompatible for parameter cs: corresponding is not a vararg parameter + def foo = macro Impls4.foo + ^ +Macros_Test_2.scala:18: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Any]): c.Expr[Any] + found : (c: scala.reflect.macros.Context): Nothing +number of parameter sections differ + def foo(x: Any) = macro Impls5.foo + ^ +Macros_Test_2.scala:22: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Unit] + found : (c: scala.reflect.macros.Context)(implicit x: c.Expr[Int]): c.Expr[Unit] +macro implementations cannot have implicit parameters other than WeakTypeTag evidences + def foo[U](x: Int) = macro Impls6.foo[T, U] + ^ +Macros_Test_2.scala:26: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): Nothing +parameter lists have different length, found extra parameter y: c.Expr[Int] + def foo(x: Int) = macro Impls7.foo + ^ +Macros_Test_2.scala:30: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(x: c.universe.Symbol): Nothing +type mismatch for parameter x: c.Expr[Int] does not conform to c.universe.Symbol + def foo(x: Int) = macro Impls8.foo + ^ +Macros_Test_2.scala:34: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(xs: c.Expr[Int]*): Nothing +parameter lists have different length, required extra parameter y: c.Expr[Int] + def foo(x: Int, y: Int) = macro Impls9.foo + ^ +Macros_Test_2.scala:38: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context)(x: c.Expr[Int], y: c.Expr[Int]): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(y: c.Expr[Int], x: c.Expr[Int]): Nothing +parameter names differ: x != y + def foo(x: Int, y: Int) = macro Impls10.foo + ^ +Macros_Test_2.scala:42: error: macro implementation has wrong shape: + required: (c: scala.reflect.macros.Context): c.Expr[Any] + found : (c: scala.reflect.macros.Context)(U: c.universe.Type): Nothing +number of parameter sections differ + def foo[U] = macro Impls11.foo[U] + ^ +Macros_Test_2.scala:46: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U] = macro Impls12.foo[U] + ^ +Macros_Test_2.scala:50: error: type arguments [U] do not conform to method foo's type parameter bounds [U <: String] + def foo[U <: Int] = macro Impls13.foo[U] + ^ +Macros_Test_2.scala:54: error: wrong number of type parameters for method foo: [U](c: scala.reflect.macros.Context)(implicit evidence$4: c.WeakTypeTag[U])Nothing + def foo = macro Impls14.foo + ^ +Macros_Test_2.scala:59: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$5: c.WeakTypeTag[T], implicit evidence$6: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] + def foo15[V] = macro Impls15.foo + ^ +Macros_Test_2.scala:60: error: wrong number of type parameters for method foo: [T, U, V](c: scala.reflect.macros.Context)(implicit evidence$7: c.WeakTypeTag[T], implicit evidence$8: c.WeakTypeTag[U], implicit V: c.WeakTypeTag[V])c.Expr[Unit] + def foo16[V] = macro Impls16.foo[V] + ^ +16 errors found diff --git a/test/files/neg/macro-invalidimpl-d.flags b/test/files/neg/macro-invalidsig.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-d.flags +++ b/test/files/neg/macro-invalidsig.flags diff --git a/test/files/neg/macro-invalidsig/Impls_1.scala b/test/files/neg/macro-invalidsig/Impls_1.scala new file mode 100644 index 0000000000..e7d6c18f8d --- /dev/null +++ b/test/files/neg/macro-invalidsig/Impls_1.scala @@ -0,0 +1,88 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U: c.WeakTypeTag: Numeric](c: Context) = { + import c.universe._ + Literal(Constant(42)) + } +} + +object Impls2 { + def foo = ??? +} + +object Impls3 { + def foo(c: scala.reflect.api.Universe) = ??? +} + +object Impls4 { + def foo(cs: Context*) = ??? +} + +object Impls5 { + def foo(c: Context) = ??? +} + +object Impls6 { + def foo[T, U: c.WeakTypeTag](c: Context)(implicit x: c.Expr[Int]) = { + import c.{prefix => prefix} + import c.universe._ + val body = Block(List( + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("invoking foo_targs...")))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))), + Literal(Constant(()))) + c.Expr[Unit](body) + } +} + +object Impls7 { + def foo(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = ??? +} + +object Impls8 { + def foo(c: Context)(x: c.universe.Symbol) = ??? +} + +object Impls9 { + def foo(c: Context)(xs: c.Expr[Int]*) = ??? +} + +object Impls10 { + def foo(c: Context)(y: c.Expr[Int], x: c.Expr[Int]) = ??? +} + +object Impls11 { + def foo[U](c: Context)(U: c.universe.Type) = ??? +} + +object Impls12 { + def foo[U <: String](c: Context) = ??? +} + +object Impls13 { + def foo[U <: String](c: Context) = ??? +} + +object Impls14 { + def foo[U: c.WeakTypeTag](c: Context) = ??? +} + +object Impls15 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Context)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { + println(implicitly[c.WeakTypeTag[T]]) + println(implicitly[c.WeakTypeTag[U]]) + println(V) + c.literalUnit + } +} + +object Impls16 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag, V](c: Context)(implicit V: c.WeakTypeTag[V]): c.Expr[Unit] = { + println(implicitly[c.WeakTypeTag[T]]) + println(implicitly[c.WeakTypeTag[U]]) + println(V) + c.literalUnit + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidsig/Macros_Test_2.scala b/test/files/neg/macro-invalidsig/Macros_Test_2.scala new file mode 100644 index 0000000000..0a6a321431 --- /dev/null +++ b/test/files/neg/macro-invalidsig/Macros_Test_2.scala @@ -0,0 +1,83 @@ +object Macros1 { + def foo[U] = macro Impls1.foo[U] +} + +object Macros2 { + def foo = macro Impls2.foo +} + +object Macros3 { + def foo = macro Impls3.foo +} + +object Macros4 { + def foo = macro Impls4.foo +} + +object Macros5 { + def foo(x: Any) = macro Impls5.foo +} + +class Macros6[T] { + def foo[U](x: Int) = macro Impls6.foo[T, U] +} + +object Macros7 { + def foo(x: Int) = macro Impls7.foo +} + +object Macros8 { + def foo(x: Int) = macro Impls8.foo +} + +object Macros9 { + def foo(x: Int, y: Int) = macro Impls9.foo +} + +object Macros10 { + def foo(x: Int, y: Int) = macro Impls10.foo +} + +object Macros11 { + def foo[U] = macro Impls11.foo[U] +} + +object Macros12 { + def foo[U] = macro Impls12.foo[U] +} + +object Macros13 { + def foo[U <: Int] = macro Impls13.foo[U] +} + +object Macros14 { + def foo = macro Impls14.foo +} + +class D[T] { + class C[U] { + def foo15[V] = macro Impls15.foo + def foo16[V] = macro Impls16.foo[V] + } +} + +object Test extends App { + println(Macros1.foo[String]) + println(Macros2.foo) + println(Macros3.foo) + println(Macros4.foo) + println(Macros5.foo(42)) + println(new Macros6[Int]().foo[String](42)) + println(Macros7.foo(42)) + println(Macros8.foo) + println(Macros9.foo(4, 2)) + println(Macros10.foo(4, 2)) + println(Macros11.foo[Int]) + println(Macros12.foo[Int]) + println(Macros13.foo[Int]) + println(Macros14.foo) + val outer1 = new D[Int] + val outer2 = new outer1.C[String] + outer2.foo15[Boolean] + outer2.foo16[Boolean] +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check index 294cfd0cf5..4c1115418b 100644 --- a/test/files/neg/macro-invalidusage-badargs.check +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -1,6 +1,18 @@ -Macros_Test_2.scala:7: error: type mismatch; +Macros_Test_2.scala:5: error: type mismatch; found : String("42") required: Int - val s: String = foo("42") - ^ -one error found + foo("42") + ^ +Macros_Test_2.scala:6: error: too few argument lists for macro invocation + foo + ^ +Macros_Test_2.scala:7: error: Int does not take parameters + foo(4)(2) + ^ +Macros_Test_2.scala:8: error: macro applications do not support named and/or default arguments + foo() + ^ +Macros_Test_2.scala:9: error: too many arguments for macro method foo: (x: Int)Int + foo(4, 2) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala index a6af1bb277..0b3ca0590b 100644 --- a/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badargs/Macros_Test_2.scala @@ -1,8 +1,10 @@ -object Macros { - def foo(x: Int) = macro Impls.foo -} +object Macros { def foo(x: Int) = macro Impls.foo } +import Macros._ object Test extends App { - import Macros._ - val s: String = foo("42") + foo("42") + foo + foo(4)(2) + foo() + foo(4, 2) }
\ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-badbounds-a.check b/test/files/neg/macro-invalidusage-badbounds.check index 277f407d38..277f407d38 100644 --- a/test/files/neg/macro-invalidusage-badbounds-a.check +++ b/test/files/neg/macro-invalidusage-badbounds.check diff --git a/test/files/neg/macro-invalidimpl-e.flags b/test/files/neg/macro-invalidusage-badbounds.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-e.flags +++ b/test/files/neg/macro-invalidusage-badbounds.flags diff --git a/test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala index 6ee71a3628..6ee71a3628 100644 --- a/test/files/neg/macro-invalidusage-badbounds-a/Impls_1.scala +++ b/test/files/neg/macro-invalidusage-badbounds/Impls_1.scala diff --git a/test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala index 3139599108..3139599108 100644 --- a/test/files/neg/macro-invalidusage-badbounds-a/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badbounds/Macros_Test_2.scala diff --git a/test/files/neg/macro-invalidusage-badtargs-untyped.check b/test/files/neg/macro-invalidusage-badtargs-untyped.check new file mode 100644 index 0000000000..1678180281 --- /dev/null +++ b/test/files/neg/macro-invalidusage-badtargs-untyped.check @@ -0,0 +1,18 @@ +Macros_Test_2.scala:11: error: macro method foo1: (x: _)Int does not take type parameters. + foo1[String](42) + ^ +Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: _)Int + foo2[String, String](42) + ^ +Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: _)Int + foo3[String](42) + ^ +Macros_Test_2.scala:14: error: String takes no type parameters, expected: one + foo4[String](42) + ^ +Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). +List's type parameters do not match type T's expected parameters: +type A has no type parameters, but type U has one + foo5[List](42) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidimpl-f.flags b/test/files/neg/macro-invalidusage-badtargs-untyped.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-f.flags +++ b/test/files/neg/macro-invalidusage-badtargs-untyped.flags diff --git a/test/files/neg/macro-invalidusage-badtargs.check b/test/files/neg/macro-invalidusage-badtargs.check index 73801ab43e..6a9e1d6e6b 100644 --- a/test/files/neg/macro-invalidusage-badtargs.check +++ b/test/files/neg/macro-invalidusage-badtargs.check @@ -1,4 +1,18 @@ -Macros_Test_2.scala:7: error: macro method foo: (x: Int)Int does not take type parameters. - val s: String = foo[String](42) - ^ -one error found +Macros_Test_2.scala:11: error: macro method foo1: (x: Int)Int does not take type parameters. + foo1[String](42) + ^ +Macros_Test_2.scala:12: error: wrong number of type parameters for macro method foo2: [T](x: Int)Int + foo2[String, String](42) + ^ +Macros_Test_2.scala:13: error: wrong number of type parameters for macro method foo3: [T, U](x: Int)Int + foo3[String](42) + ^ +Macros_Test_2.scala:14: error: String takes no type parameters, expected: one + foo4[String](42) + ^ +Macros_Test_2.scala:15: error: kinds of the type arguments (List) do not conform to the expected kinds of the type parameters (type T). +List's type parameters do not match type T's expected parameters: +type A has no type parameters, but type U has one + foo5[List](42) + ^ +5 errors found diff --git a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala index c54093b637..fd16d163c3 100644 --- a/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala +++ b/test/files/neg/macro-invalidusage-badtargs/Macros_Test_2.scala @@ -1,8 +1,16 @@ object Macros { - def foo(x: Int) = macro Impls.foo + def foo1(x: Int) = macro Impls.foo + def foo2[T](x: Int) = macro Impls.foo + def foo3[T, U](x: Int) = macro Impls.foo + def foo4[T[_]](x: Int) = macro Impls.foo + def foo5[T[U[_]]](x: Int) = macro Impls.foo } object Test extends App { import Macros._ - val s: String = foo[String](42) + foo1[String](42) + foo2[String, String](42) + foo3[String](42) + foo4[String](42) + foo5[List](42) }
\ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-nontypeable.check b/test/files/neg/macro-invalidusage-nontypeable.check new file mode 100644 index 0000000000..88e6057e5e --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable.check @@ -0,0 +1,4 @@ +Test_2.scala:2: error: not found: value IDoNotExist + Macros.foo + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-g.flags b/test/files/neg/macro-invalidusage-nontypeable.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-g.flags +++ b/test/files/neg/macro-invalidusage-nontypeable.flags diff --git a/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala b/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala new file mode 100644 index 0000000000..869a5a41fa --- /dev/null +++ b/test/files/neg/macro-invalidusage-nontypeable/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.universe._ + val body = Ident(TermName("IDoNotExist")) + c.Expr[Int](body) + } +} + +object Macros { + def foo = macro Impls.foo +}
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b/Test_2.scala b/test/files/neg/macro-invalidusage-nontypeable/Test_2.scala index 7dffc5107d..acfddae942 100644 --- a/test/files/run/macro-def-path-dependent-b/Test_2.scala +++ b/test/files/neg/macro-invalidusage-nontypeable/Test_2.scala @@ -1,3 +1,3 @@ object Test extends App { - println("it works") + Macros.foo }
\ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-presuper.check b/test/files/neg/macro-invalidusage-presuper.check new file mode 100644 index 0000000000..f63a0eef80 --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper.check @@ -0,0 +1,4 @@ +Macros_Test_2.scala:3: error: only type definitions and concrete field definitions allowed in early object initialization section +class D extends { def x = macro impl } with AnyRef + ^ +one error found diff --git a/test/files/neg/macro-invalidimpl-h.flags b/test/files/neg/macro-invalidusage-presuper.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-h.flags +++ b/test/files/neg/macro-invalidusage-presuper.flags diff --git a/test/files/neg/macro-invalidusage-presuper/Impls_1.scala b/test/files/neg/macro-invalidusage-presuper/Impls_1.scala new file mode 100644 index 0000000000..b39a037c47 --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper/Impls_1.scala @@ -0,0 +1,5 @@ +import scala.reflect.macros.Context + +object Impls { + def impl(c: Context) = c.literalUnit +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala b/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala new file mode 100644 index 0000000000..ff46a5915f --- /dev/null +++ b/test/files/neg/macro-invalidusage-presuper/Macros_Test_2.scala @@ -0,0 +1,3 @@ +import Impls._ + +class D extends { def x = macro impl } with AnyRef
\ No newline at end of file diff --git a/test/files/neg/macro-qmarkqmarkqmark.check b/test/files/neg/macro-qmarkqmarkqmark.check index afd49e7d90..bc3e25edaf 100644 --- a/test/files/neg/macro-qmarkqmarkqmark.check +++ b/test/files/neg/macro-qmarkqmarkqmark.check @@ -1,7 +1,7 @@ macro-qmarkqmarkqmark.scala:5: error: macro implementation is missing foo1 ^ -macro-qmarkqmarkqmark.scala:8: error: macros cannot be partially applied +macro-qmarkqmarkqmark.scala:8: error: too few argument lists for macro invocation foo2 ^ macro-qmarkqmarkqmark.scala:9: error: macro implementation is missing diff --git a/test/files/neg/t5689.check b/test/files/neg/t5689.check index 50aaa7dbfe..ad9b79cdcb 100644 --- a/test/files/neg/t5689.check +++ b/test/files/neg/t5689.check @@ -3,5 +3,5 @@ t5689.scala:4: error: macro implementation has wrong shape: found : (c: scala.reflect.macros.Context)(i: c.Expr[Double]): c.Expr[Int] type mismatch for return type: c.Expr[Int] does not conform to c.Expr[String] def returnsString(i: Double): String = macro returnsIntImpl - ^ + ^ one error found diff --git a/test/files/neg/t6138.check b/test/files/neg/t6138.check new file mode 100644 index 0000000000..8fd9978248 --- /dev/null +++ b/test/files/neg/t6138.check @@ -0,0 +1,7 @@ +t6138.scala:4: error: ambiguous reference to overloaded definition, +both method getClass in object definitions of type (s: Int)Any +and method getClass in object definitions of type (s: String)Any +match argument types (Nothing) + getClass(???): String + ^ +one error found diff --git a/test/files/neg/t6138.scala b/test/files/neg/t6138.scala new file mode 100644 index 0000000000..2f45a46b1c --- /dev/null +++ b/test/files/neg/t6138.scala @@ -0,0 +1,5 @@ +object definitions { + def getClass(s: String): Any = ??? + def getClass(s: Int): Any = ??? + getClass(???): String +} diff --git a/test/files/neg/t7157.check b/test/files/neg/t7157.check new file mode 100644 index 0000000000..c6a7af9a23 --- /dev/null +++ b/test/files/neg/t7157.check @@ -0,0 +1,73 @@ +Test_2.scala:5: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1) + ^ +Test_2.scala:6: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1, 2) + ^ +Test_2.scala:7: error: too many arguments for macro method m1_0_0: ()Unit + m1_0_0(1, 2, 3) + ^ +Test_2.scala:9: error: macro applications do not support named and/or default arguments + m1_1_1() + ^ +Test_2.scala:11: error: too many arguments for macro method m1_1_1: (x: Int)Unit + m1_1_1(1, 2) + ^ +Test_2.scala:12: error: too many arguments for macro method m1_1_1: (x: Int)Unit + m1_1_1(1, 2, 3) + ^ +Test_2.scala:14: error: macro applications do not support named and/or default arguments + m1_2_2() + ^ +Test_2.scala:15: error: macro applications do not support named and/or default arguments + m1_2_2(1) + ^ +Test_2.scala:17: error: too many arguments for macro method m1_2_2: (x: Int, y: Int)Unit + m1_2_2(1, 2, 3) + ^ +Test_2.scala:24: error: macro applications do not support named and/or default arguments + m1_1_inf() + ^ +Test_2.scala:29: error: macro applications do not support named and/or default arguments + m1_2_inf() + ^ +Test_2.scala:30: error: macro applications do not support named and/or default arguments + m1_2_inf(1) + ^ +Test_2.scala:35: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1) + ^ +Test_2.scala:36: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1, 2) + ^ +Test_2.scala:37: error: too many arguments for macro method m2_0_0: ()Unit + m2_0_0()(1, 2, 3) + ^ +Test_2.scala:39: error: macro applications do not support named and/or default arguments + m2_1_1()() + ^ +Test_2.scala:41: error: too many arguments for macro method m2_1_1: (x: Int)Unit + m2_1_1()(1, 2) + ^ +Test_2.scala:42: error: too many arguments for macro method m2_1_1: (x: Int)Unit + m2_1_1()(1, 2, 3) + ^ +Test_2.scala:44: error: macro applications do not support named and/or default arguments + m2_2_2()() + ^ +Test_2.scala:45: error: macro applications do not support named and/or default arguments + m2_2_2()(1) + ^ +Test_2.scala:47: error: too many arguments for macro method m2_2_2: (x: Int, y: Int)Unit + m2_2_2()(1, 2, 3) + ^ +Test_2.scala:54: error: macro applications do not support named and/or default arguments + m2_1_inf()() + ^ +Test_2.scala:59: error: macro applications do not support named and/or default arguments + m2_2_inf()() + ^ +Test_2.scala:60: error: macro applications do not support named and/or default arguments + m2_2_inf()(1) + ^ +24 errors found diff --git a/test/files/neg/t7157/Impls_Macros_1.scala b/test/files/neg/t7157/Impls_Macros_1.scala new file mode 100644 index 0000000000..09f423fbab --- /dev/null +++ b/test/files/neg/t7157/Impls_Macros_1.scala @@ -0,0 +1,32 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl1_0_0(c: Context)() = c.literalUnit + def impl1_1_1(c: Context)(x: c.Expr[Int]) = c.literalUnit + def impl1_2_2(c: Context)(x: c.Expr[Int], y: c.Expr[Int]) = c.literalUnit + def m1_0_0() = macro impl1_0_0 + def m1_1_1(x: Int) = macro impl1_1_1 + def m1_2_2(x: Int, y: Int) = macro impl1_2_2 + + def impl1_0_inf(c: Context)(x: c.Expr[Int]*) = c.literalUnit + def impl1_1_inf(c: Context)(x: c.Expr[Int], y: c.Expr[Int]*) = c.literalUnit + def impl1_2_inf(c: Context)(x: c.Expr[Int], y: c.Expr[Int], z: c.Expr[Int]*) = c.literalUnit + def m1_0_inf(x: Int*) = macro impl1_0_inf + def m1_1_inf(x: Int, y: Int*) = macro impl1_1_inf + def m1_2_inf(x: Int, y: Int, z: Int*) = macro impl1_2_inf + + def impl2_0_0(c: Context)()() = c.literalUnit + def impl2_1_1(c: Context)()(x: c.Expr[Int]) = c.literalUnit + def impl2_2_2(c: Context)()(x: c.Expr[Int], y: c.Expr[Int]) = c.literalUnit + def m2_0_0()() = macro impl2_0_0 + def m2_1_1()(x: Int) = macro impl2_1_1 + def m2_2_2()(x: Int, y: Int) = macro impl2_2_2 + + def impl2_0_inf(c: Context)()(x: c.Expr[Int]*) = c.literalUnit + def impl2_1_inf(c: Context)()(x: c.Expr[Int], y: c.Expr[Int]*) = c.literalUnit + def impl2_2_inf(c: Context)()(x: c.Expr[Int], y: c.Expr[Int], z: c.Expr[Int]*) = c.literalUnit + def m2_0_inf()(x: Int*) = macro impl2_0_inf + def m2_1_inf()(x: Int, y: Int*) = macro impl2_1_inf + def m2_2_inf()(x: Int, y: Int, z: Int*) = macro impl2_2_inf +}
\ No newline at end of file diff --git a/test/files/neg/t7157/Test_2.scala b/test/files/neg/t7157/Test_2.scala new file mode 100644 index 0000000000..45a6026399 --- /dev/null +++ b/test/files/neg/t7157/Test_2.scala @@ -0,0 +1,63 @@ +import Macros._ + +object Test extends App { + m1_0_0() + m1_0_0(1) + m1_0_0(1, 2) + m1_0_0(1, 2, 3) + + m1_1_1() + m1_1_1(1) + m1_1_1(1, 2) + m1_1_1(1, 2, 3) + + m1_2_2() + m1_2_2(1) + m1_2_2(1, 2) + m1_2_2(1, 2, 3) + + m1_0_inf() + m1_0_inf(1) + m1_0_inf(1, 2) + m1_0_inf(1, 2, 3) + + m1_1_inf() + m1_1_inf(1) + m1_1_inf(1, 2) + m1_1_inf(1, 2, 3) + + m1_2_inf() + m1_2_inf(1) + m1_2_inf(1, 2) + m1_2_inf(1, 2, 3) + + m2_0_0()() + m2_0_0()(1) + m2_0_0()(1, 2) + m2_0_0()(1, 2, 3) + + m2_1_1()() + m2_1_1()(1) + m2_1_1()(1, 2) + m2_1_1()(1, 2, 3) + + m2_2_2()() + m2_2_2()(1) + m2_2_2()(1, 2) + m2_2_2()(1, 2, 3) + + m2_0_inf()() + m2_0_inf()(1) + m2_0_inf()(1, 2) + m2_0_inf()(1, 2, 3) + + m2_1_inf()() + m2_1_inf()(1) + m2_1_inf()(1, 2) + m2_1_inf()(1, 2, 3) + + m2_2_inf()() + m2_2_inf()(1) + m2_2_inf()(1, 2) + m2_2_inf()(1, 2, 3) +}
\ No newline at end of file diff --git a/test/files/neg/t7473.check b/test/files/neg/t7473.check new file mode 100644 index 0000000000..bc8c29d463 --- /dev/null +++ b/test/files/neg/t7473.check @@ -0,0 +1,7 @@ +t7473.scala:6: error: '<-' expected but '=' found. + (for (x = Option(i); if x == j) yield 42) toList + ^ +t7473.scala:6: error: illegal start of simple expression + (for (x = Option(i); if x == j) yield 42) toList + ^ +two errors found diff --git a/test/files/neg/t7473.scala b/test/files/neg/t7473.scala new file mode 100644 index 0000000000..593231d5f2 --- /dev/null +++ b/test/files/neg/t7473.scala @@ -0,0 +1,7 @@ + +object Foo { + val i,j = 3 + //for (x = Option(i); if x == j) yield 42 //t7473.scala:4: error: '<-' expected but '=' found. + // evil postfix! + (for (x = Option(i); if x == j) yield 42) toList +} diff --git a/test/files/neg/t7507.check b/test/files/neg/t7507.check new file mode 100644 index 0000000000..d402869fd4 --- /dev/null +++ b/test/files/neg/t7507.check @@ -0,0 +1,4 @@ +t7507.scala:6: error: value bippy in trait Cake cannot be accessed in Cake + locally(bippy) + ^ +one error found diff --git a/test/files/neg/t7507.scala b/test/files/neg/t7507.scala new file mode 100644 index 0000000000..1b4756d955 --- /dev/null +++ b/test/files/neg/t7507.scala @@ -0,0 +1,7 @@ +trait Cake extends Slice { + private[this] val bippy = () +} + +trait Slice { self: Cake => + locally(bippy) +} diff --git a/test/files/neg/t7509.check b/test/files/neg/t7509.check new file mode 100644 index 0000000000..eaa6303cf5 --- /dev/null +++ b/test/files/neg/t7509.check @@ -0,0 +1,12 @@ +t7509.scala:3: error: inferred type arguments [Int] do not conform to method crash's type parameter bounds [R <: AnyRef] + crash(42) + ^ +t7509.scala:3: error: type mismatch; + found : Int(42) + required: R + crash(42) + ^ +t7509.scala:3: error: could not find implicit value for parameter ev: R + crash(42) + ^ +three errors found diff --git a/test/files/neg/t7509.scala b/test/files/neg/t7509.scala new file mode 100644 index 0000000000..3cba801ea7 --- /dev/null +++ b/test/files/neg/t7509.scala @@ -0,0 +1,4 @@ +object NMWE { + def crash[R <: AnyRef](f: R)(implicit ev: R): Any = ??? + crash(42) +} diff --git a/test/files/pos/lub-dealias-widen.scala b/test/files/pos/lub-dealias-widen.scala new file mode 100644 index 0000000000..38854fbc5c --- /dev/null +++ b/test/files/pos/lub-dealias-widen.scala @@ -0,0 +1,34 @@ +import scala.language.higherKinds + +sealed trait Path { + type EncodeFunc + type Route[R] = List[String] => R + + def >>(f: Route[Int]): Sitelet[EncodeFunc] = ??? +} + +case object PAny extends Path { + type EncodeFunc = List[String] => String +} + +case class PLit[Next <: Path]() extends Path { + type EncodeFunc = Next#EncodeFunc +} + +trait Sitelet[EncodeFunc] { self => + def &[G <: H, H >: EncodeFunc](that: Sitelet[G]): Sitelet[H] = ??? +} + +object Test { + val r: Sitelet[Int => (Int => String)] = ??? + + val p2: PLit[PAny.type] = ??? + val r2 /*: Sitelet[List[String] => String] */ // annotate type and it compiles with 2.10.0 + = p2 >> { (xs: List[String]) => 0 } + + // This works after https://github.com/scala/scala/commit/a06d31f6a + // Before: error: inferred type arguments [List[String] => String,List[String] => String] + // do not conform to method &'s type parameter bounds + // [G <: H,H >: Int => (Int => String)] + val s = r & r2 +}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.check b/test/files/pos/t7461.check index e69de29bb2..e69de29bb2 100644 --- a/test/files/run/macro-expand-tparams-bounds-a.check +++ b/test/files/pos/t7461.check diff --git a/test/files/pos/t7461/Macros_1.scala b/test/files/pos/t7461/Macros_1.scala new file mode 100644 index 0000000000..353dec66d7 --- /dev/null +++ b/test/files/pos/t7461/Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl(c: Context) = { + import c.universe._ + val wut = c.typeCheck(Select(Literal(Constant(10)), newTermName("$minus")), silent = true) + // println(showRaw(wut, printIds = true, printTypes = true)) + c.literalUnit + } + + def foo = macro impl +}
\ No newline at end of file diff --git a/test/files/pos/t7461/Test_2.scala b/test/files/pos/t7461/Test_2.scala new file mode 100644 index 0000000000..3839659c9a --- /dev/null +++ b/test/files/pos/t7461/Test_2.scala @@ -0,0 +1,3 @@ +class C { + def foo = Macros.foo +}
\ No newline at end of file diff --git a/test/files/pos/t7516/A_1.scala b/test/files/pos/t7516/A_1.scala new file mode 100644 index 0000000000..3bba19966d --- /dev/null +++ b/test/files/pos/t7516/A_1.scala @@ -0,0 +1,9 @@ +import scala.reflect._,macros._, scala.language.experimental.macros + +object A { + def impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] = { + val r = c.universe.reify { List(t.splice) } + c.Expr[List[T]]( c.resetLocalAttrs(r.tree) ) + } + def demo[T](t: T): List[T] = macro impl[T] +} diff --git a/test/files/pos/t7516/B_2.scala b/test/files/pos/t7516/B_2.scala new file mode 100644 index 0000000000..1b8531bc85 --- /dev/null +++ b/test/files/pos/t7516/B_2.scala @@ -0,0 +1,4 @@ +object B { + final case class CV(p: Int = 3, g: Int = 2) + A.demo { val d = 4; CV(g = d); "a" } +} diff --git a/test/files/pos/t7517.scala b/test/files/pos/t7517.scala new file mode 100644 index 0000000000..7ce4c6b13e --- /dev/null +++ b/test/files/pos/t7517.scala @@ -0,0 +1,22 @@ +trait Box[ K[A[x]] ] + +object Box { + // type constructor composition + sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] } + + // composes type constructors inside K + type SplitBox[K[A[x]], B[x]] = Box[ ({ type l[A[x]] = K[ (A ∙ B)#l] })#l ] + + def split[ K[A[x]], B[x] ](base: Box[K]): SplitBox[K,B] = ??? + + class Composed[B[_], L[A[x]] ] { + val box: Box[L] = ??? + + type Split[ A[x] ] = L[ (A ∙ B)#l ] + val a: Box[Split] = Box.split(box) + + //Either of these work: + val a1: Box[Split] = Box.split[L,B](box) + val a2: Box[ ({ type l[A[x]] = L[ (A ∙ B)#l ] })#l ] = Box.split(box) + } +}
\ No newline at end of file diff --git a/test/files/pos/t7520.scala b/test/files/pos/t7520.scala new file mode 100644 index 0000000000..747f5278e5 --- /dev/null +++ b/test/files/pos/t7520.scala @@ -0,0 +1,10 @@ +class A { + val x: Singleton with this.type = this + val y: this.type = x +} + +class B { + val x = "" + val xs: x.type with Singleton = x + val y: x.type = xs +} diff --git a/test/files/pos/t7532/A_1.java b/test/files/pos/t7532/A_1.java new file mode 100644 index 0000000000..1ade76cc70 --- /dev/null +++ b/test/files/pos/t7532/A_1.java @@ -0,0 +1,6 @@ +class R { + public class attr { // Will have the bytecode name `R$attr`, not to be confused with `R@tr`! + } + public static class attr1 { + } +} diff --git a/test/files/pos/t7532/B_2.scala b/test/files/pos/t7532/B_2.scala new file mode 100644 index 0000000000..ee7ce7751f --- /dev/null +++ b/test/files/pos/t7532/B_2.scala @@ -0,0 +1,5 @@ +object Test { + val r = new R + new r.attr() // Was: error while loading attr, class file '.../t7532-pos.obj/R$attr.class' has location not matching its contents: contains class + new R.attr1 +}
\ No newline at end of file diff --git a/test/files/pos/t7532b/A_1.scala b/test/files/pos/t7532b/A_1.scala new file mode 100644 index 0000000000..e8f9540609 --- /dev/null +++ b/test/files/pos/t7532b/A_1.scala @@ -0,0 +1,7 @@ +package pack +class R { + class attr // Will have the bytecode name `R$attr`, not to be confused with `R@tr`! + class `@` +} + +class `@`
\ No newline at end of file diff --git a/test/files/pos/t7532b/B_2.scala b/test/files/pos/t7532b/B_2.scala new file mode 100644 index 0000000000..1555a5daa7 --- /dev/null +++ b/test/files/pos/t7532b/B_2.scala @@ -0,0 +1,8 @@ +import pack._ + +object Test { + val r = new R + new r.attr() + new r.`@` + new `@` +}
\ No newline at end of file diff --git a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala index 9c1e4ee46d..56c5252f31 100644 --- a/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala +++ b/test/files/run/macro-bodyexpandstoimpl/Impls_1.scala @@ -7,6 +7,8 @@ object Impls { def refToFoo_impl(c: Ctx)(dummy: c.Expr[Int]) = { import c.universe._ val body = Select(Ident(TermName("Impls")), TermName("foo")) + val global = c.universe.asInstanceOf[scala.tools.nsc.Global] + global.analyzer.markMacroImplRef(body.asInstanceOf[global.Tree]) c.Expr[Int](body) } }
\ No newline at end of file diff --git a/test/files/run/macro-bundle.check b/test/files/run/macro-bundle.check new file mode 100644 index 0000000000..2107454960 --- /dev/null +++ b/test/files/run/macro-bundle.check @@ -0,0 +1,3 @@ +() +Int +() diff --git a/test/files/neg/macro-invalidimpl-i.flags b/test/files/run/macro-bundle.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidimpl-i.flags +++ b/test/files/run/macro-bundle.flags diff --git a/test/files/run/macro-bundle/Impls_Macros_1.scala b/test/files/run/macro-bundle/Impls_Macros_1.scala new file mode 100644 index 0000000000..3f651c9a43 --- /dev/null +++ b/test/files/run/macro-bundle/Impls_Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import scala.reflect.macros.Macro + +trait Impl extends Macro { + def mono = c.literalUnit + def poly[T: c.WeakTypeTag] = c.literal(c.weakTypeOf[T].toString) + def weird = macro mono +} + +object Macros { + def mono = macro Impl.mono + def poly[T] = macro Impl.poly[T] +}
\ No newline at end of file diff --git a/test/files/run/macro-bundle/Test_2.scala b/test/files/run/macro-bundle/Test_2.scala new file mode 100644 index 0000000000..428f809f9d --- /dev/null +++ b/test/files/run/macro-bundle/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + println(Macros.mono) + println(Macros.poly[Int]) + println(new Impl{val c = ???}.weird) +}
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.check b/test/files/run/macro-def-infer-return-type-a.check deleted file mode 100644 index f70d7bba4a..0000000000 --- a/test/files/run/macro-def-infer-return-type-a.check +++ /dev/null @@ -1 +0,0 @@ -42
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a.flags b/test/files/run/macro-def-infer-return-type-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala b/test/files/run/macro-def-infer-return-type-a/Impls_1.scala deleted file mode 100644 index 52c9f9c3e9..0000000000 --- a/test/files/run/macro-def-infer-return-type-a/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo(c: Ctx)(x: c.Expr[Int]) = x -} diff --git a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala deleted file mode 100644 index 60fe9dc1c2..0000000000 --- a/test/files/run/macro-def-infer-return-type-a/Macros_Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - def foo(x: Int) = macro Impls.foo - println(foo(42)) -}
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.flags b/test/files/run/macro-def-infer-return-type-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala b/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala deleted file mode 100644 index 8a0f18c01b..0000000000 --- a/test/files/run/macro-def-infer-return-type-b/Impls_Macros_1.scala +++ /dev/null @@ -1,10 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T](c: Ctx)(x: c.Expr[T]) = - throw new Error("an implementation is missing") -} - -object Macros { - def foo[T](x: T) = macro Impls.foo[T] -}
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala deleted file mode 100644 index 9e57b90b57..0000000000 --- a/test/files/run/macro-def-infer-return-type-b/Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test extends App { - import scala.reflect.runtime.universe._ - import scala.reflect.runtime.{currentMirror => cm} - import scala.tools.reflect.ToolBox - val tree = Apply(Select(Ident(TermName("Macros")), TermName("foo")), List(Literal(Constant(42)))) - try cm.mkToolBox().eval(tree) - catch { case ex: Throwable => println(ex.getMessage) } -} diff --git a/test/files/run/macro-def-infer-return-type-c.check b/test/files/run/macro-def-infer-return-type-c.check deleted file mode 100644 index f70d7bba4a..0000000000 --- a/test/files/run/macro-def-infer-return-type-c.check +++ /dev/null @@ -1 +0,0 @@ -42
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c.flags b/test/files/run/macro-def-infer-return-type-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-infer-return-type-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala b/test/files/run/macro-def-infer-return-type-c/Impls_1.scala deleted file mode 100644 index 78db67eebf..0000000000 --- a/test/files/run/macro-def-infer-return-type-c/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T](c: Ctx)(x: c.Expr[T]): c.Expr[T] = x -} diff --git a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala deleted file mode 100644 index 967d16f6de..0000000000 --- a/test/files/run/macro-def-infer-return-type-c/Macros_Test_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test extends App { - def foo[T](x: T) = macro Impls.foo[T] - println(foo(42)) -}
\ No newline at end of file diff --git a/test/files/run/macro-def-infer-return-type-b.check b/test/files/run/macro-def-infer-return-type.check index ae2dc7a06f..308e881960 100644 --- a/test/files/run/macro-def-infer-return-type-b.check +++ b/test/files/run/macro-def-infer-return-type.check @@ -1,6 +1,8 @@ +42 reflective compilation has failed: exception during macro expansion: java.lang.Error: an implementation is missing - at Impls$.foo(Impls_Macros_1.scala:5) + at Impls2$.foo(Impls_1.scala:9) +42 diff --git a/test/files/neg/macro-invalidret-nontree.flags b/test/files/run/macro-def-infer-return-type.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidret-nontree.flags +++ b/test/files/run/macro-def-infer-return-type.flags diff --git a/test/files/run/macro-def-infer-return-type/Impls_1.scala b/test/files/run/macro-def-infer-return-type/Impls_1.scala new file mode 100644 index 0000000000..f8636fe725 --- /dev/null +++ b/test/files/run/macro-def-infer-return-type/Impls_1.scala @@ -0,0 +1,14 @@ +import scala.reflect.macros.Context + +object Impls1 { + def foo(c: Context)(x: c.Expr[Int]) = x +} + +object Impls2 { + def foo[T](c: Context)(x: c.Expr[T]) = + throw new Error("an implementation is missing") +} + +object Impls3 { + def foo[T](c: Context)(x: c.Expr[T]): c.Expr[T] = x +} diff --git a/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala b/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala new file mode 100644 index 0000000000..f579586b7f --- /dev/null +++ b/test/files/run/macro-def-infer-return-type/Macros_Test_2.scala @@ -0,0 +1,24 @@ +object Macros1 { + def foo(x: Int) = macro Impls1.foo +} + +object Macros2 { + def foo[T](x: T) = macro Impls2.foo[T] +} + +object Macros3 { + def foo[T](x: T) = macro Impls3.foo[T] +} + +object Test extends App { + println(Macros1.foo(42)) + + import scala.reflect.runtime.universe._ + import scala.reflect.runtime.{currentMirror => cm} + import scala.tools.reflect.ToolBox + val tree = Apply(Select(Ident(TermName("Macros2")), TermName("foo")), List(Literal(Constant(42)))) + try cm.mkToolBox().eval(tree) + catch { case ex: Throwable => println(ex.getMessage) } + + println(Macros3.foo(42)) +} diff --git a/test/files/run/macro-def-path-dependent-a.flags b/test/files/run/macro-def-path-dependent-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-b.check b/test/files/run/macro-def-path-dependent-b.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-b.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-b.flags b/test/files/run/macro-def-path-dependent-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c.check b/test/files/run/macro-def-path-dependent-c.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-c.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-c.flags b/test/files/run/macro-def-path-dependent-c.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-c.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d1.check b/test/files/run/macro-def-path-dependent-d1.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-d1.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-d1.flags b/test/files/run/macro-def-path-dependent-d1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-d1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d1/Test_2.scala b/test/files/run/macro-def-path-dependent-d1/Test_2.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-d1/Test_2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -}
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2.check b/test/files/run/macro-def-path-dependent-d2.check deleted file mode 100644 index 7658ad2c24..0000000000 --- a/test/files/run/macro-def-path-dependent-d2.check +++ /dev/null @@ -1 +0,0 @@ -it works diff --git a/test/files/run/macro-def-path-dependent-d2.flags b/test/files/run/macro-def-path-dependent-d2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-def-path-dependent-d2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-d2/Test_3.scala b/test/files/run/macro-def-path-dependent-d2/Test_3.scala deleted file mode 100644 index 7dffc5107d..0000000000 --- a/test/files/run/macro-def-path-dependent-d2/Test_3.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test extends App { - println("it works") -}
\ No newline at end of file diff --git a/test/files/run/macro-declared-in-annotation.check b/test/files/run/macro-def-path-dependent.check index 7658ad2c24..7658ad2c24 100644 --- a/test/files/run/macro-declared-in-annotation.check +++ b/test/files/run/macro-def-path-dependent.check diff --git a/test/files/neg/macro-invalidret-nonuniversetree.flags b/test/files/run/macro-def-path-dependent.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidret-nonuniversetree.flags +++ b/test/files/run/macro-def-path-dependent.flags diff --git a/test/files/run/macro-def-path-dependent-a/Test_2.scala b/test/files/run/macro-def-path-dependent/Dummy.scala index 7dffc5107d..7dffc5107d 100644 --- a/test/files/run/macro-def-path-dependent-a/Test_2.scala +++ b/test/files/run/macro-def-path-dependent/Dummy.scala diff --git a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent/Test_1.scala index 3a91e41ff9..06c15e16c9 100644 --- a/test/files/run/macro-def-path-dependent-a/Impls_Macros_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_1.scala @@ -1,3 +1,5 @@ +package test1 + import scala.reflect.macros.{Context => Ctx} trait Exprs { diff --git a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent/Test_2.scala index cf9f9ebd0e..f1e9909981 100644 --- a/test/files/run/macro-def-path-dependent-b/Impls_Macros_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_2.scala @@ -1,3 +1,5 @@ +package test2 + import scala.reflect.macros.{Context => Ctx} trait Exprs { diff --git a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent/Test_3.scala index 6cb374d9ba..9f5efe5e47 100644 --- a/test/files/run/macro-def-path-dependent-c/Impls_Macros_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_3.scala @@ -1,3 +1,5 @@ +package test3 + import scala.reflect.macros.{Context => Ctx} trait Exprs { diff --git a/test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala b/test/files/run/macro-def-path-dependent/Test_4.scala index 69d9708b2a..3af920d739 100644 --- a/test/files/run/macro-def-path-dependent-d1/Impls_Macros_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_4.scala @@ -1,3 +1,5 @@ +package test4 + import scala.reflect.runtime.universe._ import scala.reflect.macros.Context import scala.reflect.api.Universe diff --git a/test/files/run/macro-def-path-dependent-d2/Impls_1.scala b/test/files/run/macro-def-path-dependent/Test_5.scala index 7fa9c3579e..bc32fb92de 100644 --- a/test/files/run/macro-def-path-dependent-d2/Impls_1.scala +++ b/test/files/run/macro-def-path-dependent/Test_5.scala @@ -1,3 +1,5 @@ +package test56 + import scala.reflect.runtime.universe._ import scala.reflect.macros.Context import scala.reflect.api.Universe diff --git a/test/files/run/macro-def-path-dependent-d2/Macros_2.scala b/test/files/run/macro-def-path-dependent/Test_6.scala index 65ce4d8bd2..6267743473 100644 --- a/test/files/run/macro-def-path-dependent-d2/Macros_2.scala +++ b/test/files/run/macro-def-path-dependent/Test_6.scala @@ -1,3 +1,5 @@ +package test56 + import scala.reflect.runtime.universe._ import scala.reflect.macros.Context import scala.reflect.api.Universe diff --git a/test/files/run/macro-expand-nullary-generic.check b/test/files/run/macro-expand-nullary-generic.check index 42976f4baf..0470d239dc 100644 --- a/test/files/run/macro-expand-nullary-generic.check +++ b/test/files/run/macro-expand-nullary-generic.check @@ -1,6 +1,6 @@ -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] -it works WeakTypeTag[Int] +fooNullary[Int] +fooEmpty[Int] +fooEmpty[Int] +barNullary[Int] +barEmpty[Int] kkthxbai diff --git a/test/files/run/macro-expand-nullary-generic/Impls_1.scala b/test/files/run/macro-expand-nullary-generic/Impls_1.scala index 39a9db0e14..5dfdd5c539 100644 --- a/test/files/run/macro-expand-nullary-generic/Impls_1.scala +++ b/test/files/run/macro-expand-nullary-generic/Impls_1.scala @@ -2,14 +2,14 @@ import scala.reflect.runtime.universe._ import scala.reflect.macros.{Context => Ctx} object Impls { - def impl[T: c.WeakTypeTag](c: Ctx) = { + def impl[T: c.WeakTypeTag](c: Ctx)(meth: String) = { import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works " + implicitly[c.WeakTypeTag[T]])))) + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(s"$meth[${c.weakTypeOf[T]}]")))) c.Expr[Unit](body) } - def fooNullary[T: c.WeakTypeTag](c: Ctx) = impl[T](c) - def fooEmpty[T: c.WeakTypeTag](c: Ctx)() = impl[T](c) - def barNullary[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c) - def barEmpty[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c) + def fooNullary[T: c.WeakTypeTag](c: Ctx) = impl[T](c)("fooNullary") + def fooEmpty[T: c.WeakTypeTag](c: Ctx)() = impl[T](c)("fooEmpty") + def barNullary[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int]) = impl[T](c)("barNullary") + def barEmpty[T: c.WeakTypeTag](c: Ctx)(x: c.Expr[Int])() = impl[T](c)("barEmpty") }
\ No newline at end of file diff --git a/test/files/run/macro-expand-nullary-nongeneric.check b/test/files/run/macro-expand-nullary-nongeneric.check index 9ab5f3a2bc..cb7e766394 100644 --- a/test/files/run/macro-expand-nullary-nongeneric.check +++ b/test/files/run/macro-expand-nullary-nongeneric.check @@ -1,6 +1,6 @@ -it works -it works -it works -it works -it works +fooNullary +fooEmpty +fooEmpty +barNullary +barEmpty kkthxbai diff --git a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala index 41e50acc86..d23c671c84 100644 --- a/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala +++ b/test/files/run/macro-expand-nullary-nongeneric/Impls_1.scala @@ -1,14 +1,15 @@ +import scala.reflect.runtime.universe._ import scala.reflect.macros.{Context => Ctx} object Impls { - def impl(c: Ctx) = { + def impl(c: Ctx)(meth: String) = { import c.universe._ - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works")))) + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(meth)))) c.Expr[Unit](body) } - def fooNullary(c: Ctx) = impl(c) - def fooEmpty(c: Ctx)() = impl(c) - def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c) - def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c) + def fooNullary(c: Ctx) = impl(c)("fooNullary") + def fooEmpty(c: Ctx)() = impl(c)("fooEmpty") + def barNullary(c: Ctx)(x: c.Expr[Int]) = impl(c)("barNullary") + def barEmpty(c: Ctx)(x: c.Expr[Int])() = impl(c)("barEmpty") }
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a.flags b/test/files/run/macro-expand-tparams-bounds-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala deleted file mode 100644 index b498e6f65b..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-a/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo[U <: String] = macro Impls.foo[U] -} - -object Test extends App { - import Macros._ - foo[String] -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.flags b/test/files/run/macro-expand-tparams-bounds-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala deleted file mode 100644 index c11c89151c..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b/Impls_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -class C - -object Impls { - def foo[U <: C](c: Ctx): c.Expr[Unit] = c.literalUnit -} diff --git a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala deleted file mode 100644 index 1a261e9f73..0000000000 --- a/test/files/run/macro-expand-tparams-bounds-b/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -class D extends C - -object Macros { - def foo[T <: D] = macro Impls.foo[T] -} - -object Test extends App { - import Macros._ - foo[D] -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-bounds-b.check b/test/files/run/macro-expand-tparams-bounds.check index e69de29bb2..e69de29bb2 100644 --- a/test/files/run/macro-expand-tparams-bounds-b.check +++ b/test/files/run/macro-expand-tparams-bounds.check diff --git a/test/files/neg/macro-invalidshape-a.flags b/test/files/run/macro-expand-tparams-bounds.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-a.flags +++ b/test/files/run/macro-expand-tparams-bounds.flags diff --git a/test/files/run/macro-expand-tparams-bounds/Impls_1.scala b/test/files/run/macro-expand-tparams-bounds/Impls_1.scala new file mode 100644 index 0000000000..f9103aaf8f --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds/Impls_1.scala @@ -0,0 +1,12 @@ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U <: String](c: Context): c.Expr[Unit] = c.literalUnit +} + +class C +class D extends C + +object Impls2 { + def foo[U <: C](c: Context): c.Expr[Unit] = c.literalUnit +} diff --git a/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala new file mode 100644 index 0000000000..37a4bcb2b9 --- /dev/null +++ b/test/files/run/macro-expand-tparams-bounds/Macros_Test_2.scala @@ -0,0 +1,12 @@ +object Macros1 { + def foo[U <: String] = macro Impls1.foo[U] +} + +object Macros2 { + def foo[T <: D] = macro Impls2.foo[T] +} + +object Test extends App { + Macros1.foo[String] + Macros2.foo[D] +} diff --git a/test/files/run/macro-expand-tparams-only-in-impl.flags b/test/files/run/macro-expand-tparams-only-in-impl.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala b/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala deleted file mode 100644 index 9b8dafaa97..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl/Impls_1.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U <: String](c: Ctx): c.Expr[Unit] = c.literalUnit -} diff --git a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala deleted file mode 100644 index 218c7aec7f..0000000000 --- a/test/files/run/macro-expand-tparams-only-in-impl/Macros_Test_2.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Macros { - def foo = macro Impls.foo[String] -} - -object Test extends App { - import Macros._ - foo -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-optional.flags b/test/files/run/macro-expand-tparams-optional.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-optional.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a.check b/test/files/run/macro-expand-tparams-prefix-a.check deleted file mode 100644 index ca44a4f652..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a.check +++ /dev/null @@ -1,4 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-a.flags b/test/files/run/macro-expand-tparams-prefix-a.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala deleted file mode 100644 index c729aada51..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a/Impls_1.scala +++ /dev/null @@ -1,11 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[U: c.WeakTypeTag](c: Ctx)(x: c.Expr[U]) = { - import c.universe._ - val U = implicitly[c.WeakTypeTag[U]] - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(U.toString)))) - c.Expr[Unit](body) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala deleted file mode 100644 index 81ccb7ff42..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-a/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test extends App { - class C[T] { - def foo[U](x: U) = macro Impls.foo[U] - } - - new C[Int]().foo(42) - new C[Boolean]().foo(42) - new C[Int]().foo("42") - new C[String]().foo(true) -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b.check b/test/files/run/macro-expand-tparams-prefix-b.check deleted file mode 100644 index 2ff2ce435d..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b.check +++ /dev/null @@ -1,2 +0,0 @@ -WeakTypeTag[Boolean] WeakTypeTag[Int] -WeakTypeTag[Boolean] WeakTypeTag[String] diff --git a/test/files/run/macro-expand-tparams-prefix-b.flags b/test/files/run/macro-expand-tparams-prefix-b.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala deleted file mode 100644 index 8880d13b04..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b/Impls_1.scala +++ /dev/null @@ -1,12 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Ctx)(x: c.Expr[U]) = { - import c.universe._ - val T = implicitly[c.WeakTypeTag[T]] - val U = implicitly[c.WeakTypeTag[U]] - val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) - c.Expr[Unit](body) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala deleted file mode 100644 index a4a0acfe8b..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-b/Macros_Test_2.scala +++ /dev/null @@ -1,10 +0,0 @@ -object Test extends App { - class C[T] { - def foo[U](x: U) = macro Impls.foo[T, U] - } - - object D extends C[Boolean] - - D.foo(42) - D.foo("42") -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1.check b/test/files/run/macro-expand-tparams-prefix-c1.check deleted file mode 100644 index 0f24f74db1..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c1.flags b/test/files/run/macro-expand-tparams-prefix-c1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala deleted file mode 100644 index 2df42e969f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1/Impls_1.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala deleted file mode 100644 index 4fa0c8cb33..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c1/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - } -} - -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2.check b/test/files/run/macro-expand-tparams-prefix-c2.check deleted file mode 100644 index 0f24f74db1..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[Int] -WeakTypeTag[String] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-c2.flags b/test/files/run/macro-expand-tparams-prefix-c2.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala b/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala deleted file mode 100644 index 08817708d4..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2/Impls_Macros_1.scala +++ /dev/null @@ -1,19 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -} - -class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala b/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala deleted file mode 100644 index e729d4a536..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-c2/Test_2.scala +++ /dev/null @@ -1,5 +0,0 @@ -object Test extends App { - val outer1 = new D[Int] - val outer2 = new outer1.C[String] - outer2.foo[Boolean] -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1.check b/test/files/run/macro-expand-tparams-prefix-d1.check deleted file mode 100644 index 7832503256..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1.check +++ /dev/null @@ -1,3 +0,0 @@ -WeakTypeTag[T] -WeakTypeTag[U] -WeakTypeTag[Boolean] diff --git a/test/files/run/macro-expand-tparams-prefix-d1.flags b/test/files/run/macro-expand-tparams-prefix-d1.flags deleted file mode 100644 index cd66464f2f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1.flags +++ /dev/null @@ -1 +0,0 @@ --language:experimental.macros
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala deleted file mode 100644 index 2df42e969f..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1/Impls_1.scala +++ /dev/null @@ -1,13 +0,0 @@ -import scala.reflect.runtime.universe._ -import scala.reflect.macros.{Context => Ctx} - -object Impls { - def foo[T, U: c.WeakTypeTag, V](c: Ctx)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { - import c.universe._ - c.Expr(Block(List( - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), - Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), - Literal(Constant(())))) - } -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala deleted file mode 100644 index 8222a6d1e8..0000000000 --- a/test/files/run/macro-expand-tparams-prefix-d1/Macros_Test_2.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Test extends App { - class D[T] { - class C[U] { - def foo[V] = macro Impls.foo[T, U, V] - foo[Boolean] - } - } - - val outer1 = new D[Int] - new outer1.C[String] -}
\ No newline at end of file diff --git a/test/files/run/macro-expand-tparams-prefix.check b/test/files/run/macro-expand-tparams-prefix.check new file mode 100644 index 0000000000..7397958066 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix.check @@ -0,0 +1,20 @@ +===Macros1=== +WeakTypeTag[Int] +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros2=== +WeakTypeTag[Boolean] WeakTypeTag[Int] +WeakTypeTag[Boolean] WeakTypeTag[String] +===Macros3=== +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros4=== +WeakTypeTag[Int] +WeakTypeTag[String] +WeakTypeTag[Boolean] +===Macros5=== +WeakTypeTag[T] +WeakTypeTag[U] +WeakTypeTag[Boolean] diff --git a/test/files/neg/macro-invalidshape-b.flags b/test/files/run/macro-expand-tparams-prefix.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-b.flags +++ b/test/files/run/macro-expand-tparams-prefix.flags diff --git a/test/files/run/macro-expand-tparams-prefix/Impls_1.scala b/test/files/run/macro-expand-tparams-prefix/Impls_1.scala new file mode 100644 index 0000000000..e92396d1b4 --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix/Impls_1.scala @@ -0,0 +1,40 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.macros.Context + +object Impls1 { + def foo[U: c.WeakTypeTag](c: Context)(x: c.Expr[U]) = { + import c.universe._ + val U = implicitly[c.WeakTypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(U.toString)))) + c.Expr[Unit](body) + } +} + +object Impls2 { + def foo[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(x: c.Expr[U]) = { + import c.universe._ + val T = implicitly[c.WeakTypeTag[T]] + val U = implicitly[c.WeakTypeTag[U]] + val body = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString + " " + U.toString)))) + c.Expr[Unit](body) + } +} + +object Impls345 { + def foo[T, U: c.WeakTypeTag, V](c: Context)(implicit T: c.WeakTypeTag[T], V: c.WeakTypeTag[V]): c.Expr[Unit] = { + import c.universe._ + c.Expr(Block(List( + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(T.toString)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(implicitly[c.WeakTypeTag[U]].toString)))), + Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant(V.toString))))), + Literal(Constant(())))) + } +} + +object Macros4 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + } + } +} diff --git a/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala new file mode 100644 index 0000000000..2b1730d36e --- /dev/null +++ b/test/files/run/macro-expand-tparams-prefix/Macros_Test_2.scala @@ -0,0 +1,57 @@ +object Macros1 { + class C[T] { + def foo[U](x: U) = macro Impls1.foo[U] + } +} + +object Macros2 { + class C[T] { + def foo[U](x: U) = macro Impls2.foo[T, U] + } +} + +object Macros3 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + } + } +} + +// object Macros4 is declared in Impls_1.scala + +object Macros5 { + class D[T] { + class C[U] { + def foo[V] = macro Impls345.foo[T, U, V] + foo[Boolean] + } + } +} + +object Test extends App { + println("===Macros1===") + new Macros1.C[Int]().foo(42) + new Macros1.C[Boolean]().foo(42) + new Macros1.C[Int]().foo("42") + new Macros1.C[String]().foo(true) + + println("===Macros2===") + object D2 extends Macros2.C[Boolean] + D2.foo(42) + D2.foo("42") + + println("===Macros3===") + val outer31 = new Macros3.D[Int] + val outer32 = new outer31.C[String] + outer32.foo[Boolean] + + println("===Macros4===") + val outer41 = new Macros4.D[Int] + val outer42 = new outer41.C[String] + outer42.foo[Boolean] + + println("===Macros5===") + val outer1 = new Macros5.D[Int] + new outer1.C[String] +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidshape-c.flags b/test/files/run/macro-impl-tparam-only-in-impl.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidshape-c.flags +++ b/test/files/run/macro-impl-tparam-only-in-impl.flags diff --git a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala b/test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala index 9b8dafaa97..9b8dafaa97 100644 --- a/test/files/run/macro-expand-tparams-bounds-a/Impls_1.scala +++ b/test/files/run/macro-impl-tparam-only-in-impl/Impls_1.scala diff --git a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala index 218c7aec7f..218c7aec7f 100644 --- a/test/files/neg/macro-invalidimpl-h/Macros_Test_2.scala +++ b/test/files/run/macro-impl-tparam-only-in-impl/Macros_Test_2.scala diff --git a/test/files/run/macro-expand-tparams-optional.check b/test/files/run/macro-impl-tparam-typetag-is-optional.check index b4a0f394c1..b4a0f394c1 100644 --- a/test/files/run/macro-expand-tparams-optional.check +++ b/test/files/run/macro-impl-tparam-typetag-is-optional.check diff --git a/test/files/neg/macro-invalidusage-badbounds-a.flags b/test/files/run/macro-impl-tparam-typetag-is-optional.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/neg/macro-invalidusage-badbounds-a.flags +++ b/test/files/run/macro-impl-tparam-typetag-is-optional.flags diff --git a/test/files/run/macro-expand-tparams-optional/Impls_1.scala b/test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala index ace7a6cd26..ace7a6cd26 100644 --- a/test/files/run/macro-expand-tparams-optional/Impls_1.scala +++ b/test/files/run/macro-impl-tparam-typetag-is-optional/Impls_1.scala diff --git a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala index e72c27881a..e72c27881a 100644 --- a/test/files/run/macro-expand-tparams-optional/Macros_Test_2.scala +++ b/test/files/run/macro-impl-tparam-typetag-is-optional/Macros_Test_2.scala diff --git a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check index f1d5e925fa..326f3e08ca 100644 --- a/test/files/run/macro-invalidusage-partialapplication-with-tparams.check +++ b/test/files/run/macro-invalidusage-partialapplication-with-tparams.check @@ -1,3 +1,3 @@ reflective compilation has failed: -macros cannot be partially applied +too few argument lists for macro invocation diff --git a/test/files/run/macro-invalidusage-partialapplication.check b/test/files/run/macro-invalidusage-partialapplication.check index f1d5e925fa..326f3e08ca 100644 --- a/test/files/run/macro-invalidusage-partialapplication.check +++ b/test/files/run/macro-invalidusage-partialapplication.check @@ -1,3 +1,3 @@ reflective compilation has failed: -macros cannot be partially applied +too few argument lists for macro invocation diff --git a/test/files/run/macro-def-path-dependent-a.check b/test/files/run/macro-term-declared-in-annotation.check index 7658ad2c24..7658ad2c24 100644 --- a/test/files/run/macro-def-path-dependent-a.check +++ b/test/files/run/macro-term-declared-in-annotation.check diff --git a/test/files/run/macro-declared-in-annotation.flags b/test/files/run/macro-term-declared-in-annotation.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-annotation.flags +++ b/test/files/run/macro-term-declared-in-annotation.flags diff --git a/test/files/run/macro-declared-in-annotation/Impls_1.scala b/test/files/run/macro-term-declared-in-annotation/Impls_1.scala index 1ea06de679..1ea06de679 100644 --- a/test/files/run/macro-declared-in-annotation/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-annotation/Impls_1.scala diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-term-declared-in-annotation/Macros_2.scala index 40d71c62fb..40d71c62fb 100644 --- a/test/files/run/macro-declared-in-annotation/Macros_2.scala +++ b/test/files/run/macro-term-declared-in-annotation/Macros_2.scala diff --git a/test/files/run/macro-declared-in-annotation/Test_3.scala b/test/files/run/macro-term-declared-in-annotation/Test_3.scala index 866487f028..866487f028 100644 --- a/test/files/run/macro-declared-in-annotation/Test_3.scala +++ b/test/files/run/macro-term-declared-in-annotation/Test_3.scala diff --git a/test/files/run/macro-declared-in-anonymous.check b/test/files/run/macro-term-declared-in-anonymous.check index 09b8d015a6..09b8d015a6 100644 --- a/test/files/run/macro-declared-in-anonymous.check +++ b/test/files/run/macro-term-declared-in-anonymous.check diff --git a/test/files/run/macro-declared-in-anonymous.flags b/test/files/run/macro-term-declared-in-anonymous.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-anonymous.flags +++ b/test/files/run/macro-term-declared-in-anonymous.flags diff --git a/test/files/run/macro-declared-in-anonymous/Impls_1.scala b/test/files/run/macro-term-declared-in-anonymous/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-anonymous/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-anonymous/Impls_1.scala diff --git a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala index 88cd29ae4f..88cd29ae4f 100644 --- a/test/files/run/macro-declared-in-anonymous/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-anonymous/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-block.check b/test/files/run/macro-term-declared-in-block.check index 5e687db8bf..5e687db8bf 100644 --- a/test/files/run/macro-declared-in-block.check +++ b/test/files/run/macro-term-declared-in-block.check diff --git a/test/files/run/macro-declared-in-block.flags b/test/files/run/macro-term-declared-in-block.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-block.flags +++ b/test/files/run/macro-term-declared-in-block.flags diff --git a/test/files/run/macro-declared-in-block/Impls_1.scala b/test/files/run/macro-term-declared-in-block/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-block/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-block/Impls_1.scala diff --git a/test/files/run/macro-declared-in-block/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala index 69088e24bc..69088e24bc 100644 --- a/test/files/run/macro-declared-in-block/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-block/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-class-class.check b/test/files/run/macro-term-declared-in-class-class.check index 47248d7af7..47248d7af7 100644 --- a/test/files/run/macro-declared-in-class-class.check +++ b/test/files/run/macro-term-declared-in-class-class.check diff --git a/test/files/run/macro-declared-in-class-class.flags b/test/files/run/macro-term-declared-in-class-class.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class-class.flags +++ b/test/files/run/macro-term-declared-in-class-class.flags diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-term-declared-in-class-class/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-class-class/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-class-class/Impls_1.scala diff --git a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala index 871857a97f..871857a97f 100644 --- a/test/files/run/macro-declared-in-class-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class-class/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-class-object.check b/test/files/run/macro-term-declared-in-class-object.check index 35af59e40f..35af59e40f 100644 --- a/test/files/run/macro-declared-in-class-object.check +++ b/test/files/run/macro-term-declared-in-class-object.check diff --git a/test/files/run/macro-declared-in-class-object.flags b/test/files/run/macro-term-declared-in-class-object.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class-object.flags +++ b/test/files/run/macro-term-declared-in-class-object.flags diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-term-declared-in-class-object/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-class-object/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-class-object/Impls_1.scala diff --git a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala index 994f9fe935..994f9fe935 100644 --- a/test/files/run/macro-declared-in-class-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class-object/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-class.check b/test/files/run/macro-term-declared-in-class.check index a1c1d7af8b..a1c1d7af8b 100644 --- a/test/files/run/macro-declared-in-class.check +++ b/test/files/run/macro-term-declared-in-class.check diff --git a/test/files/run/macro-declared-in-class.flags b/test/files/run/macro-term-declared-in-class.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-class.flags +++ b/test/files/run/macro-term-declared-in-class.flags diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-term-declared-in-class/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-class/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-class/Impls_1.scala diff --git a/test/files/run/macro-declared-in-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala index 1b9d13e775..1b9d13e775 100644 --- a/test/files/run/macro-declared-in-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-class/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-default-param.check b/test/files/run/macro-term-declared-in-default-param.check index 6decd7aa4d..6decd7aa4d 100644 --- a/test/files/run/macro-declared-in-default-param.check +++ b/test/files/run/macro-term-declared-in-default-param.check diff --git a/test/files/run/macro-declared-in-default-param.flags b/test/files/run/macro-term-declared-in-default-param.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-default-param.flags +++ b/test/files/run/macro-term-declared-in-default-param.flags diff --git a/test/files/run/macro-declared-in-default-param/Impls_1.scala b/test/files/run/macro-term-declared-in-default-param/Impls_1.scala index 4380f40b04..4380f40b04 100644 --- a/test/files/run/macro-declared-in-default-param/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-default-param/Impls_1.scala diff --git a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala index 356029e63e..356029e63e 100644 --- a/test/files/run/macro-declared-in-default-param/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-default-param/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-implicit-class.check b/test/files/run/macro-term-declared-in-implicit-class.check index 5dc968c08c..5dc968c08c 100644 --- a/test/files/run/macro-declared-in-implicit-class.check +++ b/test/files/run/macro-term-declared-in-implicit-class.check diff --git a/test/files/run/macro-declared-in-implicit-class.flags b/test/files/run/macro-term-declared-in-implicit-class.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-implicit-class.flags +++ b/test/files/run/macro-term-declared-in-implicit-class.flags diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala index 4c009cc367..4c009cc367 100644 --- a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala +++ b/test/files/run/macro-term-declared-in-implicit-class/Impls_Macros_1.scala diff --git a/test/files/run/macro-declared-in-implicit-class/Test_2.scala b/test/files/run/macro-term-declared-in-implicit-class/Test_2.scala index d0bc9cc38c..d0bc9cc38c 100644 --- a/test/files/run/macro-declared-in-implicit-class/Test_2.scala +++ b/test/files/run/macro-term-declared-in-implicit-class/Test_2.scala diff --git a/test/files/run/macro-declared-in-method.check b/test/files/run/macro-term-declared-in-method.check index 5e687db8bf..5e687db8bf 100644 --- a/test/files/run/macro-declared-in-method.check +++ b/test/files/run/macro-term-declared-in-method.check diff --git a/test/files/run/macro-declared-in-method.flags b/test/files/run/macro-term-declared-in-method.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-method.flags +++ b/test/files/run/macro-term-declared-in-method.flags diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-term-declared-in-method/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-method/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-method/Impls_1.scala diff --git a/test/files/run/macro-declared-in-method/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala index ed5c8b7c43..ed5c8b7c43 100644 --- a/test/files/run/macro-declared-in-method/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-method/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-object-class.check b/test/files/run/macro-term-declared-in-object-class.check index 47248d7af7..47248d7af7 100644 --- a/test/files/run/macro-declared-in-object-class.check +++ b/test/files/run/macro-term-declared-in-object-class.check diff --git a/test/files/run/macro-declared-in-object-class.flags b/test/files/run/macro-term-declared-in-object-class.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object-class.flags +++ b/test/files/run/macro-term-declared-in-object-class.flags diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-term-declared-in-object-class/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-object-class/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-object-class/Impls_1.scala diff --git a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala index 204deed61c..204deed61c 100644 --- a/test/files/run/macro-declared-in-object-class/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object-class/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-object-object.check b/test/files/run/macro-term-declared-in-object-object.check index 35af59e40f..35af59e40f 100644 --- a/test/files/run/macro-declared-in-object-object.check +++ b/test/files/run/macro-term-declared-in-object-object.check diff --git a/test/files/run/macro-declared-in-object-object.flags b/test/files/run/macro-term-declared-in-object-object.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object-object.flags +++ b/test/files/run/macro-term-declared-in-object-object.flags diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-term-declared-in-object-object/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-object-object/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-object-object/Impls_1.scala diff --git a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala index e261a50f3d..e261a50f3d 100644 --- a/test/files/run/macro-declared-in-object-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object-object/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-object.check b/test/files/run/macro-term-declared-in-object.check index 4d955a96b1..4d955a96b1 100644 --- a/test/files/run/macro-declared-in-object.check +++ b/test/files/run/macro-term-declared-in-object.check diff --git a/test/files/run/macro-declared-in-object.flags b/test/files/run/macro-term-declared-in-object.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-object.flags +++ b/test/files/run/macro-term-declared-in-object.flags diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-term-declared-in-object/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-object/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-object/Impls_1.scala diff --git a/test/files/run/macro-declared-in-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala index a5a4862ba0..a5a4862ba0 100644 --- a/test/files/run/macro-declared-in-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-object/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-package-object.check b/test/files/run/macro-term-declared-in-package-object.check index bc0069178d..bc0069178d 100644 --- a/test/files/run/macro-declared-in-package-object.check +++ b/test/files/run/macro-term-declared-in-package-object.check diff --git a/test/files/run/macro-declared-in-package-object.flags b/test/files/run/macro-term-declared-in-package-object.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-package-object.flags +++ b/test/files/run/macro-term-declared-in-package-object.flags diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-term-declared-in-package-object/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-package-object/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-package-object/Impls_1.scala diff --git a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala index 54a5962e80..54a5962e80 100644 --- a/test/files/run/macro-declared-in-package-object/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-package-object/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-refinement.check b/test/files/run/macro-term-declared-in-refinement.check index 09b8d015a6..09b8d015a6 100644 --- a/test/files/run/macro-declared-in-refinement.check +++ b/test/files/run/macro-term-declared-in-refinement.check diff --git a/test/files/run/macro-declared-in-refinement.flags b/test/files/run/macro-term-declared-in-refinement.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-refinement.flags +++ b/test/files/run/macro-term-declared-in-refinement.flags diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-term-declared-in-refinement/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-refinement/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-refinement/Impls_1.scala diff --git a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala index ff9a66d58a..ff9a66d58a 100644 --- a/test/files/run/macro-declared-in-refinement/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-refinement/Macros_Test_2.scala diff --git a/test/files/run/macro-declared-in-trait.check b/test/files/run/macro-term-declared-in-trait.check index 0d70ac74f3..0d70ac74f3 100644 --- a/test/files/run/macro-declared-in-trait.check +++ b/test/files/run/macro-term-declared-in-trait.check diff --git a/test/files/run/macro-declared-in-trait.flags b/test/files/run/macro-term-declared-in-trait.flags index cd66464f2f..cd66464f2f 100644 --- a/test/files/run/macro-declared-in-trait.flags +++ b/test/files/run/macro-term-declared-in-trait.flags diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-term-declared-in-trait/Impls_1.scala index 348f3420f2..348f3420f2 100644 --- a/test/files/run/macro-declared-in-trait/Impls_1.scala +++ b/test/files/run/macro-term-declared-in-trait/Impls_1.scala diff --git a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala index f75906b636..f75906b636 100644 --- a/test/files/run/macro-declared-in-trait/Macros_Test_2.scala +++ b/test/files/run/macro-term-declared-in-trait/Macros_Test_2.scala diff --git a/test/files/run/macro-toplevel-companion-b/Test_2.scala b/test/files/run/macro-toplevel-companion-b/Test_2.scala index ca202d053f..4e766bde89 100644 --- a/test/files/run/macro-toplevel-companion-b/Test_2.scala +++ b/test/files/run/macro-toplevel-companion-b/Test_2.scala @@ -7,5 +7,5 @@ import Macros._ object Test extends App { val tb = cm.mkToolBox() try tb.compile(Select(Ident(TermName("Macros")), TermName("foo"))) - catch { case ToolBoxError(message, _) => println("""macroSynthetic-.*?\.scala""".r.replaceAllIn(message, "<synthetic file name>")) } + catch { case ToolBoxError(message, _) => println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(message, m => m.group(1) + " <synthetic file name>")) } }
\ No newline at end of file diff --git a/test/files/run/macro-toplevel-companion-c.scala b/test/files/run/macro-toplevel-companion-c.scala index 0e99903158..c315f8b942 100644 --- a/test/files/run/macro-toplevel-companion-c.scala +++ b/test/files/run/macro-toplevel-companion-c.scala @@ -45,7 +45,7 @@ object Test extends DirectTest { log("Compiling Test_2...") if (compileTest()) log("Success!") else log("Failed...") } - println("""macroSynthetic-.*?\.scala""".r.replaceAllIn(baos.toString, "<synthetic file name>")) + println("""(Found in|and) .*?compileLateSynthetic-.*?\.scala""".r.replaceAllIn(baos.toString, m => m.group(1) + " <synthetic file name>")) System.setErr(prevErr) } }
\ No newline at end of file diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check index 1b0f3f2162..18cfd5a7ef 100644 --- a/test/files/run/reify-repl-fail-gracefully.check +++ b/test/files/run/reify-repl-fail-gracefully.check @@ -12,7 +12,7 @@ import scala.reflect.runtime.universe._ scala> scala> reify -<console>:12: error: macros cannot be partially applied +<console>:12: error: too few argument lists for macro invocation reify ^ diff --git a/test/files/run/repl-term-macros.check b/test/files/run/repl-term-macros.check new file mode 100644 index 0000000000..eae489c294 --- /dev/null +++ b/test/files/run/repl-term-macros.check @@ -0,0 +1,44 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import scala.reflect.macros.Context +import scala.reflect.macros.Context + +scala> import language.experimental.macros +import language.experimental.macros + +scala> + +scala> def impl1(c: Context) = c.literalUnit +impl1: (c: scala.reflect.macros.Context)c.Expr[Unit] + +scala> def foo1 = macro impl1 +defined term macro foo1: Unit + +scala> foo1 + +scala> + +scala> def impl2(c: Context)() = c.literalUnit +impl2: (c: scala.reflect.macros.Context)()c.Expr[Unit] + +scala> def foo2() = macro impl2 +defined term macro foo2: ()Unit + +scala> foo2() + +scala> + +scala> def impl3(c: Context)(x: c.Expr[Int])(y: c.Expr[Int]) = c.literalUnit +impl3: (c: scala.reflect.macros.Context)(x: c.Expr[Int])(y: c.Expr[Int])c.Expr[Unit] + +scala> def foo3(x: Int)(y: Int) = macro impl3 +defined term macro foo3: (x: Int)(y: Int)Unit + +scala> foo3(2)(3) + +scala> + +scala> diff --git a/test/files/run/repl-term-macros.scala b/test/files/run/repl-term-macros.scala new file mode 100644 index 0000000000..f826259be9 --- /dev/null +++ b/test/files/run/repl-term-macros.scala @@ -0,0 +1,20 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + import scala.reflect.macros.Context +import language.experimental.macros + +def impl1(c: Context) = c.literalUnit +def foo1 = macro impl1 +foo1 + +def impl2(c: Context)() = c.literalUnit +def foo2() = macro impl2 +foo2() + +def impl3(c: Context)(x: c.Expr[Int])(y: c.Expr[Int]) = c.literalUnit +def foo3(x: Int)(y: Int) = macro impl3 +foo3(2)(3) + """ +}
\ No newline at end of file diff --git a/test/files/run/t6039.scala b/test/files/run/t6039.scala deleted file mode 100644 index 9d811b0634..0000000000 --- a/test/files/run/t6039.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.tools.partest._ - -object Test extends StoreReporterDirectTest { - private def compileCode(): Boolean = { - new java.io.File("util") mkdirs - val classpath = List(sys.props("partest.lib"), ".") mkString sys.props("path.separator") - log(s"classpath = $classpath") - compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(packageCode) - } - def code = ??? - def packageCode = """ -package scala.bippy -class A { new util.Random() } -""" - def show(): Unit = { - assert(compileCode(), filteredInfos take 1 mkString "") - } -} diff --git a/test/files/run/t6309.check b/test/files/run/t6309.check new file mode 100644 index 0000000000..7f8f011eb7 --- /dev/null +++ b/test/files/run/t6309.check @@ -0,0 +1 @@ +7 diff --git a/test/files/run/t6309.scala b/test/files/run/t6309.scala new file mode 100644 index 0000000000..7bbca63c2a --- /dev/null +++ b/test/files/run/t6309.scala @@ -0,0 +1,16 @@ +trait A { + def a: Int +} + +object Test { + def f(a: Int) = new { + //private val b = a + private[this] val b = a // crashes, sorry scalac + } with A { + def a = b + } + + def main(args: Array[String]) { + println(f(7).a) + } +} diff --git a/test/files/run/t7088.check b/test/files/run/t7088.check new file mode 100644 index 0000000000..1191247b6d --- /dev/null +++ b/test/files/run/t7088.check @@ -0,0 +1,2 @@ +1 +2 diff --git a/test/files/run/t7088.scala b/test/files/run/t7088.scala new file mode 100644 index 0000000000..5f0114b940 --- /dev/null +++ b/test/files/run/t7088.scala @@ -0,0 +1,13 @@ +object Test { + type Tag[X] = {type Tag = X} + type TaggedArray[T] = Array[T] with Tag[Any] + + def method[T: scala.reflect.ClassTag](a: TaggedArray[T], value: T) { + a.update(0, value) + a foreach println + } + + def main(args: Array[String]): Unit = { + method(Array(1, 2).asInstanceOf[TaggedArray[Int]], 1) + } +} diff --git a/test/files/run/t7157.check b/test/files/run/t7157.check new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/files/run/t7157.check @@ -0,0 +1 @@ +1 diff --git a/test/files/run/t7157/Impls_Macros_1.scala b/test/files/run/t7157/Impls_Macros_1.scala new file mode 100644 index 0000000000..ad3d96eb85 --- /dev/null +++ b/test/files/run/t7157/Impls_Macros_1.scala @@ -0,0 +1,15 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + object AImpl { + def a(ctx: Context)(args: ctx.Expr[Any]*): ctx.Expr[Unit] = { + import ctx.universe._ + ctx.Expr[Unit](Apply(Ident(TermName("println")), List(Literal(Constant(1))))) + } + } + + implicit class A(context: StringContext) { + def a(args: Any*): Unit = macro AImpl.a + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-invalidimpl-c/Test_2.scala b/test/files/run/t7157/Test_2.scala index e75a8ba101..cceb5ca177 100644 --- a/test/files/neg/macro-invalidimpl-c/Test_2.scala +++ b/test/files/run/t7157/Test_2.scala @@ -1,3 +1,5 @@ +import Macros._ + object Test extends App { - new Macros().foo(42) + a"" }
\ No newline at end of file diff --git a/test/files/run/t7375a.check b/test/files/run/t7375a.check new file mode 100644 index 0000000000..a0a15dfb2f --- /dev/null +++ b/test/files/run/t7375a.check @@ -0,0 +1,4 @@ +C1 +C2 +C1 +C2 diff --git a/test/files/run/t7375a.scala b/test/files/run/t7375a.scala new file mode 100644 index 0000000000..e46ad08f63 --- /dev/null +++ b/test/files/run/t7375a.scala @@ -0,0 +1,16 @@ +import scala.reflect.ClassTag + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Test { + type F1 = C1 + type F2 = C2 + + def main(args: Array[String]): Unit = { + println(implicitly[ClassTag[C1]]) + println(implicitly[ClassTag[C2]]) + println(implicitly[ClassTag[F1]]) + println(implicitly[ClassTag[F2]]) + } +} diff --git a/test/files/run/t7375b.check b/test/files/run/t7375b.check new file mode 100644 index 0000000000..d7578e28ba --- /dev/null +++ b/test/files/run/t7375b.check @@ -0,0 +1,4 @@ +Predef.this.classOf[C1] +Predef.this.classOf[C2] +Predef.this.classOf[C1] +Predef.this.classOf[C2] diff --git a/test/files/run/t7375b/Macros_1.scala b/test/files/run/t7375b/Macros_1.scala new file mode 100644 index 0000000000..70e79cc2b4 --- /dev/null +++ b/test/files/run/t7375b/Macros_1.scala @@ -0,0 +1,18 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Macros { + type F1 = C1 + type F2 = C2 + + def foo = macro impl + def impl(c: Context) = { + import c.universe._ + def test[T: c.TypeTag] = reify(println(c.literal(c.reifyRuntimeClass(c.typeOf[T]).toString).splice)).tree + def tests = Block(List(test[C1], test[C2], test[F1], test[F2]), Literal(Constant(()))) + c.Expr[Unit](tests) + } +}
\ No newline at end of file diff --git a/test/files/run/macro-def-path-dependent-c/Test_2.scala b/test/files/run/t7375b/Test_2.scala index 7dffc5107d..acfddae942 100644 --- a/test/files/run/macro-def-path-dependent-c/Test_2.scala +++ b/test/files/run/t7375b/Test_2.scala @@ -1,3 +1,3 @@ object Test extends App { - println("it works") + Macros.foo }
\ No newline at end of file diff --git a/test/files/run/t7507.scala b/test/files/run/t7507.scala new file mode 100644 index 0000000000..6c1959ddac --- /dev/null +++ b/test/files/run/t7507.scala @@ -0,0 +1,31 @@ +trait Cake extends Slice + +// Minimization +trait Slice { self: Cake => // must have self type that extends `Slice` + private[this] val bippy = () // must be private[this] + locally(bippy) +} + +// Originally reported bug: +trait Cake1 extends Slice1 +trait Slice1 { self: Cake1 => + import java.lang.String // any import will do! + val Tuple2(x, y) = ((1, 2)) +} + + +// Nesting +trait Cake3 extends Outer.Slice3 + +// Minimization +object Outer { + private[this] val bippy = () + trait Slice3 { self: Cake3 => + locally(bippy) + } +} + +object Test extends App { + val s1 = new Cake1 {} + assert((s1.x, s1.y) == (1, 2), (s1.x, s1.y)) +} diff --git a/test/files/neg/t7441.check b/test/pending/neg/t7441.check index f259457197..f259457197 100644 --- a/test/files/neg/t7441.check +++ b/test/pending/neg/t7441.check diff --git a/test/files/neg/t7441.scala b/test/pending/neg/t7441.scala index dad7421e3f..dad7421e3f 100644 --- a/test/files/neg/t7441.scala +++ b/test/pending/neg/t7441.scala diff --git a/test/files/pos/t7234.scala b/test/pending/pos/t7234.scala index 59a233d835..59a233d835 100644 --- a/test/files/pos/t7234.scala +++ b/test/pending/pos/t7234.scala diff --git a/test/files/pos/t7234b.scala b/test/pending/pos/t7234b.scala index fee98e87a8..fee98e87a8 100644 --- a/test/files/pos/t7234b.scala +++ b/test/pending/pos/t7234b.scala diff --git a/test/files/pos/t7486.scala b/test/pending/pos/t7486.scala index 6dd7f4c4ac..6dd7f4c4ac 100644 --- a/test/files/pos/t7486.scala +++ b/test/pending/pos/t7486.scala diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import.check b/test/pending/run/macro-term-declared-in-anonymous-explicit-import.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/pending/run/macro-term-declared-in-anonymous-explicit-import.check diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala new file mode 100644 index 0000000000..348f3420f2 --- /dev/null +++ b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Impls_1.scala @@ -0,0 +1,11 @@ +import scala.reflect.macros.{Context => Ctx} + +object Impls { + def foo(c: Ctx) = { + import c.{prefix => prefix} + import c.universe._ + val printPrefix = Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("prefix = " + prefix)))) + val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), TermName("println")), List(Literal(Constant("it works"))))) + c.Expr[Unit](body) + } +}
\ No newline at end of file diff --git a/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala new file mode 100644 index 0000000000..dd2317b1b7 --- /dev/null +++ b/test/pending/run/macro-term-declared-in-anonymous-explicit-import/Macros_Test_2.scala @@ -0,0 +1,6 @@ +import language.experimental.macros + +object Test extends App { + val macros = new { def foo = macro Impls.foo } + macros.foo +}
\ No newline at end of file |