Skip to content

Commit 2e4383f

Browse files
committed
Add bindings inside the expansion
1 parent 3c9935f commit 2e4383f

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
@@ -508,9 +508,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
508508

509509
if (inlinedMethod == defn.Compiletime_error) issueError()
510510

511-
// Take care that only argument bindings go into `bindings`, since positions are
512-
// different for bindings from arguments and bindings from body.
513-
tpd.Inlined(call, finalBindings, finalExpansion)
511+
// Widen TermRefs to bindings
512+
val finalExpansion2 = finalExpansion.tpe match {
513+
case tpe: TermRef if finalBindings.exists(x => x.symbol == tpe.symbol) =>
514+
// If the return type of an inline function is a singlton type of a parameter (like in `DottyPredef.the`)
515+
// the expansion will be `{ val x = y; (x: x.type) }`. We ascribe the type to itself widening the
516+
// local TermRef of the binding `{ val x = y; (x: y.type) }`.
517+
tpd.Typed(finalExpansion, TypeTree(finalExpansion.tpe.widenTermRefExpr)).withSpan(finalExpansion.span)
518+
case _ =>
519+
finalExpansion
520+
}
521+
522+
tpd.Inlined(call, Nil, tpd.seq(finalBindings, finalExpansion2))
514523
}
515524
}
516525

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)