Skip to content

Commit e651c0f

Browse files
committed
Fix scala#8311: Propagate more information about extension method arguments
1 parent 01e4679 commit e651c0f

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3272,12 +3272,21 @@ class Typer extends Namer
32723272
case IgnoredProto(_: FunOrPolyProto) => false
32733273
case _ => true
32743274
}
3275+
// If the expected type is a selection of an extension method, deepen it
3276+
// to also propagate the argument type (which is the receiver we have
3277+
// typechecked already). This is needed for i8311.scala. Doing so
3278+
// for all expected types does not work since it would block the case
3279+
// where we have an argument that must be converted with another
3280+
// implicit conversion to the receiver type.
3281+
def sharpenedPt = pt match
3282+
case pt: SelectionProto if pt.name.isExtensionName => pt.deepenProto
3283+
case _ => pt
32753284
var resMatch: Boolean = false
32763285
wtp match {
32773286
case wtp: ExprType =>
32783287
readaptSimplified(tree.withType(wtp.resultType))
32793288
case wtp: MethodType if wtp.isImplicitMethod &&
3280-
({ resMatch = constrainResult(tree.symbol, wtp, pt); resMatch } || !functionExpected) =>
3289+
({ resMatch = constrainResult(tree.symbol, wtp, sharpenedPt); resMatch } || !functionExpected) =>
32813290
if (resMatch || ctx.mode.is(Mode.ImplicitsEnabled))
32823291
adaptNoArgsImplicitMethod(wtp)
32833292
else

tests/pos/i8311.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
trait Show[O]:
3+
extension (o: O)
4+
def show: String
5+
6+
class Box[A]
7+
class Foo
8+
9+
object test:
10+
11+
given box[A](using Show[A]) as Show[Box[A]] = _.toString
12+
given foo as Show[Foo] = _.toString
13+
14+
def run(s: Box[Box[Foo]]): Unit =
15+
val x = summon[Show[Box[Box[Foo]]]]
16+
x.extension_show(s)
17+
val r: String = box.extension_show(s)
18+
println(s"step: ${box[Box[Foo]].extension_show(s)}")
19+
println(s"step: ${s.show}")

tests/pos/reference/extension-methods.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ object ExtMethods:
104104
summon[Ord[Lst[Lst[Int]]]]
105105

106106
assert(Lst.ord[Lst[Int]].extension_less(xss)(Lst(Lst(3))))
107-
// fails type inference: assert(xss `less` Lst(Lst(3)))
107+
assert(xss `less` Lst(Lst(3)))
108108
assert(xss.flatten `less` Lst(3))
109109

110110
extension (s: String)

0 commit comments

Comments
 (0)