summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala9
-rw-r--r--test/files/neg/bug2144.check4
-rw-r--r--test/files/neg/bug2144.scala3
3 files changed, 14 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 2b3a8561d8..e64abf9204 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1700,8 +1700,13 @@ trait Typers { self: Analyzer =>
computeParamAliases(meth.owner, vparamss1, rhs1)
if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen) rhs1 = checkDead(rhs1)
- if (meth.owner.isRefinementClass && meth.allOverriddenSymbols.isEmpty)
- for (vparams <- ddef.vparamss; vparam <- vparams)
+ // If only refinement owned methods are checked, invalid code can result; see ticket #2144.
+ def requiresStructuralCheck = meth.allOverriddenSymbols.isEmpty && (
+ meth.owner.isRefinementClass ||
+ (!meth.isConstructor && !meth.isSetter && meth.owner.isAnonymousClass)
+ )
+ if (requiresStructuralCheck)
+ for (vparam <- ddef.vparamss.flatten)
checkStructuralCondition(meth.owner, vparam)
if (phase.id <= currentRun.typerPhase.id && meth.owner.isClass &&
diff --git a/test/files/neg/bug2144.check b/test/files/neg/bug2144.check
new file mode 100644
index 0000000000..ba3238dcf9
--- /dev/null
+++ b/test/files/neg/bug2144.check
@@ -0,0 +1,4 @@
+bug2144.scala:2: error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement
+ def foo[A](a: A) = new { def bar(x: A): A = x }
+ ^
+one error found
diff --git a/test/files/neg/bug2144.scala b/test/files/neg/bug2144.scala
new file mode 100644
index 0000000000..af9a5e166e
--- /dev/null
+++ b/test/files/neg/bug2144.scala
@@ -0,0 +1,3 @@
+object Test {
+ def foo[A](a: A) = new { def bar(x: A): A = x }
+}