Skip to content

Commit 4e07b5c

Browse files
committed
Add bindings inside the expansion
1 parent a9ef81f commit 4e07b5c

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ object Trees {
603603
*/
604604
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, bindings: List[MemberDef[T]], expansion: Tree[T])(implicit @constructorOnly src: SourceFile)
605605
extends Tree[T] {
606+
assert(bindings.isEmpty)
606607
type ThisTree[-T >: Untyped] = Inlined[T]
607608
}
608609

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
520520

521521
if (inlinedMethod == defn.Compiletime_error) issueError()
522522

523-
// Take care that only argument bindings go into `bindings`, since positions are
524-
// different for bindings from arguments and bindings from body.
525-
tpd.Inlined(call, finalBindings, finalExpansion)
523+
// Widen TermRefs to bindings
524+
val finalExpansion2 = finalExpansion.tpe match {
525+
case tpe: TermRef if finalBindings.exists(x => x.symbol == tpe.symbol) =>
526+
// If the return type of an inline function is a singleton type of a parameter (like in `DottyPredef.the`)
527+
// the expansion will be `{ val x = y; (x: x.type) }`. We ascribe the type to itself widening the
528+
// local TermRef of the binding `{ val x = y; (x: y.type) }`.
529+
tpd.Typed(finalExpansion, TypeTree(ctx.typer.avoidingType(finalExpansion, finalBindings))).withSpan(finalExpansion.span)
530+
case _ =>
531+
finalExpansion
532+
}
533+
534+
tpd.Inlined(call, Nil, tpd.seq(finalBindings, finalExpansion2))
526535
}
527536
}
528537

tests/pos/inlined-the.scala

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
object Instances {
3+
4+
class D[T]
5+
6+
class C {
7+
def f() = {
8+
locally {
9+
implied d[T] for D[T]
10+
the[D[Int]]
11+
implicit val s: 3 = ???
12+
val a: 3 = the[3]
13+
val b: s.type = the[s.type]
14+
()
15+
}
16+
17+
locally {
18+
implied d[T] for D[T]
19+
the2[D[Int]]
20+
implicit val s: 3 = ???
21+
val a: 3 = the2[3]
22+
val b: s.type = the2[s.type]
23+
()
24+
}
25+
26+
locally {
27+
implicit val s: List[3] = ???
28+
val a: List[3] = the2[List[3]]
29+
30+
implicit val sl: List[s.type] = ???
31+
val b: List[s.type] = the2[List[s.type]]
32+
()
33+
}
34+
}
35+
}
36+
37+
inline def the2[T](implicit x: T): x.type = x
38+
39+
inline def theList[T](implicit x: T): List[x.type] = List[x.type](x)
40+
41+
}

0 commit comments

Comments
 (0)