trait_selection: fix assumptions-on-binders diagnostics - #158588
trait_selection: fix assumptions-on-binders diagnostics#158588Dnreikronos wants to merge 3 commits into
Conversation
|
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
|
r? @folkertdev rustbot has assigned @folkertdev. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
6d112e4 to
36f4d5a
Compare
This comment has been minimized.
This comment has been minimized.
|
r? types |
|
r? BoxyUwU We intend to fully rework the way these diagnostics work and the errors are currently intentionally bad as they don't even have span information (they point to the whole containing function). I think keeping the status quo is preferable as a very explicit "this is still very WIP" and would personally prefer to close this PR |
|
|
thanks, that makes sense. i was mostly looking at this as remove the placeholder text, but imo you're right that the nicer message is a bit misleading if the span is still basically wrong. i'll wait for boxyuwu's opinion before closing the pr. if i poke at this again later, i think i'd rather start by carrying more of the failed outlives predicate / binder info through first, then make the diagnostic nicer once it has enough data to not lie. |
|
I think I agree with lcnr here 👍 Would you be interested in trying to do a more involved refactor here and figure out properly spanned diagnostics for -Zassumptions-on-binders? i.e. make it so we aren't just pointing to the whole item which the constraint originates from. I think this would be really useful to have done and I won't get the time to do it for a while because of other priorities (getting std/core to compile and then custom test suite). |
Of course! |
|
sick :3 it's probably a more involved change than your previous PRs so it's probably worth us chatting on zulip about it as you're working on it ✨ I would probably start by looking into where the spans for normal region errors come from (i.e. without -Zassumptions-on-binders) and then look into how to replicate that for -Zassumptions-on-binders |
|
@rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
36f4d5a to
269fb71
Compare
|
@rustbot ready |
| @@ -66,6 +69,9 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>( | |||
| let expected_found = ExpectedFound::new(b, a); | |||
| FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found)) | |||
| } | |||
| ty::PredicateKind::Clause( | |||
| ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::TypeOutlives(_), | |||
There was a problem hiding this comment.
Do you have test cases where this change was necessary?
There was a problem hiding this comment.
yep, higher-ranked-outlives-issue-157732.rs covers this. fyi, I tried removing this arm and the test ICEs at fulfillment_errors.rs:667 instead of emitting the diagnostic. imo keeping this arm is the right call. idk if it's worth adding a note to the test, but ltm if you'd prefer that.
There was a problem hiding this comment.
this is ok I just wanted to check that this gets hit in practice (and it makes sense to me that it would be)
| /// participate in candidate equality or caching. Spans are attached when those responses are | ||
| /// applied to an inference context. | ||
| #[derive(Clone, Debug)] | ||
| pub(crate) enum SolverRegionConstraint<'tcx> { |
There was a problem hiding this comment.
Instead of duplicating the definition of RegionConstraint could you look into making RegionConstraint be generic over some S for the Span. Then we can do type SpannedRegionConstraint<I> = RegionConstraint<I, I::Span> and type RegionConstraint<I> = RegionConstraint<I, ()>
There was a problem hiding this comment.
done :) RegionConstraint is generic over S = () now, with SpannedRegionConstraint<I> using I::Span. btw this also got rid of the duplicate infer-side enum and lets both paths use the type-ir evaluator. imo this is much cleaner.
| let constraint = self.inner.borrow().solver_region_constraint_storage.get_constraint(); | ||
| debug!(?constraint); | ||
| let constraint = | ||
| let constraint = constraint.map_atomic_constraints(&mut |constraint| { |
There was a problem hiding this comment.
If you make RegionConstraint generic over whether it's spanned or not then we can get rid of map_atomic_constraints and make destructure_type_outlives_constraints_in_root be generic over S too. That would be ideal I think
There was a problem hiding this comment.
done too. destructure_type_outlives_constraints_in_root is generic over S and carries the same span into the constraints it expands. map_atomic_constraints is gone. The shared evaluator still keeps the first ambiguity span. ltm if you had a different shape in mind.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
3acffb6 to
b3495e0
Compare
| Or(Box<[RegionConstraint<I, S>]>), | ||
| } | ||
|
|
||
| /// A solver region constraint together with the span that caused each atomic constraint. |
There was a problem hiding this comment.
| /// A solver region constraint together with the span that caused each atomic constraint. | |
| /// A solver region constraint together with the span that caused each leaf constraint. |
There was a problem hiding this comment.
Just adjusted, Boxy :)
This comment has been minimized.
This comment has been minimized.
c5beff5 to
09ce023
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
View all comments
fixes #157732
-Zassumptions-on-binderswas losing the origin of solver region constraints. By the time regionck or borrowck reported them, every constraint received the containing item span, so diagnostics pointed at an entire function or const. Some paths were also still emitting placeholder text (:3andmeoow :c).This keeps canonical solver responses and
ExternalConstraintsDataspan-free, so source locations do not participate in candidate equality or caching. When a response is applied,EvalCtxt::origin_spanis attached to each atomic solverRegionConstraintstored inInferCtxt. Late region conversion then uses the span attached to each constraint, including for ambiguity diagnostics.The affected paths now report
higher-ranked lifetime bound could not be satisfiedat the type use that introduced the failing constraint. UI coverage includes two failures from oneInferCtxtto ensure their origins remain distinct. Unit coverage checks that the spanned evaluator stays in semantic parity with the type-ir evaluator and preserves the first ambiguity origin span.Future work: carry the failed outlives predicate or originating binder far enough through this path to name the exact bound that failed, rather than only pointing at its origin.