summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-03-17 22:01:30 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-17 22:01:30 -0700
commit752aa52207bf0e29baeccf2ac369e80f257821b1 (patch)
treee076cdb998e1adc7caa3865c329e396c920dc77b
parent44af7449d137467079a610f6a702dc10a1fc9472 (diff)
parent174334b9095be2be79c164bbdea1749dab9e0cbe (diff)
downloadscala-752aa52207bf0e29baeccf2ac369e80f257821b1.tar.gz
scala-752aa52207bf0e29baeccf2ac369e80f257821b1.tar.bz2
scala-752aa52207bf0e29baeccf2ac369e80f257821b1.zip
Merge pull request #2253 from retronym/ticket/7239
SI-6921 SI-7239 Tread lightly during exploratory typing
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--test/files/pos/t6921.scala11
-rw-r--r--test/files/pos/t7239.scala38
4 files changed, 52 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 1c60f0a79d..f3736f1519 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -502,7 +502,7 @@ trait NamesDefaults { self: Analyzer =>
// disable conforms as a view...
val errsBefore = reporter.ERROR.count
try typer.silent { tpr =>
- val res = tpr.typed(arg, subst(paramtpe))
+ val res = tpr.typed(arg.duplicate, subst(paramtpe))
// better warning for SI-5044: if `silent` was not actually silent give a hint to the user
// [H]: the reason why `silent` is not silent is because the cyclic reference exception is
// thrown in a context completely different from `context` here. The exception happens while
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 93d24996eb..ef28837c51 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1375,9 +1375,8 @@ trait Typers extends Modes with Adaptations with Tags {
def onError(reportError: => Tree): Tree = {
context.tree match {
case Apply(tree1, args) if (tree1 eq tree) && args.nonEmpty =>
- silent(_.typedArgs(args, mode)) match {
- case SilentResultValue(xs) =>
- val args = xs.asInstanceOf[List[Tree]]
+ silent(_.typedArgs(args.map(_.duplicate), mode)) match {
+ case SilentResultValue(args) =>
if (args exists (_.isErrorTyped))
reportError
else
diff --git a/test/files/pos/t6921.scala b/test/files/pos/t6921.scala
new file mode 100644
index 0000000000..36e70e5d2c
--- /dev/null
+++ b/test/files/pos/t6921.scala
@@ -0,0 +1,11 @@
+class Message(messageType: String, reason: Option[String])
+
+class ReproForSI6921 {
+
+ private[this] var reason = ""
+
+ def decideElection = {
+ val explanation = None
+ new Message("", reason = explanation)
+ }
+}
diff --git a/test/files/pos/t7239.scala b/test/files/pos/t7239.scala
new file mode 100644
index 0000000000..16e9d00f17
--- /dev/null
+++ b/test/files/pos/t7239.scala
@@ -0,0 +1,38 @@
+object Test {
+ def BrokenMethod(): HasFilter[(Int, String)] = ???
+
+ trait HasFilter[B] {
+ def filter(p: B => Boolean) = ???
+ }
+
+ trait HasWithFilter {
+ def withFilter = ???
+ }
+
+ object addWithFilter {
+ trait NoImplicit
+ implicit def enrich(v: Any)
+ (implicit F0: NoImplicit): HasWithFilter = ???
+ }
+
+ BrokenMethod().withFilter(_ => true) // okay
+ BrokenMethod().filter(_ => true) // okay
+
+ locally {
+ import addWithFilter._
+ BrokenMethod().withFilter((_: (Int, String)) => true) // okay
+ }
+
+ locally {
+ import addWithFilter._
+ // adaptToMemberWithArgs sets the type of the tree `x`
+ // to ErrorType (while in silent mode, so the error is not
+ // reported. Later, when the fallback from `withFilter`
+ // to `filter` is attempted, the closure is taken to have
+ // have the type `<error> => Boolean`, which conforms to
+ // `(B => Boolean)`. Only later during pickling does the
+ // defensive check for erroneous types in the tree pick up
+ // the problem.
+ BrokenMethod().withFilter(x => true) // erroneous or inaccessible type.
+ }
+}