Skip to content

Commit 74046bb

Browse files
committed
Merge pull request scala#4118 from retronym/ticket/5639
SI-5639 Fix spurious discarding of implicit import
2 parents b2ba80a + a77f01f commit 74046bb

File tree

13 files changed

+185
-15
lines changed

13 files changed

+185
-15
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ trait Contexts { self: Analyzer =>
798798
isAccessible(sym, pre) &&
799799
!(imported && {
800800
val e = scope.lookupEntry(name)
801-
(e ne null) && (e.owner == scope)
801+
(e ne null) && (e.owner == scope) && (!settings.isScala212 || e.sym.exists)
802802
})
803803

804804
private def collectImplicits(syms: Scope, pre: Type, imported: Boolean = false): List[ImplicitInfo] =

test/files/neg/t2866.check

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
t2866.scala:30: warning: imported `one' is permanently hidden by definition of value one
2+
import A.one // warning: imported `one' is permanently hidden by definition of value one.
3+
^
4+
t2866.scala:42: error: ambiguous implicit values:
5+
both value two of type Int
6+
and value one in object A of type => Int
7+
match expected type Int
8+
assert(implicitly[Int] == 2) // !!! Not ambiguous in 2.8.0. Ambigous in 2.7.6
9+
^
10+
t2866.scala:50: error: ambiguous implicit values:
11+
both value two of type Int
12+
and value one in object A of type => Int
13+
match expected type Int
14+
assert(implicitly[Int] == 2) // !!! Not ambiguous in 2.8.0. Ambiguous in 2.7.6
15+
^
16+
one warning found
17+
two errors found

test/files/neg/t2866.scala

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// for 2.7.x compatibility
2+
3+
object A {
4+
implicit val one = 1
5+
}
6+
7+
object Test {
8+
9+
locally {
10+
import A._
11+
locally {
12+
// assert(implicitly[Int] == 1) // error: could not find implicit value for parameter e: Int.
13+
// !!! Why one A.one?
14+
// (I assume you mean: why _not_ A.one? A.one is shadowed by local one.
15+
// but the local one cannot be used yet because it does not have an explicit type.
16+
implicit val one = 2
17+
assert(implicitly[Int] == 2)
18+
assert(one == 2)
19+
}
20+
}
21+
22+
locally {
23+
import A._
24+
implicit val one: Int = 2
25+
assert(implicitly[Int] == 2)
26+
assert(one == 2)
27+
}
28+
29+
locally {
30+
import A.one // warning: imported `one' is permanently hidden by definition of value one.
31+
// !!! Really?
32+
//assert(implicitly[Int] == 1)
33+
implicit val one = 2
34+
assert(implicitly[Int] == 2) // !!! why not 2?
35+
assert(one == 2)
36+
}
37+
38+
locally {
39+
import A.one
40+
assert(implicitly[Int] == 1)
41+
implicit val two = 2
42+
assert(implicitly[Int] == 2) // !!! Not ambiguous in 2.8.0. Ambigous in 2.7.6
43+
}
44+
45+
locally {
46+
import A._
47+
assert(implicitly[Int] == 1)
48+
implicit val two = 2
49+
import A.{one => _}
50+
assert(implicitly[Int] == 2) // !!! Not ambiguous in 2.8.0. Ambiguous in 2.7.6
51+
}
52+
53+
locally {
54+
import A.{one => _, _}
55+
implicit val two = 2
56+
assert(implicitly[Int] == 2) // not ambiguous in 2.8.0 nor im ambiguous in 2.7.6
57+
}
58+
59+
}

test/files/neg/t5639b.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
A_2.scala:6: error: could not find implicit value for parameter e: Int
2+
implicitly[Int]
3+
^
4+
one error found

test/files/neg/t5639b/A_1.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Implicits._
2+
3+
class Baz
4+
5+
object Test {
6+
implicitly[Int]
7+
}
8+
9+
object Implicits {
10+
implicit val Baz: Int = 0
11+
// This implicit was being ignored by `isQualifyingImplicit`
12+
// if the classpath contained a class file for `class Baz`.
13+
// This is because the package scope contains a speculative
14+
// symbol for `object Baz` which is entered by `SymbolLoaders`
15+
// before looking inside the class file. (A Java originated
16+
// classfile results in the class/module symbol pair.)
17+
}

test/files/neg/t5639b/A_2.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Implicits._
2+
3+
class Baz
4+
5+
object Test {
6+
implicitly[Int]
7+
}
8+
9+
object Implicits {
10+
implicit val Baz: Int = 0
11+
}

test/files/pos/t5639.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-Xsource:2.12

test/files/pos/t5639/A_1.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Implicits._
2+
3+
class Baz
4+
5+
object Test {
6+
implicitly[Int]
7+
}
8+
9+
object Implicits {
10+
implicit val Baz: Int = 0
11+
// This implicit was being ignored by `isQualifyingImplicit`
12+
// if the classpath contained a class file for `class Baz`.
13+
// This is because the package scope contains a speculative
14+
// symbol for `object Baz` which is entered by `SymbolLoaders`
15+
// before looking inside the class file. (A Java originated
16+
// classfile results in the class/module symbol pair.)
17+
}

test/files/pos/t5639/A_2.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Implicits._
2+
3+
class Baz
4+
5+
object Test {
6+
implicitly[Int]
7+
}
8+
9+
object Implicits {
10+
implicit val Baz: Int = 0
11+
}

test/files/pos/t5639/Bar.scala

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

test/files/pos/t5639/Foo.scala

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

test/files/run/t2866.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
t2866.scala:30: warning: imported `one' is permanently hidden by definition of value one
2+
import A.one // warning: imported `one' is permanently hidden by definition of value one.
3+
^

test/files/run/t2866.scala

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// for 2.7.x compatibility
2+
3+
object A {
4+
implicit val one = 1
5+
}
6+
7+
object Test extends App {
8+
9+
locally {
10+
import A._
11+
locally {
12+
// assert(implicitly[Int] == 1) // error: could not find implicit value for parameter e: Int.
13+
// !!! Why one A.one?
14+
// (I assume you mean: why _not_ A.one? A.one is shadowed by local one.
15+
// but the local one cannot be used yet because it does not have an explicit type.
16+
implicit val one = 2
17+
assert(implicitly[Int] == 2)
18+
assert(one == 2)
19+
}
20+
}
21+
22+
locally {
23+
import A._
24+
implicit val one: Int = 2
25+
assert(implicitly[Int] == 2)
26+
assert(one == 2)
27+
}
28+
29+
locally {
30+
import A.one // warning: imported `one' is permanently hidden by definition of value one.
31+
// !!! Really?
32+
//assert(implicitly[Int] == 1)
33+
implicit val one = 2
34+
assert(implicitly[Int] == 2) // !!! why not 2?
35+
assert(one == 2)
36+
}
37+
38+
locally {
39+
import A.{one => _, _}
40+
implicit val two = 2
41+
assert(implicitly[Int] == 2) // not ambiguous in 2.8.0 nor im ambiguous in 2.7.6
42+
}
43+
44+
}

0 commit comments

Comments
 (0)