Enforce scoverage type lifting to be observationally transparent for later phases - #26895
Enforce scoverage type lifting to be observationally transparent for later phases#26895anatoliykmetyuk wants to merge 9 commits into
Conversation
627ca6d to
6cfae14
Compare
6cfae14 to
a8a1dff
Compare
|
The challenges described here afflict other lifted expressions as well. My other (naive) observation is that coverage need not be a core feature, but maybe a mechanism for plugins to safely lift is a core feature. (Like unused warnings, coverage feels like a third party operation.) |
a8a1dff to
4946257
Compare
Makes sense - other lifting cases may also need to observe similar transparency guarantees. Exploring a reusable core lifting mechanism would be broader than this PR, which keeps the implementation scoped to coverage instrumentation. |
Fixes #26780
Fixes #26781
Fixes #26782
Fixes #26784
Excludelist additions are the same as #26894 to address upstream regression independent of this work.
Problem
Coverage instrumentation runs after typing and lifts expressions into synthetic local values to preserve evaluation order while inserting probes. E.g.:
becomes:
Those temporaries are then encountered by later rechecking and capture-checking phases as if they were ordinary source values.
One root cause for a whole class of bugs is scoverage computing the type of the temporary in an incorrect, incomplete or overly simplistic way, breaking the assumptions by later phases.
The central question to correctly implementing coverage phase is therefore the correct computation of the lifted expression's type. This type can be one of the two things:
valNaively, we may always want to preserve the original type, however, in practice, this is often not possible as properties such as stability, laziness, source singleton path, skolem/capture identity would be genuinely different for the temporary
val. Typing the temporary by the original type would be wrong.Therefore, the central question of this PR is determining in which cases a lifted expression should preserve the original type, when to default to the eagerly-computed (recomputed) type, and what that eagerly-computed type should be.
Solution
The solution attempts to establish the following invariant: lifting of application parameters must be observationally transparent. This means a lifted argument should be possible to use at the same position as the original argument without changing the type of the application's other arguments, the application's result type, and the capture tracking behavior.
The PR defaults to eagerly computing the type of lifted expressions, preserving the original type only in either of following cases:
NothingAny of the above, provided that:
Coverage lifting now distinguishes the eager type of the value actually stored in a temporary from the original semantic type observed by the already-typed application.
Review Guide
liftArgContextis where the decision of eager vs original type is made.liftedDefandliftedRefconstruct the synthetic value definition tree and its substitution into the application.liftedExprType- computes the lifted expression's type, according to the decision made byliftArgContext, also taking measures to make the operation transparent for capture-checking purposes viadeclareNestedCaptureRefinements.declareNestedCaptureRefinements- checks whether capture checking phase will change any of the structural parts of the synthetic value's type duringSetup, and if so, asks it not to do so by annotating it with@Declared.liftAppis lifting entrypoint for applications, callingcopyApplytransitively;copyApplypreserves skolemsHave you relied on LLM-based tools in this contribution?s
Yes, and I checked the output by review and regression tests.
How was the solution tested?
New automated tests cover the four targeted issues, exact typer skolems, dependent and path-dependent arguments, parameterless and lazy accessors, nested capture refinements, named arguments, repeated arguments, read-only adaptation, exactly-once left-to-right evaluation, and a genuine escaping-capture negative control.
[test_coverage]