From 2f7511058f0233bf093ddd564321fda7d3f8371e Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 20 Apr 2024 17:40:39 +0200 Subject: [PATCH] Make inline proxy vals have inferred types Fixes #20237 since it erases illegal capture sets containing skolem types. --- compiler/src/dotty/tools/dotc/cc/Setup.scala | 16 ++++++++++------ .../src/dotty/tools/dotc/inlines/Inliner.scala | 6 +++--- tests/pos/i20237.scala | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 tests/pos/i20237.scala diff --git a/compiler/src/dotty/tools/dotc/cc/Setup.scala b/compiler/src/dotty/tools/dotc/cc/Setup.scala index 9ab41859f170..60691d279c38 100644 --- a/compiler/src/dotty/tools/dotc/cc/Setup.scala +++ b/compiler/src/dotty/tools/dotc/cc/Setup.scala @@ -369,12 +369,16 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI: def setupTraverser(recheckDef: DefRecheck) = new TreeTraverserWithPreciseImportContexts: def transformResultType(tpt: TypeTree, sym: Symbol)(using Context): Unit = - transformTT(tpt, - boxed = !ccConfig.allowUniversalInBoxed && sym.is(Mutable, butNot = Method), - // types of mutable variables are boxed in pre 3.3 codee - exact = sym.allOverriddenSymbols.hasNext, - // types of symbols that override a parent don't get a capture set TODO drop - ) + try + transformTT(tpt, + boxed = !ccConfig.allowUniversalInBoxed && sym.is(Mutable, butNot = Method), + // types of mutable variables are boxed in pre 3.3 codee + exact = sym.allOverriddenSymbols.hasNext, + // types of symbols that override a parent don't get a capture set TODO drop + ) + catch case ex: IllegalCaptureRef => + capt.println(i"fail while transforming result type $tpt of $sym") + throw ex val addDescription = new TypeTraverser: def traverse(tp: Type) = tp match case tp @ CapturingType(parent, refs) => diff --git a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala index 629bc2ed3b16..4ee3682626c4 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala @@ -237,7 +237,7 @@ class Inliner(val call: tpd.Tree)(using Context): if bindingFlags.is(Inline) && argIsBottom then newArg = Typed(newArg, TypeTree(formal.widenExpr)) // type ascribe RHS to avoid type errors in expansion. See i8612.scala if isByName then DefDef(boundSym, newArg) - else ValDef(boundSym, newArg) + else ValDef(boundSym, newArg, inferred = true) }.withSpan(boundSym.span) inlining.println(i"parameter binding: $binding, $argIsBottom") buf += binding @@ -319,7 +319,7 @@ class Inliner(val call: tpd.Tree)(using Context): else pre val binding = accountForOpaques( - ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym)).withSpan(selfSym.span)) + ValDef(selfSym.asTerm, QuoteUtils.changeOwnerOfTree(rhs, selfSym), inferred = true).withSpan(selfSym.span)) bindingsBuf += binding inlining.println(i"proxy at $level: $selfSym = ${bindingsBuf.last}") lastSelf = selfSym @@ -368,7 +368,7 @@ class Inliner(val call: tpd.Tree)(using Context): RefinedType(parent, refinement._1, TypeAlias(refinement._2)) ) val refiningSym = newSym(InlineBinderName.fresh(), Synthetic, refinedType).asTerm - val refiningDef = ValDef(refiningSym, tpd.ref(ref).cast(refinedType)).withSpan(span) + val refiningDef = ValDef(refiningSym, tpd.ref(ref).cast(refinedType), inferred = true).withSpan(span) inlining.println(i"add opaque alias proxy $refiningDef for $ref in $tp") bindingsBuf += refiningDef opaqueProxies += ((ref, refiningSym.termRef)) diff --git a/tests/pos/i20237.scala b/tests/pos/i20237.scala new file mode 100644 index 000000000000..da3e902b78b4 --- /dev/null +++ b/tests/pos/i20237.scala @@ -0,0 +1,15 @@ +import language.experimental.captureChecking +import scala.annotation.capability + +@capability class Cap: + def use[T](body: Cap ?=> T) = body(using this) + +class Box[T](body: Cap ?=> T): + inline def open(using cap: Cap) = cap.use(body) + +object Box: + def make[T](body: Cap ?=> T)(using Cap): Box[T]^{body} = Box(body) + +def main = + given Cap = new Cap + val box = Box.make(1).open \ No newline at end of file