Skip to content

Commit cb06328

Browse files
committed
SI-2405 Confer implicit privileges to renamed imports.
Yin and yang would be pleased: A fix in two parts. 1. Use the name of the imported symbol, rather than the alias, in the generated Select(qual, name) tree. 2. Do the opposite in isQualifyingImplicit, which performs one part of the shadowing check. But there is still work to do. The second part of the shadowing check, nonImplicitSynonymInScope, fails to notice this case (irrespective of aliased imports). // Expecting shadowing #2. Alas, none is cast! object Test1 { object A { implicit val x: Int = 1 } import A.x def x: Int = 0 implicitly[Int] } I'm hitching the residual problem to SI-4270's wagon.
1 parent f406550 commit cb06328

File tree

6 files changed

+60
-5
lines changed

6 files changed

+60
-5
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,16 +598,16 @@ trait Contexts { self: Analyzer =>
598598
* it is accessible, and if it is imported there is not already a local symbol
599599
* with the same names. Local symbols override imported ones. This fixes #2866.
600600
*/
601-
private def isQualifyingImplicit(sym: Symbol, pre: Type, imported: Boolean) =
601+
private def isQualifyingImplicit(name: Name, sym: Symbol, pre: Type, imported: Boolean) =
602602
sym.isImplicit &&
603603
isAccessible(sym, pre) &&
604604
!(imported && {
605-
val e = scope.lookupEntry(sym.name)
605+
val e = scope.lookupEntry(name)
606606
(e ne null) && (e.owner == scope)
607607
})
608608

609609
private def collectImplicits(syms: List[Symbol], pre: Type, imported: Boolean = false): List[ImplicitInfo] =
610-
for (sym <- syms if isQualifyingImplicit(sym, pre, imported)) yield
610+
for (sym <- syms if isQualifyingImplicit(sym.name, sym, pre, imported)) yield
611611
new ImplicitInfo(sym.name, pre, sym)
612612

613613
private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = {
@@ -621,7 +621,7 @@ trait Contexts { self: Analyzer =>
621621
var impls = collect(sels1) filter (info => info.name != from)
622622
if (to != nme.WILDCARD) {
623623
for (sym <- imp.importedSymbol(to).alternatives)
624-
if (isQualifyingImplicit(sym, pre, imported = true))
624+
if (isQualifyingImplicit(to, sym, pre, imported = true))
625625
impls = new ImplicitInfo(to, pre, sym) :: impls
626626
}
627627
impls

src/compiler/scala/tools/nsc/typechecker/Implicits.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,11 @@ trait Implicits {
554554

555555
val itree = atPos(pos.focus) {
556556
if (info.pre == NoPrefix) Ident(info.name)
557-
else Select(gen.mkAttributedQualifier(info.pre), info.name)
557+
else {
558+
// SI-2405 Not info.name, which might be an aliased import
559+
val implicitMemberName = info.sym.name
560+
Select(gen.mkAttributedQualifier(info.pre), implicitMemberName)
561+
}
558562
}
559563
printTyping("typedImplicit1 %s, pt=%s, from implicit %s:%s".format(
560564
typeDebug.ptTree(itree), wildPt, info.name, info.tpe)

test/files/neg/t2405.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
t2405.scala:6: warning: imported `y' is permanently hidden by definition of method y
2+
import A.{x => y}
3+
^
4+
t2405.scala:8: error: could not find implicit value for parameter e: Int
5+
implicitly[Int]
6+
^
7+
one warning found
8+
one error found

test/files/neg/t2405.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object A { implicit val x: Int = 1 }
2+
3+
// Expecting shadowing #1
4+
object Test2 {
5+
{
6+
import A.{x => y}
7+
def y: Int = 0
8+
implicitly[Int]
9+
}
10+
}

test/files/neg/t2405b.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object A { implicit val x: Int = 1 }
2+
3+
// Expecting shadowing #1
4+
object Test2 {
5+
{
6+
import A.{x => y}
7+
def y: Int = 0
8+
implicitly[Int]
9+
}
10+
}

test/files/pos/t2405.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
object A { implicit val x: Int = 1 }
2+
3+
// Problem as stated in the ticket.
4+
object Test1 {
5+
import A.{x => y}
6+
implicitly[Int]
7+
}
8+
9+
// Testing for the absense of shadowing #1.
10+
object Test2 {
11+
import A.{x => y}
12+
val x = 2
13+
implicitly[Int]
14+
}
15+
16+
// Testing for the absense of shadowing #2.
17+
object Test3 {
18+
{
19+
import A.{x => y}
20+
def x: Int = 0
21+
implicitly[Int]
22+
}
23+
}

0 commit comments

Comments
 (0)