Skip to content
Permalink
Browse files

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.
  • Loading branch information
retronym committed May 22, 2012
1 parent f406550 commit 820897b978ee6837ca463b186bab0f6349807c18
@@ -598,16 +598,16 @@ trait Contexts { self: Analyzer =>
* it is accessible, and if it is imported there is not already a local symbol
* with the same names. Local symbols override imported ones. This fixes #2866.
*/
private def isQualifyingImplicit(sym: Symbol, pre: Type, imported: Boolean) =
private def isQualifyingImplicit(name: Name, sym: Symbol, pre: Type, imported: Boolean) =
sym.isImplicit &&
isAccessible(sym, pre) &&
!(imported && {
val e = scope.lookupEntry(sym.name)
val e = scope.lookupEntry(name)
(e ne null) && (e.owner == scope)
})

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

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

val itree = atPos(pos.focus) {
if (info.pre == NoPrefix) Ident(info.name)
else Select(gen.mkAttributedQualifier(info.pre), info.name)
else {
// SI-2405 Not info.name, which might be an aliased import
val implicitMemberName = info.sym.name
Select(gen.mkAttributedQualifier(info.pre), implicitMemberName)
}
}
printTyping("typedImplicit1 %s, pt=%s, from implicit %s:%s".format(
typeDebug.ptTree(itree), wildPt, info.name, info.tpe)
@@ -0,0 +1,8 @@
t2405.scala:6: warning: imported `y' is permanently hidden by definition of method y
import A.{x => y}
^
t2405.scala:8: error: could not find implicit value for parameter e: Int
implicitly[Int]
^
one warning found
one error found
@@ -0,0 +1,10 @@
object A { implicit val x: Int = 1 }

// Expecting shadowing #1
object Test2 {
{
import A.{x => y}
def y: Int = 0
implicitly[Int]
}
}
@@ -0,0 +1,23 @@
object A { implicit val x: Int = 1 }

// Problem as stated in the ticket.
object Test1 {
import A.{x => y}
implicitly[Int]
}

// Testing for the absense of shadowing #1.
object Test2 {
import A.{x => y}
val x = 2
implicitly[Int]
}

// Testing for the absense of shadowing #2.
object Test3 {
{
import A.{x => y}
def x: Int = 0
implicitly[Int]
}
}

0 comments on commit 820897b

Please sign in to comment.
You can’t perform that action at this time.