Skip to content

Commit d4e8f5d

Browse files
committed
Also use casts for transparent inlines
1 parent 3f07fb9 commit d4e8f5d

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -924,16 +924,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
924924

925925
// Apply inliner to `rhsToInline`, split off any implicit bindings from result, and
926926
// make them part of `bindingsBuf`. The expansion is then the tree that remains.
927-
val expansion0 = inliner.transform(rhsToInline)
928-
val expansion =
929-
if opaqueProxies.nonEmpty && !inlinedMethod.is(Transparent) then
930-
expansion0.cast(call.tpe)(using ctx.withSource(expansion0.source))
931-
// the cast makes sure that the sealing with the declared type
932-
// is type correct. Without it we might get problems since the
933-
// expression's type is the opaque alias but the call's type is
934-
// the opaque type itself. An example is in pos/opaque-inline1.scala.
935-
else
936-
expansion0
927+
val expansion = inliner.transform(rhsToInline)
937928

938929
def issueError() = callValueArgss match {
939930
case (msgArg :: Nil) :: Nil =>
@@ -1005,7 +996,17 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1005996

1006997
// Take care that only argument bindings go into `bindings`, since positions are
1007998
// different for bindings from arguments and bindings from body.
1008-
tpd.Inlined(call, finalBindings, finalExpansion)
999+
val res = tpd.Inlined(call, finalBindings, finalExpansion)
1000+
if opaqueProxies.isEmpty then res
1001+
else
1002+
val target =
1003+
if inlinedMethod.is(Transparent) then call.tpe & res.tpe
1004+
else call.tpe
1005+
res.ensureConforms(target)
1006+
// Make sure that the sealing with the declared type
1007+
// is type correct. Without it we might get problems since the
1008+
// expression's type is the opaque alias but the call's type is
1009+
// the opaque type itself. An example is in pos/opaque-inline1.scala.
10091010
}
10101011
}
10111012

tests/pos/opaque-inline1.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
object refined:
33
opaque type Positive = Int
44
inline def Positive(value: Int): Positive = f(value)
5+
transparent inline def TPositive(value: Int): Positive = f(value)
56
def f(x: Positive): Positive = x
67

78
object test:
89
def run: Unit =
910
val x = 9
1011
val nine = refined.Positive(x)
12+
val tnine: refined.Positive = refined.TPositive(x)
1113

0 commit comments

Comments
 (0)