From 03aa7fc3904033f8d2f6f14a87574a03553b7c72 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 29 Jun 2011 10:27:23 +0000 Subject: SI-6616 Check that unsafe operations are only called on the presentation compiler thread. The method that checks the actual constraint is @elidable, expecting it to be used for nightly builds but stripped-off in release builds. This way we don't lose any performance, but 'fail-fast' in IDE nightlies. This assumes that release builds will have at least `-Xelide-below ASSERTION`, but this pull request does not do that. --- .../scala/tools/nsc/interactive/Global.scala | 41 +++++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 01889f4f98..6f7695ba0e 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -20,18 +20,23 @@ import scala.tools.nsc.io.Pickler._ import scala.tools.nsc.typechecker.DivergentImplicit import scala.annotation.tailrec import symtab.Flags.{ACCESSOR, PARAMACCESSOR} +import scala.annotation.elidable import scala.language.implicitConversions /** The main class of the presentation compiler in an interactive environment such as an IDE */ -class Global(settings: Settings, _reporter: Reporter, projectName: String = "") - extends scala.tools.nsc.Global(settings, _reporter) - with CompilerControl - with RangePositions - with ContextTrees - with RichCompilationUnits - with ScratchPadMaker - with Picklers { +class Global(settings: Settings, _reporter: Reporter, projectName: String = "") extends { + /* Is the compiler initializing? Early def, so that the field is true during the + * execution of the super constructor. + */ + private var initializing = true +} with scala.tools.nsc.Global(settings, _reporter) + with CompilerControl + with RangePositions + with ContextTrees + with RichCompilationUnits + with ScratchPadMaker + with Picklers { import definitions._ @@ -51,6 +56,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") import log.logreplay debugLog("logger: " + log.getClass + " writing to " + (new java.io.File(logName)).getAbsolutePath) debugLog("classpath: "+classPath) + Console.err.println("\n ======= CHECK THREAD ACCESS compiler build ========\n") private var curTime = System.nanoTime private def timeStep = { @@ -433,7 +439,18 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") private var threadId = 0 /** The current presentation compiler runner */ - @volatile private[interactive] var compileRunner = newRunnerThread() + @volatile private[interactive] var compileRunner: Thread = newRunnerThread() + + /** Check that the currenyly executing thread is the presentation compiler thread. + * + * Compiler initialization may happen on a different thread (signalled by globalPhase being NoPhase) + */ + @elidable(elidable.WARNING) + override def assertCorrectThread() { + assert(initializing || (Thread.currentThread() eq compileRunner), + "Race condition detected: You are running a presentation compiler method outside the PC thread.[phase: %s]".format(globalPhase) + + " Please file a ticket with the current stack trace at https://www.assembla.com/spaces/scala-ide/support/tickets") + } /** Create a new presentation compiler runner. */ @@ -1110,6 +1127,12 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") alt } } + + /** The compiler has been initialized. Constructors are evaluated in textual order, + * so this is set to true only after all super constructors and the primary constructor + * have been executed. + */ + initializing = false } object CancelException extends Exception -- cgit v1.2.3 From 6902da3168c02448387edc000dedfe97ef5f7cd9 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 6 Nov 2012 22:23:09 +0100 Subject: SI-6539 Annotation for methods unfit for post-typer ASTs Motivated by the `.value` method in the SBT task-syntax branch, which should only be called within the context of the argument to a setting initialization macro. The facility is akin to a fatal deprecation. --- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 6 ++++++ src/reflect/scala/reflect/internal/Definitions.scala | 1 + src/reflect/scala/reflect/internal/Symbols.scala | 3 +++ src/reflect/scala/reflect/macros/compileTimeOnly.scala | 16 ++++++++++++++++ test/files/neg/t6539.check | 10 ++++++++++ test/files/neg/t6539/Macro_1.scala | 10 ++++++++++ test/files/neg/t6539/Test_2.scala | 6 ++++++ 7 files changed, 52 insertions(+) create mode 100644 src/reflect/scala/reflect/macros/compileTimeOnly.scala create mode 100644 test/files/neg/t6539.check create mode 100644 test/files/neg/t6539/Macro_1.scala create mode 100644 test/files/neg/t6539/Test_2.scala (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index c1dc91dbfc..726c8d3b24 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1376,6 +1376,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans ) } + private def checkCompileTimeOnly(sym: Symbol, pos: Position) = { + if (sym.isCompileTimeOnly) + unit.error(pos, s"reference to ${sym.fullLocationString} should not survive typechecking: ${sym.compileTimeOnlyMessage.get}") + } + private def lessAccessible(otherSym: Symbol, memberSym: Symbol): Boolean = ( (otherSym != NoSymbol) && !otherSym.isProtected @@ -1562,6 +1567,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans checkDeprecated(sym, tree.pos) if (settings.Xmigration28.value) checkMigration(sym, tree.pos) + checkCompileTimeOnly(sym, tree.pos) if (sym eq NoSymbol) { unit.warning(tree.pos, "Select node has NoSymbol! " + tree + " / " + tree.tpe) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index e24971a309..4c7694c319 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -944,6 +944,7 @@ trait Definitions extends api.StandardDefinitions { lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] lazy val CloneableAttr = requiredClass[scala.annotation.cloneable] + lazy val CompileTimeOnlyAttr = requiredClass[scala.reflect.macros.compileTimeOnly] lazy val DeprecatedAttr = requiredClass[scala.deprecated] lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance] diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 7cb9a0e105..7a0f5f2caf 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -743,6 +743,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) } def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) } + def isCompileTimeOnly = hasAnnotation(CompileTimeOnlyAttr) + def compileTimeOnlyMessage = getAnnotation(CompileTimeOnlyAttr) flatMap (_ stringArg 0) + /** Is this symbol an accessor method for outer? */ final def isOuterAccessor = { hasFlag(STABLE | ARTIFACT) && diff --git a/src/reflect/scala/reflect/macros/compileTimeOnly.scala b/src/reflect/scala/reflect/macros/compileTimeOnly.scala new file mode 100644 index 0000000000..4018e7db71 --- /dev/null +++ b/src/reflect/scala/reflect/macros/compileTimeOnly.scala @@ -0,0 +1,16 @@ +package scala.reflect +package macros + +import scala.annotation.meta._ + +/** + * An annotation that designates a member should not be referred to after + * type checking (which includes macro expansion); it must only be used in + * the arguments of some other macro that will eliminate it from the AST. + * + * @param message the error message to print during compilation if a reference remains + * after type checking + * @since 2.10.0 + */ +@getter @setter @beanGetter @beanSetter +final class compileTimeOnly(message: String = "") extends scala.annotation.StaticAnnotation diff --git a/test/files/neg/t6539.check b/test/files/neg/t6539.check new file mode 100644 index 0000000000..a5d5a7244d --- /dev/null +++ b/test/files/neg/t6539.check @@ -0,0 +1,10 @@ +Test_2.scala:2: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m + M.cto // error + ^ +Test_2.scala:3: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m + M.m(M.cto, ()) // error + ^ +Test_2.scala:5: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m + M.cto // error + ^ +three errors found diff --git a/test/files/neg/t6539/Macro_1.scala b/test/files/neg/t6539/Macro_1.scala new file mode 100644 index 0000000000..69bd53fe07 --- /dev/null +++ b/test/files/neg/t6539/Macro_1.scala @@ -0,0 +1,10 @@ +import language.experimental.macros +import reflect.macros.Context + +object M { + def m(a: Any, b: Any): Any = macro mImpl + def mImpl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]) = a + + @reflect.macros.compileTimeOnly("cto may only be used as an argument to m") + def cto = 0 +} diff --git a/test/files/neg/t6539/Test_2.scala b/test/files/neg/t6539/Test_2.scala new file mode 100644 index 0000000000..1569c79788 --- /dev/null +++ b/test/files/neg/t6539/Test_2.scala @@ -0,0 +1,6 @@ +object Test { + M.cto // error + M.m(M.cto, ()) // error + M.m((), M.cto) // okay + M.cto // error +} \ No newline at end of file -- cgit v1.2.3 From 48ee29aa26e4e5358cb1de7890565095420177b4 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 6 Nov 2012 23:43:44 +0100 Subject: Refine @compileTimeOnly - Don't default the message, and show it exclusively. - Fix cut-and-pasto in the @since tag - Be tolerant if the annotaion class is missing, as seems to have been the case compiling the continuations plugin. - s/\t/ / in the test file to show the errors are positioned correctly. - Use defensive getOrElse --- .../scala/tools/nsc/typechecker/RefChecks.scala | 9 +++++++-- src/reflect/scala/reflect/internal/Definitions.scala | 2 +- src/reflect/scala/reflect/macros/compileTimeOnly.scala | 4 ++-- test/files/neg/t6539.check | 18 +++++++++--------- test/files/neg/t6539/Macro_1.scala | 8 ++++---- test/files/neg/t6539/Test_2.scala | 10 +++++----- 6 files changed, 28 insertions(+), 23 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 726c8d3b24..ee7805cb3d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1377,8 +1377,13 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } private def checkCompileTimeOnly(sym: Symbol, pos: Position) = { - if (sym.isCompileTimeOnly) - unit.error(pos, s"reference to ${sym.fullLocationString} should not survive typechecking: ${sym.compileTimeOnlyMessage.get}") + if (sym.isCompileTimeOnly) { + def defaultMsg = + s"""|Reference to ${sym.fullLocationString} should not have survived past type checking, + |it should have been processed and eliminated during expansion of an enclosing macro.""".stripMargin + // The getOrElse part should never happen, it's just here as a backstop. + unit.error(pos, sym.compileTimeOnlyMessage getOrElse defaultMsg) + } } private def lessAccessible(otherSym: Symbol, memberSym: Symbol): Boolean = ( diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 4c7694c319..2a7b55cb5a 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -944,7 +944,7 @@ trait Definitions extends api.StandardDefinitions { lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] lazy val CloneableAttr = requiredClass[scala.annotation.cloneable] - lazy val CompileTimeOnlyAttr = requiredClass[scala.reflect.macros.compileTimeOnly] + lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.reflect.macros.compileTimeOnly") lazy val DeprecatedAttr = requiredClass[scala.deprecated] lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance] diff --git a/src/reflect/scala/reflect/macros/compileTimeOnly.scala b/src/reflect/scala/reflect/macros/compileTimeOnly.scala index 4018e7db71..5a3a352a53 100644 --- a/src/reflect/scala/reflect/macros/compileTimeOnly.scala +++ b/src/reflect/scala/reflect/macros/compileTimeOnly.scala @@ -10,7 +10,7 @@ import scala.annotation.meta._ * * @param message the error message to print during compilation if a reference remains * after type checking - * @since 2.10.0 + * @since 2.10.1 */ @getter @setter @beanGetter @beanSetter -final class compileTimeOnly(message: String = "") extends scala.annotation.StaticAnnotation +final class compileTimeOnly(message: String) extends scala.annotation.StaticAnnotation diff --git a/test/files/neg/t6539.check b/test/files/neg/t6539.check index a5d5a7244d..b647636338 100644 --- a/test/files/neg/t6539.check +++ b/test/files/neg/t6539.check @@ -1,10 +1,10 @@ -Test_2.scala:2: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m - M.cto // error - ^ -Test_2.scala:3: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m - M.m(M.cto, ()) // error - ^ -Test_2.scala:5: error: reference to method cto in object M should not survive typechecking: cto may only be used as an argument to m - M.cto // error - ^ +Test_2.scala:2: error: cto may only be used as an argument to m + M.cto // error + ^ +Test_2.scala:3: error: cto may only be used as an argument to m + M.m(M.cto, ()) // error + ^ +Test_2.scala:5: error: cto may only be used as an argument to m + M.cto // error + ^ three errors found diff --git a/test/files/neg/t6539/Macro_1.scala b/test/files/neg/t6539/Macro_1.scala index 69bd53fe07..ed52776d95 100644 --- a/test/files/neg/t6539/Macro_1.scala +++ b/test/files/neg/t6539/Macro_1.scala @@ -2,9 +2,9 @@ import language.experimental.macros import reflect.macros.Context object M { - def m(a: Any, b: Any): Any = macro mImpl - def mImpl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]) = a + def m(a: Any, b: Any): Any = macro mImpl + def mImpl(c: Context)(a: c.Expr[Any], b: c.Expr[Any]) = a - @reflect.macros.compileTimeOnly("cto may only be used as an argument to m") - def cto = 0 + @reflect.macros.compileTimeOnly("cto may only be used as an argument to " + "m") + def cto = 0 } diff --git a/test/files/neg/t6539/Test_2.scala b/test/files/neg/t6539/Test_2.scala index 1569c79788..5a602879ec 100644 --- a/test/files/neg/t6539/Test_2.scala +++ b/test/files/neg/t6539/Test_2.scala @@ -1,6 +1,6 @@ object Test { - M.cto // error - M.m(M.cto, ()) // error - M.m((), M.cto) // okay - M.cto // error -} \ No newline at end of file + M.cto // error + M.m(M.cto, ()) // error + M.m((), M.cto) // okay + M.cto // error +} -- cgit v1.2.3 From f98e4d05a68a8a41a92d292bd590ce765b1a6bd5 Mon Sep 17 00:00:00 2001 From: Grzegorz Kossakowski Date: Fri, 9 Nov 2012 10:47:19 -0800 Subject: Fix type of the custom `ClassTag` in `PatternMatching.scala` In fb315772 custom ClassTags were introduced to optimize array creation in hot places. The idea was that if `Array[T]` is allocated through `ClassTag[T]` (which is essentially a factory for Array[T]) we would introduce a custom class implementing `ClassTag[T]` interface and would have specialized array allocation instruction instead of having reflective call as it's being done with default (compiler synthesized) implementation of `ClassTag[T]`. In case of `PatternMatching.scala` I made a mistake of providing `ClassTag[Array[Clause]]` instead of `ClassTag[Clause]` so that value would never be used and compiler still would resolve implicit through default mechanism. This has been discovered thanks to @paulp's work on unused value detection. Review by @paulp. --- src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 7d504d8c81..31db042942 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -2037,9 +2037,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // CNF: a formula is a conjunction of clauses type Formula = Array[Clause] /** Override Array creation for efficiency (to not go through reflection). */ - private implicit val formulaTag: scala.reflect.ClassTag[Formula] = new scala.reflect.ClassTag[Formula] { - def runtimeClass: java.lang.Class[Formula] = classOf[Formula] - final override def newArray(len: Int): Array[Formula] = new Array[Formula](len) + private implicit val clauseTag: scala.reflect.ClassTag[Clause] = new scala.reflect.ClassTag[Clause] { + def runtimeClass: java.lang.Class[Clause] = classOf[Clause] + final override def newArray(len: Int): Array[Clause] = new Array[Clause](len) } def formula(c: Clause*): Formula = c.toArray def andFormula(a: Formula, b: Formula): Formula = a ++ b -- cgit v1.2.3 From 8b2caf0746fd4405f2d47b54d17d484e6603c89d Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 10 Nov 2012 13:07:26 +0100 Subject: SI-6646 Fix regression in for desugaring. The early check in the parser of pattern irrefutability, added in c82ecab, failed to consider InitCaps and `backquoted` identifiers. --- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 2 +- src/reflect/scala/reflect/internal/TreeInfo.scala | 45 +++++++++++++--------- test/files/run/t6646.check | 3 ++ test/files/run/t6646.scala | 13 +++++++ 4 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 test/files/run/t6646.check create mode 100644 test/files/run/t6646.scala (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 0d13623e0c..0ac46a18bc 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -285,7 +285,7 @@ abstract class TreeBuilder { def makeGenerator(pos: Position, pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = { val pat1 = patvarTransformer.transform(pat) val rhs1 = - if (valeq || treeInfo.isVariablePattern(pat)) rhs + if (valeq || treeInfo.isVarPatternDeep(pat)) rhs else makeFilter(rhs, pat1.duplicate, nme.CHECK_IF_REFUTABLE_STRING) if (valeq) ValEq(pos, pat1, rhs1) diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 38e55a3c01..56a0bac72b 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -245,6 +245,33 @@ abstract class TreeInfo { isSelfConstrCall(tree1) || isSuperConstrCall(tree1) } + /** Is this tree comprised of nothing but identifiers, + * but possibly in bindings or tuples? For instance: + * + * {{{ + * foo @ (bar, (baz, quux)) + * }}} + * + * is a variable pattern; if the structure matches, + * then the remainder is inevitable. + * + * The following are not variable patterns. + * + * {{{ + * foo @ (bar, (`baz`, Quux)) + * foo @ (bar, Quux) + * }}} + */ + def isVarPatternDeep(tree: Tree): Boolean = tree match { + case Bind(name, pat) => isVarPatternDeep(pat) + case Ident(name) => isVarPattern(tree) + case Apply(sel, args) => + ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) + && (args forall isVarPatternDeep) + ) + case _ => false + } + /** Is tree a variable pattern? */ def isVarPattern(pat: Tree): Boolean = pat match { case x: Ident => !x.isBackquoted && nme.isVariableName(x.name) @@ -330,24 +357,6 @@ abstract class TreeInfo { case _ => false } - /** Is this tree comprised of nothing but identifiers, - * but possibly in bindings or tuples? For instance - * - * foo @ (bar, (baz, quux)) - * - * is a variable pattern; if the structure matches, - * then the remainder is inevitable. - */ - def isVariablePattern(tree: Tree): Boolean = tree match { - case Bind(name, pat) => isVariablePattern(pat) - case Ident(name) => true - case Apply(sel, args) => - ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) - && (args forall isVariablePattern) - ) - case _ => false - } - /** Is this argument node of the form : _* ? */ def isWildcardStarArg(tree: Tree): Boolean = tree match { diff --git a/test/files/run/t6646.check b/test/files/run/t6646.check new file mode 100644 index 0000000000..e27b5b9efb --- /dev/null +++ b/test/files/run/t6646.check @@ -0,0 +1,3 @@ +Found NotNull +Found lower +Found 2 diff --git a/test/files/run/t6646.scala b/test/files/run/t6646.scala new file mode 100644 index 0000000000..9418bfafb1 --- /dev/null +++ b/test/files/run/t6646.scala @@ -0,0 +1,13 @@ +sealed trait ColumnOption +case object NotNull extends ColumnOption +case object PrimaryKey extends ColumnOption +case object lower extends ColumnOption + +object Test { + def main(args: Array[String]) { + val l = List(PrimaryKey, NotNull, lower) + for (option @ NotNull <- l) println("Found " + option) + for (option @ `lower` <- l) println("Found " + option) + for ((`lower`, i) <- l.zipWithIndex) println("Found " + i) + } +} -- cgit v1.2.3 From 1e0a30a744e6853b1e69928a63b327226f4bf27f Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 10 Nov 2012 21:51:24 +0100 Subject: SI-6644 Account for varargs in extmethod forwarder Which sounded difficult, so instead I offshored the work to the friendly republic of TreeGen. --- src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 4 +--- test/files/run/t6644.scala | 8 ++++++++ 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 test/files/run/t6644.scala (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 6cc957a9eb..6f3d7932a5 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -173,9 +173,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { List(This(currentOwner))) val extensionCall = atOwner(origMeth) { localTyper.typedPos(rhs.pos) { - (extensionCallPrefix /: vparamss) { - case (fn, params) => Apply(fn, params map (param => Ident(param.symbol))) - } + gen.mkForwarder(extensionCallPrefix, mmap(vparamss)(_.symbol)) } } deriveDefDef(tree)(_ => extensionCall) diff --git a/test/files/run/t6644.scala b/test/files/run/t6644.scala new file mode 100644 index 0000000000..b8b36f957c --- /dev/null +++ b/test/files/run/t6644.scala @@ -0,0 +1,8 @@ +class Testable(val c: String) extends AnyVal { + def matching(cases: Boolean*) = cases contains true +} + +object Test extends App { + assert(new Testable("").matching(true, false)) +} + -- cgit v1.2.3 From af3b03bf33ac5ed556b51a213d6b466d01109969 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 11 Nov 2012 22:58:42 +0100 Subject: -Yshow-trees-compact respects other options The aforementioned tree printer now respects other tree printing options such as -uniqid and -Xprint-types. This helps debugging reify, which uses `nodePrinters`, not `showRaw` to print its trees, because back then `showRaw` didn't exist yet. --- src/compiler/scala/tools/nsc/ast/NodePrinters.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index 275cfcd123..deea4de707 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -102,7 +102,7 @@ abstract class NodePrinters { buf.clear() if (settings.XshowtreesStringified.value) buf.append(tree.toString + EOL) if (settings.XshowtreesCompact.value) { - buf.append(showRaw(tree)) + buf.append(showRaw(tree, printIds = settings.uniqid.value, printTypes = settings.printtypes.value)) } else { level = 0 traverse(tree) -- cgit v1.2.3 From 1bdd5ee07d8ec4374b848099c9a95f27c2e9b381 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Mon, 12 Nov 2012 20:18:20 +0100 Subject: better error when typetagging local classes Inspired by https://issues.scala-lang.org/browse/SI-6649 --- src/compiler/scala/reflect/reify/Errors.scala | 2 +- test/files/neg/t6323a.check | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index b8b5f8033b..3d7cb95792 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -28,7 +28,7 @@ trait Errors { } def CannotReifyWeakType(details: Any) = { - val msg = "cannot create a TypeTag" + details + val msg = "cannot create a TypeTag" + details + ": use WeakTypeTag instead" throw new ReificationException(defaultErrorPosition, msg) } diff --git a/test/files/neg/t6323a.check b/test/files/neg/t6323a.check index 670247887c..a80c9a0a81 100644 --- a/test/files/neg/t6323a.check +++ b/test/files/neg/t6323a.check @@ -1,6 +1,6 @@ t6323a.scala:11: `package`.this.materializeTypeTag[Test](scala.reflect.runtime.`package`.universe) is not a valid implicit value for reflect.runtime.universe.TypeTag[Test] because: failed to typecheck the materialized tag: -cannot create a TypeTag referring to local class Test.Test +cannot create a TypeTag referring to local class Test.Test: use WeakTypeTag instead val value = u.typeOf[Test] ^ t6323a.scala:11: error: No TypeTag available for Test -- cgit v1.2.3 From b9225732889448378ccb880faa6d8421cf40e02c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 13 Nov 2012 13:39:46 -0800 Subject: Fix for SI-6662, macro failing too early. Don't give up before you try tupling. Who knows what someone might be doing with a Unit. --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- test/files/run/t6662.check | 1 + test/files/run/t6662/Macro_1.scala | 8 ++++++++ test/files/run/t6662/Test_2.scala | 8 ++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t6662.check create mode 100644 test/files/run/t6662/Macro_1.scala create mode 100644 test/files/run/t6662/Test_2.scala (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index df3731794a..d3847de894 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3078,7 +3078,7 @@ trait Typers extends Modes with Adaptations with Tags { def checkNotMacro() = { if (fun.symbol != null && fun.symbol.filter(sym => sym != null && sym.isTermMacro && !sym.isErroneous) != NoSymbol) - duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) + tryTupleApply getOrElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun)) } if (mt.isErroneous) duplErrTree diff --git a/test/files/run/t6662.check b/test/files/run/t6662.check new file mode 100644 index 0000000000..6a452c185a --- /dev/null +++ b/test/files/run/t6662.check @@ -0,0 +1 @@ +() diff --git a/test/files/run/t6662/Macro_1.scala b/test/files/run/t6662/Macro_1.scala new file mode 100644 index 0000000000..f373eaaf94 --- /dev/null +++ b/test/files/run/t6662/Macro_1.scala @@ -0,0 +1,8 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +object Demo { + def id[T](a: T): T = macro idImpl[T] + + def idImpl[T: c.WeakTypeTag](c: Context)(a: c.Expr[T]): c.Expr[T] = a +} diff --git a/test/files/run/t6662/Test_2.scala b/test/files/run/t6662/Test_2.scala new file mode 100644 index 0000000000..03a80b655a --- /dev/null +++ b/test/files/run/t6662/Test_2.scala @@ -0,0 +1,8 @@ +// Macro usage: + +object Test { + def main(args: Array[String]) { + val s = Demo id () + println(s) + } +} -- cgit v1.2.3