Skip to content

Commit 026b58a

Browse files
committed
Fix scala#8311: Propagate more information about extension method arguments
1 parent e33d36f commit 026b58a

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
@@ -3251,12 +3251,21 @@ class Typer extends Namer
32513251
case IgnoredProto(_: FunOrPolyProto) => false
32523252
case _ => true
32533253
}
3254+
// If the expected type is a selection of an extension method, deepen it
3255+
// to also propagate the argument type (which is the receiver we have
3256+
// typechecked already). This is needed for i8311.scala. Doing so
3257+
// for all expected types does not work since it would block the case
3258+
// where we have an argument that must be converted with another
3259+
// implicit conversion to the receiver type.
3260+
def sharpenedPt = pt match
3261+
case pt: SelectionProto if pt.name.isExtensionName => pt.deepenProto
3262+
case _ => pt
32543263
var resMatch: Boolean = false
32553264
wtp match {
32563265
case wtp: ExprType =>
32573266
readaptSimplified(tree.withType(wtp.resultType))
32583267
case wtp: MethodType if wtp.isImplicitMethod &&
3259-
({ resMatch = constrainResult(tree.symbol, wtp, pt); resMatch } || !functionExpected) =>
3268+
({ resMatch = constrainResult(tree.symbol, wtp, sharpenedPt); resMatch } || !functionExpected) =>
32603269
if (resMatch || ctx.mode.is(Mode.ImplicitsEnabled))
32613270
adaptNoArgsImplicitMethod(wtp)
32623271
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)