Skip to content

Refactorings for CC error reporting #23260

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions compiler/src/dotty/tools/dotc/cc/CCState.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dotc
package cc

import core.*
import CaptureSet.{CompareResult, CompareFailure, VarState}
import CaptureSet.VarState
import collection.mutable
import reporting.Message
import Contexts.Context
Expand All @@ -16,24 +16,6 @@ class CCState:

// ------ Error diagnostics -----------------------------

/** Error reprting notes produces since the last call to `test` */
var notes: List[ErrorNote] = Nil

def addNote(note: ErrorNote): Unit =
if !notes.exists(_.getClass == note.getClass) then
notes = note :: notes

def test(op: => CompareResult): CompareResult =
val saved = notes
notes = Nil
try op match
case res: CompareFailure => res.withNotes(notes)
case res => res
finally notes = saved

def testOK(op: => Boolean): CompareResult =
test(if op then CompareResult.OK else CompareResult.Fail(Nil))

/** Warnings relating to upper approximations of capture sets with
* existentially bound variables.
*/
Expand Down
19 changes: 16 additions & 3 deletions compiler/src/dotty/tools/dotc/cc/Capability.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ object Capabilities:
trait RootCapability extends Capability:
val rootId = nextRootId
nextRootId += 1
def descr(using Context): String

/** The base trait of all capabilties represented as types */
trait CoreCapability extends TypeProxy, Capability:
Expand Down Expand Up @@ -120,6 +121,7 @@ object Capabilities:
*/
@sharable // We override below all operations that access internal capability state
object GlobalCap extends RootCapability:
def descr(using Context) = "the universal root capability"
override val maybe = Maybe(this)
override val readOnly = ReadOnly(this)
override def reach = unsupported("cap.reach")
Expand All @@ -136,13 +138,21 @@ object Capabilities:
* for diagnostics
*/
case class FreshCap private (owner: Symbol, origin: Origin)(using @constructorOnly ctx: Context) extends RootCapability:
val hiddenSet = CaptureSet.HiddenSet(owner)
hiddenSet.owningCap = this
val hiddenSet = CaptureSet.HiddenSet(owner, this: @unchecked)
// fails initialization check without the @unchecked

override def equals(that: Any) = that match
case that: FreshCap => this eq that
case _ => false

def descr(using Context) =
val originStr = origin match
case Origin.InDecl(sym) if sym.exists =>
origin.explanation
case _ =>
i" created in ${hiddenSet.owner.sanitizedDescription}${origin.explanation}"
i"a fresh root capability$originStr"

object FreshCap:
def apply(origin: Origin)(using Context): FreshCap | GlobalCap.type =
if ccConfig.useSepChecks then FreshCap(ctx.owner, origin)
Expand Down Expand Up @@ -225,6 +235,9 @@ object Capabilities:
rcap.myOrigin = primary
primary.variants += rcap
rcap

def descr(using Context) =
i"a root capability associated with the result type of $binder"
end ResultCap

/** A trait for references in CaptureSets. These can be NamedTypes, ThisTypes or ParamRefs,
Expand Down Expand Up @@ -545,7 +558,7 @@ object Capabilities:
case y: ResultCap => vs.unify(x, y)
case _ => y.derivesFromSharedCapability
if !result then
ccState.addNote(CaptureSet.ExistentialSubsumesFailure(x, y))
TypeComparer.addErrorNote(CaptureSet.ExistentialSubsumesFailure(x, y))
result
case GlobalCap =>
y match
Expand Down
5 changes: 1 addition & 4 deletions compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ def depFun(args: List[Type], resultType: Type, isContextual: Boolean, paramNames
/** An exception thrown if a @retains argument is not syntactically a Capability */
class IllegalCaptureRef(tpe: Type)(using Context) extends Exception(tpe.show)

/** A base trait for data producing addenda to error messages */
trait ErrorNote

/** The currently valid CCState */
def ccState(using Context): CCState =
Phases.checkCapturesPhase.asInstanceOf[CheckCaptures].ccState1
Expand Down Expand Up @@ -157,7 +154,7 @@ extension (tp: Type)
* the two capture sets are combined.
*/
def capturing(cs: CaptureSet)(using Context): Type =
if (cs.isAlwaysEmpty || cs.isConst && cs.subCaptures(tp.captureSet, VarState.Separate).isOK)
if (cs.isAlwaysEmpty || cs.isConst && cs.subCaptures(tp.captureSet, VarState.Separate))
&& !cs.keepAlways
then tp
else tp match
Expand Down
Loading
Loading