Skip to content

Commit c5c0768

Browse files
committed
Some infrastructure for making existentials Fresh instances
1 parent 3ad3660 commit c5c0768

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import dotty.tools.dotc.util.SimpleIdentitySet
2626
object Fresh:
2727

2828
/** The annotation of a Fresh instance */
29-
case class Annot(hidden: CaptureSet.HiddenSet, binder: MethodType | NoType.type = NoType) extends Annotation:
29+
case class Annot(hidden: CaptureSet.HiddenSet, binder: MethodType | NoType.type) extends Annotation:
3030
override def symbol(using Context) = defn.FreshCapabilityAnnot
3131
override def tree(using Context) = New(symbol.typeRef, Nil)
3232
override def derivedAnnotation(tree: Tree)(using Context): Annotation = this
@@ -45,11 +45,11 @@ object Fresh:
4545
case _ => this
4646
end Annot
4747

48-
/** Extractor methods for "fresh" capabilities */
48+
/** Constructor and extractor methods for "fresh" capabilities */
4949
def apply(owner: Symbol, initialHidden: Refs = emptyRefs)(using Context): CaptureRef =
5050
if ccConfig.useSepChecks then
5151
val hiddenSet = CaptureSet.HiddenSet(owner, initialHidden)
52-
val res = AnnotatedType(defn.captureRoot.termRef, Annot(hiddenSet))
52+
val res = AnnotatedType(defn.captureRoot.termRef, Annot(hiddenSet, NoType))
5353
hiddenSet.owningCap = res
5454
//assert(hiddenSet.id != 3)
5555
res
@@ -63,9 +63,16 @@ object Fresh:
6363
apply(owner, ownerToHidden(owner, reach = false))
6464

6565
def unapply(tp: AnnotatedType): Option[CaptureSet.HiddenSet] = tp.annot match
66-
case Annot(hidden, _) => Some(hidden)
66+
case Annot(hidden, binder) if !binder.exists => Some(hidden)
6767
case _ => None
6868

69+
/** Create an existential */
70+
def existential(binder: MethodType)(using Context): AnnotatedType =
71+
val hiddenSet = CaptureSet.HiddenSet(NoSymbol, emptyRefs)
72+
val res = AnnotatedType(defn.captureRoot.termRef, Annot(hiddenSet, binder))
73+
hiddenSet.owningCap = res
74+
res
75+
6976
/** The initial elements (either 0 or 1) of a hidden set created for given `owner`.
7077
* If owner `x` is a trackable this is `x*` if reach` is true, or `x` otherwise.
7178
*/

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,18 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
390390
case _ =>
391391
tp
392392

393+
/** Map references to capability classes C to C^,
394+
* normalize captures and map to dependent functions.
395+
*/
396+
def defaultApply(t: Type) =
397+
if t.derivesFromCapability
398+
&& !t.isSingleton
399+
&& t.typeSymbol != defn.Caps_Exists
400+
&& (!sym.isConstructor || (t ne tp.finalResultType))
401+
// Don't add ^ to result types of class constructors deriving from Capability
402+
then CapturingType(t, defn.universalCSImpliedByCapability, boxed = false)
403+
else normalizeCaptures(normalizeFunctions(mapFollowingAliases(t), t))
404+
393405
def innerApply(t: Type) =
394406
t match
395407
case t @ CapturingType(parent, refs) =>
@@ -414,15 +426,16 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
414426
t.derivedAnnotatedType(parent1, ann)
415427
case throwsAlias(res, exc) =>
416428
this(expandThrowsAlias(res, exc, Nil))
429+
case t @ AppliedType(tycon, args)
430+
if defn.isNonRefinedFunction(tp)
431+
&& !defn.isFunctionSymbol(tp.typeSymbol) && (tp.dealias ne tp) =>
432+
// Expand arguments of aliases of function types before proceeding with dealias.
433+
// This is necessary to bind existentialFresh instances to the right method binder.
434+
val args1 = atVariance(-variance):
435+
args.map(this)
436+
defaultApply(t.derivedAppliedType(tycon, args1))
417437
case t =>
418-
// Map references to capability classes C to C^
419-
if t.derivesFromCapability
420-
&& !t.isSingleton
421-
&& t.typeSymbol != defn.Caps_Exists
422-
&& (!sym.isConstructor || (t ne tp.finalResultType))
423-
// Don't add ^ to result types of class constructors deriving from Capability
424-
then CapturingType(t, defn.universalCSImpliedByCapability, boxed = false)
425-
else normalizeCaptures(normalizeFunctions(mapFollowingAliases(t), t))
438+
defaultApply(t)
426439
end toCapturing
427440

428441
val tp1 = toCapturing(tp)

tests/neg-custom-args/captures/i19330.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
22 | val bad: bar.T = foo(bar) // error
88
| ^^^^^^^^
99
| Found: () => Logger^
10-
| Required: () ->{fresh} (ex$7: caps.Exists) -> Logger^{ex$7}
10+
| Required: () ->{fresh} Logger^{fresh}
1111
|
1212
| longer explanation available when compiling with `-explain`
1313
-- Error: tests/neg-custom-args/captures/i19330.scala:16:14 ------------------------------------------------------------

0 commit comments

Comments
 (0)