From 803488f3e2e1074c373cac55d8d4c08ac4a07eb9 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 25 Jan 2007 15:50:26 +0000 Subject: 1. 2. More detailed error messages for ambiguous implicits. 3. Relaxed rules for necessary overlap in pattern matching --- src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 15 +++++++++++++++ src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Infer.scala | 7 +++++++ src/compiler/scala/tools/nsc/typechecker/Typers.scala | 3 ++- src/library/scala/Stream.scala | 2 +- test/files/neg/bug900.check | 10 ++++++++++ test/files/neg/bug900.scala | 5 +++++ test/files/neg/implicits.check | 5 ++++- test/files/neg/nopredefs.check | 4 ++++ test/files/neg/nopredefs.scala | 6 ++++++ test/files/neg/viewtest.check | 2 +- test/files/pos/bug911.scala | 6 ++++++ 12 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 test/files/neg/bug900.check create mode 100644 test/files/neg/bug900.scala create mode 100644 test/files/neg/nopredefs.check create mode 100644 test/files/neg/nopredefs.scala create mode 100644 test/files/pos/bug911.scala diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 5b4622a984..13980856ec 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -225,4 +225,19 @@ abstract class TreeInfo { case AppliedTypeTree(fn, _) => methPart(fn) case _ => tree } + + /** Top-level definition sequence contains a leading import of Predef or scala.Predef + */ + def containsLeadingPredefImport(defs: List[Tree]): boolean = defs match { + case List(PackageDef(_, defs1)) => + containsLeadingPredefImport(defs1) + case Import(Ident(nme.Predef), _) :: _ => + true + case Import(Select(Ident(nme.scala_), nme.Predef), _) :: _ => + true + case Import(_, _) :: defs1 => + containsLeadingPredefImport(defs1) + case _ => + false + } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 2e4742e94c..a77098a50f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -51,7 +51,7 @@ trait Contexts requires Analyzer { addImport(JavaLangPackage) assert(ScalaPackage ne null, "Scala package is null") addImport(ScalaPackage) - if (!settings.nopredefs.value/* || unit.source.file.name != "Predef.scala"*/) + if (!(settings.nopredefs.value || treeInfo.containsLeadingPredefImport(List(unit.body)))) addImport(PredefModule) } val c = sc.make(unit, tree, sc.owner, sc.scope, sc.imports) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 983e72c75f..589e36b5d3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -915,6 +915,13 @@ trait Infer requires Analyzer { } } + object approximateAbstracts extends TypeMap { + def apply(tp: Type): Type = tp match { + case TypeRef(pre, sym, _) if sym.isAbstractType => WildcardType + case _ => mapOver(tp) + } + } + /** A traverser to collect type parameters referred to in a type */ object freeTypeParamsOfTerms extends SymCollector { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6c5462196a..3b3c02ce5b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -630,7 +630,8 @@ trait Typers requires Analyzer { if ((mode & PATTERNmode) != 0) { if ((tree.symbol ne null) && tree.symbol.isModule) inferModulePattern(tree, pt) - if (isPopulated(tree.tpe, pt)) return tree + if (isPopulated(tree.tpe, approximateAbstracts(pt))) + return tree } val tree1 = constfold(tree, pt) // (10) (11) if (tree1.tpe <:< pt) adapt(tree1, mode, pt) diff --git a/src/library/scala/Stream.scala b/src/library/scala/Stream.scala index e42947512b..6ecc9b768c 100644 --- a/src/library/scala/Stream.scala +++ b/src/library/scala/Stream.scala @@ -192,7 +192,7 @@ trait Stream[+a] extends Seq[a] { */ def elements: Iterator[a] = new Iterator[a] { var current = Stream.this - def hasNext: boolean = !current.isEmpty + def hasNext: Boolean = !current.isEmpty def next: a = { val result = current.head; current = current.tail; result } } diff --git a/test/files/neg/bug900.check b/test/files/neg/bug900.check new file mode 100644 index 0000000000..531ac5bee4 --- /dev/null +++ b/test/files/neg/bug900.check @@ -0,0 +1,10 @@ +bug900.scala:4: error: type mismatch; + found : Foo.this.x.type (with underlying type Foo.this.bar) + required: java.lang.Object +Note that implicit conversions are not applicable because they are ambiguous: + both method any2stringadd in object Predef of type (scala.Any)scala.runtime.StringAdd + and method any2ArrowAssoc in object Predef of type [a](a)scala.Predef.ArrowAssoc[a] + are possible conversion functions from Foo.this.x.type to java.lang.Object + def break(): x.type + ^ +one error found diff --git a/test/files/neg/bug900.scala b/test/files/neg/bug900.scala new file mode 100644 index 0000000000..2d2c857575 --- /dev/null +++ b/test/files/neg/bug900.scala @@ -0,0 +1,5 @@ +trait Foo { + type bar + val x : bar + def break(): x.type +} diff --git a/test/files/neg/implicits.check b/test/files/neg/implicits.check index 9f9f7f1ced..266d92c765 100644 --- a/test/files/neg/implicits.check +++ b/test/files/neg/implicits.check @@ -1,4 +1,7 @@ -implicits.scala:21: error: ambiguous implicit value: +implicits.scala:21: error: type mismatch; + found : Pos + required: ?{val +: ?} +Note that implicit conversions are not applicable because they are ambiguous: most specific definition is: method pos2int in object Super of type (Pos)scala.Int yet alternative definition method any2plus in object Sub of type (scala.Any)Sub.Plus is defined in a subclass. diff --git a/test/files/neg/nopredefs.check b/test/files/neg/nopredefs.check new file mode 100644 index 0000000000..0a0ab34482 --- /dev/null +++ b/test/files/neg/nopredefs.check @@ -0,0 +1,4 @@ +nopredefs.scala:5: error: not found: value Set + val y = Set(3) + ^ +one error found diff --git a/test/files/neg/nopredefs.scala b/test/files/neg/nopredefs.scala new file mode 100644 index 0000000000..1128b18934 --- /dev/null +++ b/test/files/neg/nopredefs.scala @@ -0,0 +1,6 @@ +import Predef.{Set => _, _} + +object Test { + val x = Map(1 -> 2) + val y = Set(3) +} diff --git a/test/files/neg/viewtest.check b/test/files/neg/viewtest.check index d84d03fe24..2b1b2c4cbc 100644 --- a/test/files/neg/viewtest.check +++ b/test/files/neg/viewtest.check @@ -3,7 +3,7 @@ viewtest.scala:43: error: type mismatch; required: scala.List[a(in method view3)] case y1: List[a] => compareLists(x, y1) ^ -viewtest.scala:104: error: ambiguous implicit value: +viewtest.scala:104: error: ambiguous implicit values: both method view4 in object O of type [a](a)a and method identity in object Predef of type [a](a)a match expected type (test.Str) => test.Ordered[test.Str] diff --git a/test/files/pos/bug911.scala b/test/files/pos/bug911.scala new file mode 100644 index 0000000000..224b14cda3 --- /dev/null +++ b/test/files/pos/bug911.scala @@ -0,0 +1,6 @@ +object Test { +def foo : Any = { + case class Foo {} + Foo; +} +} -- cgit v1.2.3