summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala16
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala5
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala80
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala19
-rw-r--r--src/reflect/scala/reflect/macros/compileTimeOnly.scala16
6 files changed, 115 insertions, 27 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index ed45010091..9a358cec46 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -360,12 +360,13 @@ trait Definitions extends api.StandardDefinitions {
lazy val PredefModule = requiredModule[scala.Predef.type]
lazy val PredefModuleClass = PredefModule.moduleClass
- def Predef_classOf = getMemberMethod(PredefModule, nme.classOf)
- def Predef_identity = getMemberMethod(PredefModule, nme.identity)
- def Predef_conforms = getMemberMethod(PredefModule, nme.conforms)
- def Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray)
- def Predef_??? = getMemberMethod(PredefModule, nme.???)
- def Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly)
+ def Predef_classOf = getMemberMethod(PredefModule, nme.classOf)
+ def Predef_identity = getMemberMethod(PredefModule, nme.identity)
+ def Predef_conforms = getMemberMethod(PredefModule, nme.conforms)
+ def Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray)
+ def Predef_wrapArray(tp: Type) = getMemberMethod(PredefModule, wrapArrayMethodName(tp))
+ def Predef_??? = getMemberMethod(PredefModule, nme.???)
+ def Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly)
/** Is `sym` a member of Predef with the given name?
* Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def`
@@ -490,6 +491,8 @@ trait Definitions extends api.StandardDefinitions {
// arrays and their members
lazy val ArrayModule = requiredModule[scala.Array.type]
lazy val ArrayModule_overloadedApply = getMemberMethod(ArrayModule, nme.apply)
+ def ArrayModule_genericApply = ArrayModule_overloadedApply.suchThat(_.paramss.flatten.last.tpe.typeSymbol == ClassTagClass) // [T: ClassTag](xs: T*): Array[T]
+ def ArrayModule_apply(tp: Type) = ArrayModule_overloadedApply.suchThat(_.tpe.resultType =:= arrayType(tp)) // (p1: AnyVal1, ps: AnyVal1*): Array[AnyVal1]
lazy val ArrayClass = getRequiredClass("scala.Array") // requiredClass[scala.Array[_]]
lazy val Array_apply = getMemberMethod(ArrayClass, nme.apply)
lazy val Array_update = getMemberMethod(ArrayClass, nme.update)
@@ -981,6 +984,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 = 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/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 68b5794b59..fb1bf9ed9d 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -6,6 +6,7 @@
package scala.reflect
package internal
+import scala.annotation.elidable
import scala.collection.{ mutable, immutable }
import util._
@@ -108,6 +109,11 @@ abstract class SymbolTable extends macros.Universe
val global: SymbolTable.this.type = SymbolTable.this
} with util.TraceSymbolActivity
+ /** Check that the executing thread is the compiler thread. No-op here,
+ * overridden in interactive.Global. */
+ @elidable(elidable.WARNING)
+ def assertCorrectThread() {}
+
/** Are we compiling for Java SE? */
// def forJVM: Boolean
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index b975ea5786..eec780470e 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -740,6 +740,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) &&
@@ -1259,6 +1262,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
val current = phase
try {
+ assertCorrectThread()
phase = phaseOf(infos.validFrom)
tp.complete(this)
} finally {
@@ -1329,6 +1333,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
infos = infos.prev
if (validTo < curPeriod) {
+ assertCorrectThread()
// adapt any infos that come from previous runs
val current = phase
try {
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index ddfc1f2af0..7ae7cf1821 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -287,6 +287,68 @@ abstract class TreeInfo {
isSelfConstrCall(tree1) || isSuperConstrCall(tree1)
}
+ /**
+ * Does this tree represent an irrefutable pattern match
+ * in the position `for { <tree> <- expr }` based only
+ * on information at the `parser` phase? To qualify, there
+ * may be no subtree that will be interpreted as a
+ * Stable Identifier Pattern.
+ *
+ * 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)) // back quoted ident, not at top level
+ * foo @ (bar, Quux) // UpperCase ident, not at top level
+ * }}}
+ *
+ * If the pattern is a simple identifier, it is always
+ * a variable pattern. For example, the following
+ * introduce new bindings:
+ *
+ * {{{
+ * for { X <- xs } yield X
+ * for { `backquoted` <- xs } yield `backquoted`
+ * }}}
+ *
+ * Note that this differs from a case clause:
+ *
+ * {{{
+ * object X
+ * scrut match {
+ * case X => // case _ if scrut == X
+ * }
+ * }}}
+ *
+ * Background: [[https://groups.google.com/d/msg/scala-internals/qwa_XOw_7Ks/IktkeTBYqg0J]]
+ *
+ */
+ def isVarPatternDeep(tree: Tree): Boolean = {
+ def isVarPatternDeep0(tree: Tree): Boolean = {
+ tree match {
+ case Bind(name, pat) => isVarPatternDeep0(pat)
+ case Ident(name) => isVarPattern(tree)
+ case Apply(sel, args) =>
+ ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName)
+ && (args forall isVarPatternDeep0)
+ )
+ case _ => false
+ }
+ }
+ tree match {
+ case Ident(name) => true
+ case _ => isVarPatternDeep0(tree)
+ }
+ }
+
/** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
case x: Ident => !x.isBackquoted && nme.isVariableName(x.name)
@@ -372,24 +434,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 <expr> : _* ?
*/
def isWildcardStarArg(tree: Tree): Boolean = tree match {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 3104c1e74e..42a9d9e456 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -143,6 +143,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** Undo all changes to constraints to type variables upto `limit`. */
//OPT this method is public so we can do `manual inlining`
def undoTo(limit: UndoPairs) {
+ assertCorrectThread()
while ((log ne limit) && log.nonEmpty) {
val (tv, constr) = log.head
tv.constr = constr
@@ -321,6 +322,18 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ /** Same as a call to narrow unless existentials are visible
+ * after widening the type. In that case, narrow from the widened
+ * type instead of the proxy. This gives buried existentials a
+ * chance to make peace with the other types. See SI-5330.
+ */
+ private def narrowForFindMember(tp: Type): Type = {
+ val w = tp.widen
+ // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type.
+ if ((tp ne w) && containsExistential(w)) w.narrow
+ else tp.narrow
+ }
+
/** The base class for all types */
abstract class Type extends TypeApiImpl with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
@@ -1070,7 +1083,7 @@ trait Types extends api.Types { self: SymbolTable =>
(other ne sym) &&
((other.owner eq sym.owner) ||
(flags & PRIVATE) != 0 || {
- if (self eq null) self = this.narrow
+ if (self eq null) self = narrowForFindMember(this)
if (symtpe eq null) symtpe = self.memberType(sym)
!(self.memberType(other) matches symtpe)
})}) {
@@ -1148,7 +1161,7 @@ trait Types extends api.Types { self: SymbolTable =>
if ((member ne sym) &&
((member.owner eq sym.owner) ||
(flags & PRIVATE) != 0 || {
- if (self eq null) self = this.narrow
+ if (self eq null) self = narrowForFindMember(this)
if (membertpe eq null) membertpe = self.memberType(member)
!(membertpe matches self.memberType(sym))
})) {
@@ -1163,7 +1176,7 @@ trait Types extends api.Types { self: SymbolTable =>
(other ne sym) &&
((other.owner eq sym.owner) ||
(flags & PRIVATE) != 0 || {
- if (self eq null) self = this.narrow
+ if (self eq null) self = narrowForFindMember(this)
if (symtpe eq null) symtpe = self.memberType(sym)
!(self.memberType(other) matches symtpe)
})}) {
diff --git a/src/reflect/scala/reflect/macros/compileTimeOnly.scala b/src/reflect/scala/reflect/macros/compileTimeOnly.scala
new file mode 100644
index 0000000000..5a3a352a53
--- /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.1
+ */
+@getter @setter @beanGetter @beanSetter
+final class compileTimeOnly(message: String) extends scala.annotation.StaticAnnotation