Skip to content

Commit 2ca0ce7

Browse files
Make inline proxy vals have inferred types (#20241)
Fixes #20237 since it erases illegal capture sets containing skolem types.
2 parents fef6576 + 2f75110 commit 2ca0ce7

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

compiler/src/dotty/tools/dotc/cc/Setup.scala

+10-6
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,16 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
369369
def setupTraverser(recheckDef: DefRecheck) = new TreeTraverserWithPreciseImportContexts:
370370

371371
def transformResultType(tpt: TypeTree, sym: Symbol)(using Context): Unit =
372-
transformTT(tpt,
373-
boxed = !ccConfig.allowUniversalInBoxed && sym.is(Mutable, butNot = Method),
374-
// types of mutable variables are boxed in pre 3.3 codee
375-
exact = sym.allOverriddenSymbols.hasNext,
376-
// types of symbols that override a parent don't get a capture set TODO drop
377-
)
372+
try
373+
transformTT(tpt,
374+
boxed = !ccConfig.allowUniversalInBoxed && sym.is(Mutable, butNot = Method),
375+
// types of mutable variables are boxed in pre 3.3 codee
376+
exact = sym.allOverriddenSymbols.hasNext,
377+
// types of symbols that override a parent don't get a capture set TODO drop
378+
)
379+
catch case ex: IllegalCaptureRef =>
380+
capt.println(i"fail while transforming result type $tpt of $sym")
381+
throw ex
378382
val addDescription = new TypeTraverser:
379383
def traverse(tp: Type) = tp match
380384
case tp @ CapturingType(parent, refs) =>

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class Inliner(val call: tpd.Tree)(using Context):
237237
if bindingFlags.is(Inline) && argIsBottom then
238238
newArg = Typed(newArg, TypeTree(formal.widenExpr)) // type ascribe RHS to avoid type errors in expansion. See i8612.scala
239239
if isByName then DefDef(boundSym, newArg)
240-
else ValDef(boundSym, newArg)
240+
else ValDef(boundSym, newArg, inferred = true)
241241
}.withSpan(boundSym.span)
242242
inlining.println(i"parameter binding: $binding, $argIsBottom")
243243
buf += binding
@@ -319,7 +319,7 @@ class Inliner(val call: tpd.Tree)(using Context):
319319
else pre
320320

321321
val binding = accountForOpaques(
322-
ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym)).withSpan(selfSym.span))
322+
ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym), inferred = true).withSpan(selfSym.span))
323323
bindingsBuf += binding
324324
inlining.println(i"proxy at $level: $selfSym = ${bindingsBuf.last}")
325325
lastSelf = selfSym
@@ -368,7 +368,7 @@ class Inliner(val call: tpd.Tree)(using Context):
368368
RefinedType(parent, refinement._1, TypeAlias(refinement._2))
369369
)
370370
val refiningSym = newSym(InlineBinderName.fresh(), Synthetic, refinedType).asTerm
371-
val refiningDef = ValDef(refiningSym, tpd.ref(ref).cast(refinedType)).withSpan(span)
371+
val refiningDef = ValDef(refiningSym, tpd.ref(ref).cast(refinedType), inferred = true).withSpan(span)
372372
inlining.println(i"add opaque alias proxy $refiningDef for $ref in $tp")
373373
bindingsBuf += refiningDef
374374
opaqueProxies += ((ref, refiningSym.termRef))

tests/pos/i20237.scala

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import language.experimental.captureChecking
2+
import scala.annotation.capability
3+
4+
@capability class Cap:
5+
def use[T](body: Cap ?=> T) = body(using this)
6+
7+
class Box[T](body: Cap ?=> T):
8+
inline def open(using cap: Cap) = cap.use(body)
9+
10+
object Box:
11+
def make[T](body: Cap ?=> T)(using Cap): Box[T]^{body} = Box(body)
12+
13+
def main =
14+
given Cap = new Cap
15+
val box = Box.make(1).open

0 commit comments

Comments
 (0)