Skip to content

Commit 0a50465

Browse files
committed
Merge pull request scala#666 from dotty-staging/fix/shadowing-so
Fix stack overflow when testing for shadowing
2 parents 05e81c1 + 084d4bd commit 0a50465

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ trait Implicits { self: Typer =>
491491
pt)
492492
val generated1 = adapt(generated, pt)
493493
lazy val shadowing =
494-
typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.setNewTyperState)
494+
typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.setNewTyperState.addMode(Mode.ImplicitShadowing))
495495
def refMatches(shadowing: Tree): Boolean =
496496
ref.symbol == closureBody(shadowing).symbol || {
497497
shadowing match {
@@ -501,7 +501,8 @@ trait Implicits { self: Typer =>
501501
}
502502
if (ctx.typerState.reporter.hasErrors)
503503
nonMatchingImplicit(ref)
504-
else if (contextual && !shadowing.tpe.isError && !refMatches(shadowing)) {
504+
else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
505+
!shadowing.tpe.isError && !refMatches(shadowing)) {
505506
implicits.println(i"SHADOWING $ref in ${ref.termSymbol.owner} is shadowed by $shadowing in ${shadowing.symbol.owner}")
506507
shadowedImplicit(ref, methPart(shadowing).tpe)
507508
}

src/dotty/tools/dotc/typer/Mode.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,10 @@ object Mode {
6868
*/
6969
val Printing = newMode(10, "Printing")
7070

71+
/** We are currently typechecking an ident to determine whether some implicit
72+
* is shadowed - don't do any other shadowing tests.
73+
*/
74+
val ImplicitShadowing = newMode(11, "ImplicitShadowing")
75+
7176
val PatternOrType = Pattern | Type
7277
}

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class tests extends CompilerTest {
137137
@Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
138138
@Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8)
139139
@Test def neg_selfInheritance = compileFile(negDir, "selfInheritance", xerrors = 5)
140+
@Test def neg_shadowedImplicits = compileFile(negDir, "arrayclone-new", xerrors = 2)
140141

141142
@Test def run_all = runFiles(runDir)
142143

tests/neg/arrayclone-new.scala

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Run with -explaintypes to see information about shadowing failures
2+
import scala.reflect.{ClassTag, classTag}
3+
4+
object Test extends dotty.runtime.LegacyApp{
5+
ObjectArrayClone;
6+
PolymorphicArrayClone;
7+
}
8+
9+
object ObjectArrayClone{
10+
val it : Array[String] = Array("1", "0");
11+
val cloned = it.clone();
12+
assert(cloned.sameElements(it));
13+
cloned(0) = "0";
14+
assert(it(0) == "1")
15+
}
16+
17+
object PolymorphicArrayClone{
18+
def testIt[T](it : Array[T], one : T, zero : T) = {
19+
val cloned = it.clone();
20+
assert(cloned.sameElements(it));
21+
cloned(0) = zero;
22+
assert(it(0) == one)
23+
}
24+
25+
testIt(Array("one", "two"), "one", "two");
26+
27+
class Mangler[T: ClassTag](ts : T*){
28+
// this will always be a BoxedAnyArray even after we've unboxed its contents.
29+
val it = ts.toArray[T];
30+
}
31+
32+
val mangled = new Mangler[Int](0, 1);
33+
34+
val y : Array[Int] = mangled.it; // make sure it's unboxed
35+
36+
testIt(mangled.it, 0, 1);
37+
}
38+

0 commit comments

Comments
 (0)