Skip to content

Commit 3966b08

Browse files
committed
Fix #1857: Allow lower bounds in to influence implicit search
The previous implementation claimed to conform to the spec: We exclude lower bounds to conform to SLS 7.2: "The parts of a type T are: [...] if T is an abstract type, the parts of its upper bound" But in fact we do not need to exclude lower bounds from `namedPartsWith` to do that - TypeRefs are already lifted to classes, which implements SLS 7.2. Including lower bounds does affect wildcard types (i1857.scala) and wildcard parameters in implicits (implicit-lower-bound.scala), but the spec does not exclude either if these.
1 parent 5b1b747 commit 3966b08

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,7 @@ trait ImplicitRunInfo { self: Run =>
459459
}
460460
tp.classSymbols(liftingCtx) foreach addClassScope
461461
case _ =>
462-
// We exclude lower bounds to conform to SLS 7.2:
463-
// "The parts of a type T are: [...] if T is an abstract type, the parts of its upper bound"
464-
for (part <- tp.namedPartsWith(_.isType, excludeLowerBounds = true))
465-
comps ++= iscopeRefs(part)
462+
for (part <- tp.namedPartsWith(_.isType)) comps ++= iscopeRefs(part)
466463
}
467464
comps
468465
}

tests/pos/i1857.scala

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package commandeer
2+
3+
4+
trait CommandeerDSL[Host] {
5+
trait Operation[T]
6+
type Op[T] <: Operation[T]
7+
}
8+
9+
object CommandeerDSL {
10+
def apply[Host, DSL <: CommandeerDSL[Host]](host: Host)(implicit dsl: DSL): DSL = dsl
11+
}
12+
13+
trait Foo {
14+
def bar(a: String, b: Int): Double
15+
}
16+
17+
object Foo {
18+
implicit val fooDSL: FooDSL = new FooDSL {}
19+
}
20+
21+
trait FooDSL extends CommandeerDSL[Foo] {
22+
sealed trait FooOperation[T] extends Operation[T]
23+
type Op[T] = FooOperation[T]
24+
25+
case class Bar(a: String, b: Int) extends FooOperation[Double]
26+
}
27+
28+
object RunMe {
29+
//import Foo._
30+
def main(args: Array[String]): Unit = {
31+
println("Hi Mum")
32+
33+
val kevin = CommandeerDSL(null.asInstanceOf[Foo])
34+
println(s"Found DSL for Foo: $kevin")
35+
val bar = kevin.Bar("bob", 3)
36+
println(s"Made a bar: $bar")
37+
}
38+
}

tests/neg/implicit-lower-bound.scala renamed to tests/pos/implicit-lower-bound.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ class Test {
99
def get1(implicit lf: List[_ <: Bar]) = {}
1010
def get2(implicit lf: List[_ >: Bar]) = {}
1111

12-
get1 // works
13-
get2 // error
12+
get1
13+
get2
1414
}

0 commit comments

Comments
 (0)