summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library-src.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala7
-rw-r--r--src/library/scala/Predef.scala14
-rw-r--r--test/files/neg/t0590.check5
10 files changed, 44 insertions, 18 deletions
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index d3bbd16629..c125aae2c9 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-972d3a12779e2cee43fc4f0085710f5a5f908479 ?scala-compiler.jar
+8295eeb50cc3863605e6bf774fe06b464e416262 ?scala-compiler.jar
diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1
index fac8ce0f24..d841bc5f28 100644
--- a/lib/scala-library-src.jar.desired.sha1
+++ b/lib/scala-library-src.jar.desired.sha1
@@ -1 +1 @@
-874a57a6804e974f66aa71014d6823fb88e6a12a ?scala-library-src.jar
+77a930b105649c63bab0894fb44c633d3d915f58 ?scala-library-src.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index b29dd577af..5c46624893 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-065eca5c251e3750915ea6e8ea9409653a5e5490 ?scala-library.jar
+bdfb4d0bc539178810d030d85089ed18eb89d403 ?scala-library.jar
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 150cc9a12d..0f6fd6a944 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -111,7 +111,6 @@ trait Definitions {
if (!ClassClass.unsafeTypeParams.isEmpty && !phase.erasedTypes)
appliedType(ClassClass.tpe, List(classType))
else ClassClass.tpe
- def Predef_identity = getMember(PredefModule, nme.identity)
def Predef_error = getMember(PredefModule, nme.error)
lazy val ConsoleModule: Symbol = getModule("scala.Console")
lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime")
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index baeea7273a..885af91fdb 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -295,7 +295,6 @@ trait StdNames {
val hashCode_ = newTermName("hashCode")
val hasNext = newTermName("hasNext")
val head = newTermName("head")
- val identity = newTermName("identity")
val invoke_ = newTermName("invoke")
val isInstanceOf_ = newTermName("isInstanceOf")
val isDefinedAt = newTermName("isDefinedAt")
@@ -403,6 +402,9 @@ trait StdNames {
// Stores Java annotations on parameters with RetentionPolicy.RUNTIME
val RuntimeParamAnnotationATTR = newTermName("RuntimeVisibleParameterAnnotations")
val ScalaATTR = newTermName("Scala")
+
+ newTermName("utterweirdness") // (adriaan) removed newTermName("identity"),
+ // but if I don't give something in return, quick.lib (after newstarr) fails with "error: not found: value Nil"
}
def encode(str: String): Name = newTermName(NameTransformer.encode(str))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index dc00955e0b..bce3c4a5ee 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -247,16 +247,17 @@ self: Analyzer =>
private def typedImplicit(info: ImplicitInfo): SearchResult =
context.openImplicits find (dominates(pt, _)) match {
case Some(pending) =>
- //println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams)
+ // println("Pending implicit "+pending+" dominates "+pt+"/"+undetParams) //@MDEBUG
throw DivergentImplicit
SearchFailure
case None =>
try {
context.openImplicits = pt :: context.openImplicits
- //println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt)
+ // println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG
typedImplicit0(info)
} catch {
case DivergentImplicit =>
+ // println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG
if (context.openImplicits.tail.isEmpty) {
if (!(pt.isErroneous))
context.unit.error(
@@ -413,16 +414,17 @@ self: Analyzer =>
* This is the case if all of the following holds:
* - the info's type is not erroneous,
* - the info is not shadowed by another info with the same name,
- * - if the symbol is Predef.identity, then we are not looking for a view,
* - the result of typedImplicit is non-empty.
* @return A search result with an attributed tree containing the implicit if succeeded,
* SearchFailure if not.
*/
def tryImplicit(info: ImplicitInfo): SearchResult =
- if (!containsError(info.tpe) &&
- !(isLocal && shadowed.contains(info.name)) &&
- (!isView || info.sym != Predef_identity)) typedImplicit(info)
- else SearchFailure
+ if (containsError(info.tpe) ||
+ (isLocal && shadowed.contains(info.name)) //||
+ // (isView && (info.sym == Predef_identity || info.sym == Predef_conforms})) //@M this condition prevents no-op conversions, which are a problem (besides efficiency),
+ // one example is removeNames in NamesDefaults, which relies on the type checker failing in case of ambiguity between an assignment/named arg
+ ) SearchFailure
+ else typedImplicit(info)
def appInfos(is: List[ImplicitInfo]): Map[ImplicitInfo, SearchResult] = {
var applicable = Map[ImplicitInfo, SearchResult]()
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 482c53fac5..9d485cc730 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -390,9 +390,16 @@ trait NamesDefaults { self: Analyzer =>
argPos(index) = pos
rhs
case t: Tree =>
- errorTree(arg, "reference to "+ name +" is ambiguous; it is both, a parameter\n"+
+ //@M was: errorTree(arg, ...)
+ // this throws an exception that's caught in `tryTypedApply` (as it uses `silent`)
+ // unfortunately, tryTypedApply recovers from the exception if you use errorTree(arg, ...) and conforms is allowed as a view (see tryImplicit in Implicits)
+ // because it tries to produce a new qualifier (if the old one was P, the new one will be conforms.apply(P)), and if that works, it pretends nothing happened
+ // so, to make sure tryTypedApply fails, pass EmptyTree instead
+ errorTree(EmptyTree, "reference to "+ name +" is ambiguous; it is both, a parameter\n"+
"name of the method and the name of a variable currently in scope.")
}
+ //@M note that we don't get here when an ambiguity was detected (during the computation of res),
+ // as errorTree throws an exception
typer.context.undetparams = udp
res
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 745d1c8241..b609f1f24b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -991,7 +991,12 @@ trait Typers { self: Analyzer =>
if (qual.isTerm &&
((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) &&
phase.id <= currentRun.typerPhase.id && !qtpe.isError && !tp.isError &&
- qtpe.typeSymbol != NullClass && qtpe.typeSymbol != NothingClass && qtpe != WildcardType) {
+ qtpe.typeSymbol != NullClass && qtpe.typeSymbol != NothingClass && qtpe != WildcardType &&
+ context.implicitsEnabled) { // don't try to adapt a top-level type that's the subject of an implicit search
+ // this happens because, if isView, typedImplicit tries to apply the "current" implicit value to
+ // a value that needs to be coerced, so we check whether the implicit value has an `apply` method
+ // (if we allow this, we get divergence, e.g., starting at `conforms` during ant quick.bin)
+ // note: implicit arguments are still inferred (this kind of "chaining" is allowed)
val coercion = inferView(qual, qtpe, name, tp)
if (coercion != EmptyTree)
typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual))))
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 565aa363e8..aa718e1892 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -76,6 +76,10 @@ object Predef {
val Map = collection.immutable.Map
val Set = collection.immutable.Set
+ // no longer a view: subsumed by `conforms` (which is less likely to give rise to ambiguities)
+ // @see `conforms` for the implicit version
+ def identity[A](x: A): A = x
+
// errors and asserts -------------------------------------------------
def error(message: String): Nothing = throw new RuntimeException(message)
@@ -180,8 +184,6 @@ object Predef {
// views --------------------------------------------------------------
- implicit def identity[A](x: A): A = x
-
implicit def byteWrapper(x: Byte) = new runtime.RichByte(x)
implicit def shortWrapper(x: Short) = new runtime.RichShort(x)
implicit def intWrapper(x: Int) = new runtime.RichInt(x)
@@ -249,5 +251,13 @@ object Predef {
override def toString: String = xs.mkString("")
}
+ // used, for example, in the encoding of generalized constraints
+ // we need a new type constructor `<:<` and evidence `conforms`, as
+ // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred)
+ // to constrain any abstract type T that's in scope in a method's argument list (not just the method's own type parameters)
+ // simply add an implicit argument of type `T <:< U`, where U is the required upper bound (for lower-bounds, use: `U <: T`)
+ sealed abstract class <:<[-From, +To] extends (From => To)
+ implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}
+
def currentThread = java.lang.Thread.currentThread()
}
diff --git a/test/files/neg/t0590.check b/test/files/neg/t0590.check
index b928c1cb76..a3ef70c6cd 100644
--- a/test/files/neg/t0590.check
+++ b/test/files/neg/t0590.check
@@ -1,5 +1,6 @@
-t0590.scala:2: error: diverging implicit expansion for type (Null(null)) => T
-starting with method foo in object Test
+t0590.scala:2: error: type mismatch;
+ found : Null(null)
+ required: T
implicit def foo[T] : T = null
^
one error found