summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/codegen/Types.scala2
-rw-r--r--src/compiler/scala/reflect/reify/package.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Taggings.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--src/library/scala/DelayedInit.scala32
-rw-r--r--test/files/neg/t2775.check8
-rw-r--r--test/pending/neg/t2066.scala16
-rw-r--r--test/pending/pos/t5639/Bar.scala7
-rw-r--r--test/pending/pos/t5639/Foo.scala7
13 files changed, 94 insertions, 38 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala
index 1f336f4b0f..a2b074c6b2 100644
--- a/src/compiler/scala/reflect/reify/codegen/Types.scala
+++ b/src/compiler/scala/reflect/reify/codegen/Types.scala
@@ -99,7 +99,7 @@ trait Types {
// if this fails, it might produce the dreaded "erroneous or inaccessible type" error
// to find out the whereabouts of the error run scalac with -Ydebug
if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe))
- typer.resolveTypeTag(defaultErrorPosition, prefix.tpe, tpe, concrete) match {
+ typer.resolveTypeTag(prefix.tpe, tpe, defaultErrorPosition, concrete) match {
case failure if failure.isEmpty =>
if (reifyDebug) println("implicit search was fruitless")
EmptyTree
diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala
index 3f9d6200cd..f3040ad79c 100644
--- a/src/compiler/scala/reflect/reify/package.scala
+++ b/src/compiler/scala/reflect/reify/package.scala
@@ -33,8 +33,8 @@ package object reify {
import definitions._
import analyzer.enclosingMacroPosition
- def erasureTagInScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(enclosingMacroPosition, tpe, concrete = concrete))
- def arrayTagInScope = typer0.context.withMacrosDisabled(typer0.resolveArrayTag(enclosingMacroPosition, tpe))
+ def erasureTagInScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(tpe, enclosingMacroPosition, concrete = concrete))
+ def arrayTagInScope = typer0.context.withMacrosDisabled(typer0.resolveArrayTag(tpe, enclosingMacroPosition))
val inScope = (erasureTagInScope, arrayTagInScope)
inScope match {
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 338c39dc5f..b8e43dfc50 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -997,7 +997,7 @@ abstract class Erasure extends AddInterfaces
}
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
else if (isPrimitiveValueClass(qual.tpe.typeSymbol))
- global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveErasureTag(tree.pos, qual.tpe.widen, true))))
+ global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveErasureTag(qual.tpe.widen, tree.pos, true))))
else
tree
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index cf00ee6b5d..ef98935f9c 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -410,23 +410,23 @@ abstract class UnCurry extends InfoTransform
def sequenceToArray(tree: Tree) = {
val toArraySym = tree.tpe member nme.toArray
assert(toArraySym != NoSymbol)
- def getClassTag(tp: Type): Tree = {
- val tag = localTyper.resolveArrayTag(tree.pos, tp)
+ def getArrayTag(tp: Type): Tree = {
+ val tag = localTyper.resolveArrayTag(tp, tree.pos)
// Don't want bottom types getting any further than this (SI-4024)
- if (tp.typeSymbol.isBottomClass) getClassTag(AnyClass.tpe)
+ if (tp.typeSymbol.isBottomClass) getArrayTag(AnyClass.tpe)
else if (!tag.isEmpty) tag
- else if (tp.bounds.hi ne tp) getClassTag(tp.bounds.hi)
- else localTyper.TyperErrorGen.MissingClassTagError(tree, tp)
+ else if (tp.bounds.hi ne tp) getArrayTag(tp.bounds.hi)
+ else localTyper.TyperErrorGen.MissingArrayTagError(tree, tp)
}
- def traversableClassTag(tpe: Type): Tree = {
+ def traversableArrayTag(tpe: Type): Tree = {
(tpe baseType TraversableClass).typeArgs match {
- case targ :: _ => getClassTag(targ)
+ case targ :: _ => getArrayTag(targ)
case _ => EmptyTree
}
}
afterUncurry {
localTyper.typedPos(pos) {
- gen.mkMethodCall(tree, toArraySym, Nil, List(traversableClassTag(tree.tpe)))
+ gen.mkMethodCall(tree, toArraySym, Nil, List(traversableArrayTag(tree.tpe)))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 6932030fc2..08bf581256 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -343,7 +343,7 @@ trait ContextErrors {
issueNormalTypeError(tree, "macros cannot be eta-expanded")
setError(tree)
}
-
+
def MacroPartialApplicationError(tree: Tree) = {
issueNormalTypeError(tree, "macros cannot be partially applied")
setError(tree)
@@ -592,9 +592,9 @@ trait ContextErrors {
def AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) =
issueNormalTypeError(tree, "can't existentially abstract over parameterized type " + tp)
- // classTagTree
- def MissingClassTagError(tree: Tree, tp: Type) = {
- issueNormalTypeError(tree, "cannot find class tag for element type "+tp)
+ // resolveArrayTag
+ def MissingArrayTagError(tree: Tree, tp: Type) = {
+ issueNormalTypeError(tree, "cannot find array tag for element type "+tp)
setError(tree)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 787d7af136..722440349a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1266,8 +1266,8 @@ trait Implicits {
}
val tagInScope =
- if (full) context.withMacrosDisabled(resolveTypeTag(pos, ReflectMirrorPrefix.tpe, tp, true))
- else context.withMacrosDisabled(resolveArrayTag(pos, tp))
+ if (full) context.withMacrosDisabled(resolveTypeTag(ReflectMirrorPrefix.tpe, tp, pos, true))
+ else context.withMacrosDisabled(resolveArrayTag(tp, pos))
if (tagInScope.isEmpty) mot(tp, Nil, Nil)
else {
val interop =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
index d276b39f16..fb0d6fb3c5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Taggings.scala
@@ -10,7 +10,7 @@ trait Taggings {
trait Tagging {
self: Typer =>
- private def resolveTag(pos: Position, taggedTp: Type) = beforeTyper {
+ private def resolveTag(taggedTp: Type, pos: Position) = beforeTyper {
inferImplicit(
EmptyTree,
taggedTp,
@@ -25,47 +25,47 @@ trait Taggings {
/** Finds in scope or materializes an ArrayTag.
* Should be used instead of ClassTag or ClassManifest every time compiler needs to create an array.
*
+ * @param tp Type we're looking an ArrayTag for, e.g. resolveArrayTag(IntClass.tpe, pos) will look for ArrayTag[Int].
* @param pos Position for error reporting. Please, provide meaningful value.
- * @param tp Type we're looking an ArrayTag for, e.g. resolveArrayTag(pos, IntClass.tpe) will look for ArrayTag[Int].
*
* @returns Tree that represents an `scala.reflect.ArrayTag` for `tp` if everything is okay.
* EmptyTree if the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
*/
- def resolveArrayTag(pos: Position, tp: Type): Tree = {
+ def resolveArrayTag(tp: Type, pos: Position): Tree = {
val taggedTp = appliedType(ArrayTagClass.typeConstructor, List(tp))
- resolveTag(pos, taggedTp)
+ resolveTag(taggedTp, pos)
}
/** Finds in scope or materializes an ErasureTag (if `concrete` is false) or a ClassTag (if `concrete` is true).
* Should be used instead of ClassTag or ClassManifest every time compiler needs to persist an erasure.
*
+ * @param tp Type we're looking an ErasureTag for, e.g. resolveErasureTag(IntClass.tpe, pos, true) will look for ClassTag[Int].
* @param pos Position for error reporting. Please, provide meaningful value.
- * @param tp Type we're looking an ErasureTag for, e.g. resolveErasureTag(pos, IntClass.tpe, true) will look for ClassTag[Int].
* @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members.
* If false then the function will always succeed (abstract types will be erased to their upper bounds).
*
* @returns Tree that represents an `scala.reflect.ErasureTag` for `tp` if everything is okay.
* EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
*/
- def resolveErasureTag(pos: Position, tp: Type, concrete: Boolean): Tree = {
+ def resolveErasureTag(tp: Type, pos: Position, concrete: Boolean): Tree = {
val taggedTp = appliedType(if (concrete) ClassTagClass.typeConstructor else ErasureTagClass.typeConstructor, List(tp))
- resolveTag(pos, taggedTp)
+ resolveTag(taggedTp, pos)
}
/** Finds in scope or materializes a TypeTag (if `concrete` is false) or a ConcreteTypeTag (if `concrete` is true).
*
- * @param pos Position for error reporting. Please, provide meaningful value.
* @param pre Prefix that represents a universe this type tag will be bound to.
- * @param tp Type we're looking a TypeTag for, e.g. resolveTypeTag(pos, reflectMirrorPrefix, IntClass.tpe, false) will look for scala.reflect.mirror.TypeTag[Int].
+ * @param tp Type we're looking a TypeTag for, e.g. resolveTypeTag(reflectMirrorPrefix, IntClass.tpe, pos, false) will look for scala.reflect.mirror.TypeTag[Int].
+ * @param pos Position for error reporting. Please, provide meaningful value.
* @param concrete If true then the result must not contain unresolved (i.e. not spliced) type parameters and abstract type members.
* If false then the function will always succeed (abstract types will be reified as free types).
*
* @returns Tree that represents a `scala.reflect.TypeTag` for `tp` if everything is okay.
* EmptyTree if `concrete` is true and the result contains unresolved (i.e. not spliced) type parameters and abstract type members.
*/
- def resolveTypeTag(pos: Position, pre: Type, tp: Type, concrete: Boolean): Tree = {
+ def resolveTypeTag(pre: Type, tp: Type, pos: Position, concrete: Boolean): Tree = {
val taggedTp = appliedType(singleType(pre, pre member (if (concrete) ConcreteTypeTagClass else TypeTagClass).name), List(tp))
- resolveTag(pos, taggedTp)
+ resolveTag(taggedTp, pos)
}
}
} \ 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 5902e480a3..8c2eae1c86 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4841,8 +4841,8 @@ trait Typers extends Modes with Adaptations with Taggings {
val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe)
val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last
val newArrayApp = atPos(tree.pos) {
- val tag = resolveArrayTag(tree.pos, tagType)
- if (tag.isEmpty) MissingClassTagError(tree, tagType)
+ val tag = resolveArrayTag(tagType, tree.pos)
+ if (tag.isEmpty) MissingArrayTagError(tree, tagType)
else new ApplyToImplicitArgs(Select(tag, nme.newArray), args)
}
typed(newArrayApp, mode, pt)
diff --git a/src/library/scala/DelayedInit.scala b/src/library/scala/DelayedInit.scala
index e898bca720..52a38ca6f7 100644
--- a/src/library/scala/DelayedInit.scala
+++ b/src/library/scala/DelayedInit.scala
@@ -8,15 +8,41 @@
package scala
-/** Classes and traits inheriting the `DelayedInit` marker trait
- * will have their initialization code rewritten as follows:
+/** Classes and objects (but note, not traits) inheriting the `DelayedInit`
+ * marker trait will have their initialization code rewritten as follows:
* `code` becomes `delayedInit(code)`.
*
* Initialization code comprises all statements and all value definitions
* that are executed during initialization.
*
+ * Example:
+ * {{{
+ * trait Helper extends DelayedInit {
+ * def delayedInit(body: => Unit) = {
+ * println("dummy text, printed before initialization of C")
+ * body // evaluates the initialization code of C
+ * }
+ * }
+ *
+ * class C extends Helper {
+ * println("this is the initialization code of C")
+ * }
+ *
+ * object Test extends App {
+ * val c = new C
+ * }
+ * }}}
+ *
+ * Should result in the following being printed:
+ * {{{
+ * dummy text, printed before initialization of C
+ * this is the initialization code of C
+ * }}}
+ *
+ * @see "Delayed Initialization" subsection of the Scala Language Specification (section 5.1)
+ *
* @author Martin Odersky
*/
trait DelayedInit {
def delayedInit(x: => Unit): Unit
-}
+} \ No newline at end of file
diff --git a/test/files/neg/t2775.check b/test/files/neg/t2775.check
index f357221cd9..a1e950cf73 100644
--- a/test/files/neg/t2775.check
+++ b/test/files/neg/t2775.check
@@ -1,4 +1,4 @@
-t2775.scala:1: error: cannot find class tag for element type B.this.T
-trait B[S] { type T = S; val c = new Array[T](1) }
- ^
-one error found
+t2775.scala:1: error: cannot find array tag for element type B.this.T
+trait B[S] { type T = S; val c = new Array[T](1) }
+ ^
+one error found
diff --git a/test/pending/neg/t2066.scala b/test/pending/neg/t2066.scala
new file mode 100644
index 0000000000..46177b19f7
--- /dev/null
+++ b/test/pending/neg/t2066.scala
@@ -0,0 +1,16 @@
+object Test extends App {
+ trait A {
+ def f[T[_]](x : T[Int]) : T[Any]
+ }
+
+ class B extends A {
+ def f[T[+_]](x : T[Int]) : T[Any] = x
+ }
+
+ class P[Y](var y : Y)
+
+ val p = new P(1)
+ val palias = (new B():A).f[P](p)
+ palias.y = "hello"
+ val z: Int = p.y
+} \ No newline at end of file
diff --git a/test/pending/pos/t5639/Bar.scala b/test/pending/pos/t5639/Bar.scala
new file mode 100644
index 0000000000..f577500acd
--- /dev/null
+++ b/test/pending/pos/t5639/Bar.scala
@@ -0,0 +1,7 @@
+package pack.age
+
+import pack.age.Implicits._
+
+object Quux {
+ def baz : Baz = 1
+}
diff --git a/test/pending/pos/t5639/Foo.scala b/test/pending/pos/t5639/Foo.scala
new file mode 100644
index 0000000000..6602150661
--- /dev/null
+++ b/test/pending/pos/t5639/Foo.scala
@@ -0,0 +1,7 @@
+package pack.age
+
+class Baz
+
+object Implicits {
+ implicit def Baz(n: Int): Baz = new Baz
+}