summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-02-23 13:36:19 +0000
committerPaul Phillips <paulp@improving.org>2009-02-23 13:36:19 +0000
commitef13a9d40b2b62d73d8caabca576e1d2667ea83d (patch)
treec1e09697d438239a1e2a06e74483b2000088b007
parenta187f432f712734d00504e8250955272220eb418 (diff)
downloadscala-ef13a9d40b2b62d73d8caabca576e1d2667ea83d.tar.gz
scala-ef13a9d40b2b62d73d8caabca576e1d2667ea83d.tar.bz2
scala-ef13a9d40b2b62d73d8caabca576e1d2667ea83d.zip
Fix and test case for #935; added test in RefCh...
Fix and test case for #935; added test in RefChecks to confirm that parameterized annotations conform to type bounds.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala29
-rw-r--r--test/files/neg/bug935.check4
-rw-r--r--test/files/neg/bug935.scala6
3 files changed, 33 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index bcc1a1686e..600f4f7953 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -737,11 +737,13 @@ abstract class RefChecks extends InfoTransform {
override def transform(tree: Tree): Tree = try {
/* Check whether argument types conform to bounds of type parameters */
- def checkBounds(pre: Type, owner: Symbol, tparams: List[Symbol], argtps: List[Type]): Unit = try {
- typer.infer.checkBounds(tree.pos, pre, owner, tparams, argtps, "");
+ def checkBounds(pre: Type, owner: Symbol, tparams: List[Symbol], argtps: List[Type]): Unit =
+ checkBoundsWithPos(pre, owner, tparams, argtps, tree.pos)
+ def checkBoundsWithPos(pre: Type, owner: Symbol, tparams: List[Symbol], argtps: List[Type], pos: Position): Unit = try {
+ typer.infer.checkBounds(pos, pre, owner, tparams, argtps, "");
} catch {
case ex: TypeError =>
- unit.error(tree.pos, ex.getMessage());
+ unit.error(pos, ex.getMessage());
if (settings.explaintypes.value) {
val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, argtps).bounds)
List.map2(argtps, bounds)((targ, bound) => explainTypes(bound.lo, targ))
@@ -810,10 +812,27 @@ abstract class RefChecks extends InfoTransform {
def isCaseApply(sym : Symbol) = sym.isSourceMethod && sym.hasFlag(CASE) && sym.name == nme.apply
+ def checkTypeRef(tp: TypeRef, pos: Position) {
+ val TypeRef(pre, sym, args) = tp
+ checkDeprecated(sym, pos)
+ if (!tp.isHigherKinded)
+ checkBoundsWithPos(pre, sym.owner, sym.typeParams, args, pos)
+ }
+ def checkAnnotations(annots: List[Annotation]) {
+ for ((tp @ TypeRef(_,_,_), pos) <- annots.map(a => (a.tpe, a.pos)))
+ checkTypeRef(tp, pos)
+ }
+
val savedLocalTyper = localTyper
val savedCurrentApplication = currentApplication
val sym = tree.symbol
var result = tree
+
+ // if this tree can carry modifiers, make sure any annotations also conform to type bounds; bug #935
+ tree match {
+ case x: MemberDef => checkAnnotations(x.mods.annotations)
+ case _ =>
+ }
tree match {
case DefDef(mods, name, tparams, vparams, tpt, EmptyTree) if tree.symbol.hasAttribute(definitions.NativeAttr) =>
tree.symbol.resetFlag(DEFERRED)
@@ -836,9 +855,7 @@ abstract class RefChecks extends InfoTransform {
new TypeTraverser {
def traverse(tp: Type) {
tp match {
- case TypeRef(pre, sym, args) =>
- checkDeprecated(sym, tree.pos)
- if (!tp.isHigherKinded) checkBounds(pre, sym.owner, sym.typeParams, args)
+ case t: TypeRef => checkTypeRef(t, tree.pos)
case _ =>
}
}
diff --git a/test/files/neg/bug935.check b/test/files/neg/bug935.check
new file mode 100644
index 0000000000..e2c2b87be8
--- /dev/null
+++ b/test/files/neg/bug935.check
@@ -0,0 +1,4 @@
+bug935.scala:5: error: type arguments [Test3.B] do not conform to class E's type parameter bounds [T <: String]
+ @E[B](new B) val b = "hi"
+ ^
+one error found
diff --git a/test/files/neg/bug935.scala b/test/files/neg/bug935.scala
new file mode 100644
index 0000000000..4497e0812e
--- /dev/null
+++ b/test/files/neg/bug935.scala
@@ -0,0 +1,6 @@
+object Test3 {
+ class E[T >: Nothing <: String](s: T) extends Annotation
+ class B
+ // val a = new E[B](new B)
+ @E[B](new B) val b = "hi"
+} \ No newline at end of file