Skip to content

Commit

Permalink
Polishments
Browse files Browse the repository at this point in the history
  • Loading branch information
Linyxus committed Nov 9, 2023
1 parent c2bffc7 commit 1255c13
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 9 deletions.
18 changes: 10 additions & 8 deletions compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,8 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
end postProcess
end setupTraverser

private def superTypeIsImpure(tp: Type)(using Context): Boolean = {
/** Checks whether an abstract type could be impure. See also: [[needsVariable]]. */
private def instanceCanBeImpure(tp: Type)(using Context): Boolean = {
tp.dealiasKeepAnnots match
case CapturingType(_, refs) =>
!refs.isAlwaysEmpty
Expand All @@ -552,20 +553,21 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
case tp: (TypeRef | AppliedType) =>
val sym = tp.typeSymbol
if sym.isClass then
sym == defn.AnyClass || !sym.isPureClass
sym == defn.AnyClass
// we assume Any is a shorthand of {cap} Any, so if Any is an upper
// bound, the type is taken to be impure.
|| !sym.isPureClass
else
sym != defn.Caps_Cap && superTypeIsImpure(tp.superType)
sym != defn.Caps_Cap && instanceCanBeImpure(tp.superType)
case tp: (RefinedOrRecType | MatchType) =>
superTypeIsImpure(tp.underlying)
instanceCanBeImpure(tp.underlying)
case tp: AndType =>
superTypeIsImpure(tp.tp1) || superTypeIsImpure(tp.tp2)
instanceCanBeImpure(tp.tp1) || instanceCanBeImpure(tp.tp2)
case tp: OrType =>
superTypeIsImpure(tp.tp1) && superTypeIsImpure(tp.tp2)
instanceCanBeImpure(tp.tp1) && instanceCanBeImpure(tp.tp2)
case _ =>
false
}.showing(i"super type is impure $tp = $result", capt)
}.showing(i"instance can be impure $tp = $result", capt)

/** Should a capture set variable be added on type `tp`? */
def needsVariable(tp: Type)(using Context): Boolean = {
Expand All @@ -577,7 +579,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
else
val tp1 = tp.dealiasKeepAnnots
if tp1 ne tp then needsVariable(tp1)
else superTypeIsImpure(tp1)
else instanceCanBeImpure(tp1)
case tp: (RefinedOrRecType | MatchType) =>
needsVariable(tp.underlying)
case tp: AndType =>
Expand Down
3 changes: 2 additions & 1 deletion tests/pos-custom-args/captures/cc-setup-impure-classes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import language.experimental.captureChecking

trait Resource
def id[X](x: X): x.type = x
def foo[M <: Resource](r: M^): Unit = id(r)
def foo[M <: Resource](r: M^): Unit = id(r) // was error, should be ok
def bar[M](r: M^): Unit = id(r) // ok

0 comments on commit 1255c13

Please sign in to comment.