Skip to content

Commit af3ab3b

Browse files
committed
Merge branch 'master' of github.com:lampepfl/dotty
2 parents 99a1db0 + 4126f63 commit af3ab3b

File tree

14 files changed

+74
-110
lines changed

14 files changed

+74
-110
lines changed

compiler/src/dotty/tools/dotc/core/Mode.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ object Mode {
6060
*/
6161
val Printing: Mode = newMode(10, "Printing")
6262

63-
/** We are currently typechecking an ident to determine whether some implicit
64-
* is shadowed - don't do any other shadowing tests.
65-
*/
66-
val ImplicitShadowing: Mode = newMode(11, "ImplicitShadowing")
67-
6863
/** We are currently in a `viewExists` check. In that case, ambiguous
6964
* implicits checks are disabled and we succeed with the first implicit
7065
* found.

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,6 @@ class PlainPrinter(_ctx: Context) extends Printer {
520520
result.reason match {
521521
case _: NoMatchingImplicits => "No Matching Implicit"
522522
case _: DivergingImplicit => "Diverging Implicit"
523-
case _: ShadowedImplicit => "Shadowed Implicit"
524523
case result: AmbiguousImplicits =>
525524
"Ambiguous Implicit: " ~ toText(result.alt1.ref) ~ " and " ~ toText(result.alt2.ref)
526525
case _ =>

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,21 +1182,17 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
11821182
/** Compare to alternatives of an overloaded call or an implicit search.
11831183
*
11841184
* @param alt1, alt2 Non-overloaded references indicating the two choices
1185-
* @param level1, level2 If alternatives come from a comparison of two contextual
1186-
* implicit candidates, the nesting levels of the candidates.
1187-
* In all other cases the nesting levels are both 0.
11881185
* @return 1 if 1st alternative is preferred over 2nd
11891186
* -1 if 2nd alternative is preferred over 1st
11901187
* 0 if neither alternative is preferred over the other
11911188
*
11921189
* An alternative A1 is preferred over an alternative A2 if it wins in a tournament
11931190
* that awards one point for each of the following:
11941191
*
1195-
* - A1 is nested more deeply than A2
1196-
* - The nesting levels of A1 and A2 are the same, and A1's owner derives from A2's owner
1192+
* - A1's owner derives from A2's owner.
11971193
* - A1's type is more specific than A2's type.
11981194
*/
1199-
def compare(alt1: TermRef, alt2: TermRef, nesting1: Int = 0, nesting2: Int = 0)(implicit ctx: Context): Int = track("compare") { trace(i"compare($alt1, $alt2)", overload) {
1195+
def compare(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Int = track("compare") { trace(i"compare($alt1, $alt2)", overload) {
12001196

12011197
assert(alt1 ne alt2)
12021198

@@ -1306,10 +1302,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
13061302

13071303
val owner1 = if (alt1.symbol.exists) alt1.symbol.owner else NoSymbol
13081304
val owner2 = if (alt2.symbol.exists) alt2.symbol.owner else NoSymbol
1309-
val ownerScore =
1310-
if (nesting1 > nesting2) 1
1311-
else if (nesting1 < nesting2) -1
1312-
else compareOwner(owner1, owner2)
1305+
val ownerScore = compareOwner(owner1, owner2)
13131306

13141307
val tp1 = stripImplicit(alt1.widen)
13151308
val tp2 = stripImplicit(alt2.widen)

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

Lines changed: 38 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -437,20 +437,6 @@ object Implicits {
437437
em"${err.refStr(ref)} does not $qualify"
438438
}
439439

440-
class ShadowedImplicit(ref: TermRef,
441-
shadowing: Type,
442-
val expectedType: Type,
443-
val argument: Tree) extends SearchFailureType {
444-
/** same as err.refStr but always prints owner even if it is a term */
445-
def show(ref: Type)(implicit ctx: Context): String = ref match {
446-
case ref: NamedType if ref.symbol.maybeOwner.isTerm =>
447-
i"${ref.symbol} in ${ref.symbol.owner}"
448-
case _ => err.refStr(ref)
449-
}
450-
def explanation(implicit ctx: Context): String =
451-
em"${show(ref)} does $qualify but it is shadowed by ${show(shadowing)}"
452-
}
453-
454440
class DivergingImplicit(ref: TermRef,
455441
val expectedType: Type,
456442
val argument: Tree) extends SearchFailureType {
@@ -534,27 +520,32 @@ trait ImplicitRunInfo { self: Run =>
534520
val comps = new TermRefSet
535521
tp match {
536522
case tp: NamedType =>
537-
val pre = tp.prefix
538-
comps ++= iscopeRefs(pre)
539-
def addRef(companion: TermRef): Unit = {
540-
val compSym = companion.symbol
541-
if (compSym is Package)
542-
addRef(companion.select(nme.PACKAGE))
543-
else if (compSym.exists)
544-
comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef]
545-
}
546-
def addCompanionOf(sym: Symbol) = {
547-
val companion = sym.companionModule
548-
if (companion.exists) addRef(companion.termRef)
549-
}
550-
def addClassScope(cls: ClassSymbol): Unit = {
551-
addCompanionOf(cls)
552-
for (parent <- cls.classParents; ref <- iscopeRefs(tp.baseType(parent.classSymbol)))
553-
addRef(ref)
523+
if (!tp.symbol.is(Package) || ctx.scala2Mode) {
524+
// Don't consider implicits in package prefixes unless under -language:Scala2
525+
val pre = tp.prefix
526+
comps ++= iscopeRefs(pre)
527+
def addRef(companion: TermRef): Unit = {
528+
val compSym = companion.symbol
529+
if (compSym is Package) {
530+
assert(ctx.scala2Mode)
531+
addRef(companion.select(nme.PACKAGE))
532+
}
533+
else if (compSym.exists)
534+
comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef]
535+
}
536+
def addCompanionOf(sym: Symbol) = {
537+
val companion = sym.companionModule
538+
if (companion.exists) addRef(companion.termRef)
539+
}
540+
def addClassScope(cls: ClassSymbol): Unit = {
541+
addCompanionOf(cls)
542+
for (parent <- cls.classParents; ref <- iscopeRefs(tp.baseType(parent.classSymbol)))
543+
addRef(ref)
544+
}
545+
val underlyingTypeSym = tp.widen.typeSymbol
546+
if (underlyingTypeSym.isOpaqueAlias) addCompanionOf(underlyingTypeSym)
547+
else tp.classSymbols(liftingCtx).foreach(addClassScope)
554548
}
555-
val underlyingTypeSym = tp.widen.typeSymbol
556-
if (underlyingTypeSym.isOpaqueAlias) addCompanionOf(underlyingTypeSym)
557-
else tp.classSymbols(liftingCtx).foreach(addClassScope)
558549
case _ =>
559550
for (part <- tp.namedPartsWith(_.isType)) comps ++= iscopeRefs(part)
560551
}
@@ -836,9 +827,6 @@ trait Implicits { self: Typer =>
836827
shortForm
837828
case _ =>
838829
arg.tpe match {
839-
case tpe: ShadowedImplicit =>
840-
i"""$headline;
841-
|${tpe.explanation}."""
842830
case tpe: SearchFailureType =>
843831
i"""$headline.
844832
|I found:
@@ -1034,9 +1022,6 @@ trait Implicits { self: Typer =>
10341022

10351023
private def isCoherent = pt.isRef(defn.EqlClass)
10361024

1037-
private val cmpContext = nestedContext()
1038-
private val cmpCandidates = (c1: Candidate, c2: Candidate) => compare(c1.ref, c2.ref, c1.level, c2.level)(cmpContext)
1039-
10401025
/** The expected type for the searched implicit */
10411026
lazy val fullProto: Type = implicitProto(pt, identity)
10421027

@@ -1050,9 +1035,9 @@ trait Implicits { self: Typer =>
10501035
/** Try to typecheck an implicit reference */
10511036
def typedImplicit(cand: Candidate, contextual: Boolean)(implicit ctx: Context): SearchResult = track("typedImplicit") { trace(i"typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", implicits, show = true) {
10521037
val ref = cand.ref
1053-
var generated: Tree = tpd.ref(ref).withSpan(span.startPos)
1038+
val generated: Tree = tpd.ref(ref).withSpan(span.startPos)
10541039
val locked = ctx.typerState.ownedVars
1055-
val generated1 =
1040+
val adapted =
10561041
if (argument.isEmpty)
10571042
adapt(generated, pt, locked)
10581043
else {
@@ -1074,51 +1059,20 @@ trait Implicits { self: Typer =>
10741059
}
10751060
else tryConversion
10761061
}
1077-
lazy val shadowing =
1078-
typedUnadapted(untpd.Ident(cand.implicitRef.implicitName).withSpan(span.toSynthetic))(
1079-
nestedContext().addMode(Mode.ImplicitShadowing).setExploreTyperState())
1080-
1081-
/** Is candidate reference the same as the `shadowing` reference? (i.e.
1082-
* no actual shadowing occured). This is the case if the
1083-
* underlying symbol of the shadowing reference is the same as the
1084-
* symbol of the candidate reference, or if they have a common type owner.
1085-
*
1086-
* The second condition (same owner) is needed because the candidate reference
1087-
* and the potential shadowing reference are typechecked with different prototypes.
1088-
* so might yield different overloaded symbols. E.g. if the candidate reference
1089-
* is to an implicit conversion generated from an implicit class, the shadowing
1090-
* reference could go to the companion object of that class instead.
1091-
*/
1092-
def refSameAs(shadowing: Tree): Boolean = {
1093-
def symMatches(sym: Symbol): Boolean =
1094-
sym == ref.symbol || sym.owner.isType && sym.owner == ref.symbol.owner
1095-
def denotMatches(d: Denotation): Boolean = d match {
1096-
case d: SingleDenotation => symMatches(d.symbol)
1097-
case d => d.hasAltWith(denotMatches(_))
1098-
}
1099-
denotMatches(closureBody(shadowing).denot)
1100-
}
1101-
11021062
if (ctx.reporter.hasErrors) {
11031063
ctx.reporter.removeBufferedMessages
11041064
SearchFailure {
1105-
generated1.tpe match {
1106-
case _: SearchFailureType => generated1
1107-
case _ => generated1.withType(new MismatchedImplicit(ref, pt, argument))
1065+
adapted.tpe match {
1066+
case _: SearchFailureType => adapted
1067+
case _ => adapted.withType(new MismatchedImplicit(ref, pt, argument))
11081068
}
11091069
}
11101070
}
1111-
else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
1112-
!shadowing.tpe.isError && !refSameAs(shadowing)) {
1113-
implicits.println(i"SHADOWING $ref in ${ref.termSymbol.maybeOwner} is shadowed by $shadowing in ${shadowing.symbol.maybeOwner}")
1114-
SearchFailure(generated1.withTypeUnchecked(
1115-
new ShadowedImplicit(ref, methPart(shadowing).tpe, pt, argument)))
1116-
}
11171071
else {
1118-
val generated2 =
1119-
if (cand.isExtension) Applications.ExtMethodApply(generated1).withType(generated1.tpe)
1120-
else generated1
1121-
SearchSuccess(generated2, ref, cand.level)(ctx.typerState, ctx.gadt)
1072+
val returned =
1073+
if (cand.isExtension) Applications.ExtMethodApply(adapted).withType(adapted.tpe)
1074+
else adapted
1075+
SearchSuccess(returned, ref, cand.level)(ctx.typerState, ctx.gadt)
11221076
}
11231077
}}
11241078

@@ -1143,12 +1097,14 @@ trait Implicits { self: Typer =>
11431097

11441098
/** Search a list of eligible implicit references */
11451099
def searchImplicits(eligible: List[Candidate], contextual: Boolean): SearchResult = {
1100+
11461101
/** Compare previous success with reference and level to determine which one would be chosen, if
11471102
* an implicit starting with the reference was found.
11481103
*/
11491104
def compareCandidate(prev: SearchSuccess, ref: TermRef, level: Int): Int =
11501105
if (prev.ref eq ref) 0
1151-
else nestedContext().test(implicit ctx => compare(prev.ref, ref, prev.level, level))
1106+
else if (prev.level != level) prev.level - level
1107+
else nestedContext().test(implicit ctx => compare(prev.ref, ref))
11521108

11531109
/** If `alt1` is also a search success, try to disambiguate as follows:
11541110
* - If alt2 is preferred over alt1, pick alt2, otherwise return an
@@ -1326,7 +1282,7 @@ trait Implicits { self: Typer =>
13261282
case _: AmbiguousImplicits => failure2
13271283
case _ =>
13281284
reason match {
1329-
case (_: DivergingImplicit) | (_: ShadowedImplicit) => failure
1285+
case (_: DivergingImplicit) => failure
13301286
case _ => List(failure, failure2).maxBy(_.tree.treeSize)
13311287
}
13321288
}

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,7 +2029,6 @@ class Typer extends Namer
20292029
val result = if (ifpt.exists &&
20302030
xtree.isTerm &&
20312031
!untpd.isContextualClosure(xtree) &&
2032-
!ctx.mode.is(Mode.ImplicitShadowing) &&
20332032
!ctx.mode.is(Mode.Pattern) &&
20342033
!ctx.isAfterTyper)
20352034
makeContextualFunction(xtree, ifpt)
@@ -2598,7 +2597,6 @@ class Typer extends Namer
25982597
!untpd.isContextualClosure(tree) &&
25992598
!isApplyProto(pt) &&
26002599
!ctx.mode.is(Mode.Pattern) &&
2601-
!ctx.mode.is(Mode.ImplicitShadowing) &&
26022600
!ctx.isAfterTyper) {
26032601
typr.println(i"insert apply on implicit $tree")
26042602
typed(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt, locked)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package t1000647.bar
2+
3+
import t1000647.foo.{ScalaActorRef}
4+
5+
object DataFlow {
6+
def foo(ref: ScalaActorRef) = ref.stop() // error: value stop is not a member of ...
7+
}

tests/new/package-implicit/DataFlow.scala

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/neg/implicit-shadowing.scala renamed to tests/pos/implicit-shadowing.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ object Test {
44

55
def outer(implicit c: C) = {
66

7-
def f(c: C) = implicitly[C] // error: shadowing
8-
def g(c: Int) = implicitly[C] // error: shadowing (even though type is different)
7+
def f(c: C) = implicitly[C] // now ok: shadowing no longer tested
8+
def g(c: Int) = implicitly[C] // now ok: shadowing no longer tested
99

1010
f(new C)
1111
}

tests/run/i5224.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
barInt
2-
bar
2+
barInt

tests/run/i5224.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ object Test extends App {
1616
def barInt: Unit = ???
1717

1818
implicitly[Bar[Int]]
19+
// used to resolve to bar, but
20+
// resolves to barInt now, since shadowing is no longer tested
1921
}
2022
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
B
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
abstract class A {
2+
def show: String
3+
}
4+
class B extends A {
5+
def show = "B"
6+
}
7+
class C extends A {
8+
def show = "C"
9+
}
10+
object M {
11+
def f given B, C : String = {
12+
implied a for A = infer[B]
13+
infer[A].show
14+
}
15+
}
16+
object Test extends App {
17+
implied b for B
18+
implied c for C
19+
println(M.f)
20+
}

0 commit comments

Comments
 (0)