aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala5
-rw-r--r--src/dotty/tools/dotc/typer/Mode.scala5
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/neg/arrayclone-new.scala38
4 files changed, 47 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index b03bcfcf9..841390ef1 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -491,7 +491,7 @@ trait Implicits { self: Typer =>
pt)
val generated1 = adapt(generated, pt)
lazy val shadowing =
- typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.setNewTyperState)
+ typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.setNewTyperState.addMode(Mode.ImplicitShadowing))
def refMatches(shadowing: Tree): Boolean =
ref.symbol == closureBody(shadowing).symbol || {
shadowing match {
@@ -501,7 +501,8 @@ trait Implicits { self: Typer =>
}
if (ctx.typerState.reporter.hasErrors)
nonMatchingImplicit(ref)
- else if (contextual && !shadowing.tpe.isError && !refMatches(shadowing)) {
+ else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
+ !shadowing.tpe.isError && !refMatches(shadowing)) {
implicits.println(i"SHADOWING $ref in ${ref.termSymbol.owner} is shadowed by $shadowing in ${shadowing.symbol.owner}")
shadowedImplicit(ref, methPart(shadowing).tpe)
}
diff --git a/src/dotty/tools/dotc/typer/Mode.scala b/src/dotty/tools/dotc/typer/Mode.scala
index 8889cf604..e84ef2784 100644
--- a/src/dotty/tools/dotc/typer/Mode.scala
+++ b/src/dotty/tools/dotc/typer/Mode.scala
@@ -68,5 +68,10 @@ object Mode {
*/
val Printing = newMode(10, "Printing")
+ /** We are currently typechecking an ident to determine whether some implicit
+ * is shadowed - don't do any other shadowing tests.
+ */
+ val ImplicitShadowing = newMode(11, "ImplicitShadowing")
+
val PatternOrType = Pattern | Type
}
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index a7123602b..0a6127580 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -137,6 +137,7 @@ class tests extends CompilerTest {
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 5)
+ @Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2)
@Test def run_all = runFiles(runDir)
diff --git a/tests/neg/arrayclone-new.scala b/tests/neg/arrayclone-new.scala
new file mode 100644
index 000000000..4e33a7d8c
--- /dev/null
+++ b/tests/neg/arrayclone-new.scala
@@ -0,0 +1,38 @@
+// Run with -explaintypes to see information about shadowing failures
+import scala.reflect.{ClassTag, classTag}
+
+object Test extends dotty.runtime.LegacyApp{
+ ObjectArrayClone;
+ PolymorphicArrayClone;
+}
+
+object ObjectArrayClone{
+ val it : Array[String] = Array("1", "0");
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = "0";
+ assert(it(0) == "1")
+}
+
+object PolymorphicArrayClone{
+ def testIt[T](it : Array[T], one : T, zero : T) = {
+ val cloned = it.clone();
+ assert(cloned.sameElements(it));
+ cloned(0) = zero;
+ assert(it(0) == one)
+ }
+
+ testIt(Array("one", "two"), "one", "two");
+
+ class Mangler[T: ClassTag](ts : T*){
+ // this will always be a BoxedAnyArray even after we've unboxed its contents.
+ val it = ts.toArray[T];
+ }
+
+ val mangled = new Mangler[Int](0, 1);
+
+ val y : Array[Int] = mangled.it; // make sure it's unboxed
+
+ testIt(mangled.it, 0, 1);
+}
+