Repository navigation
trait_selection: Preserve eager normalization failures - #162618
rust-bors[bot] merged 1 commit into
Conversation
This comment has been minimized.
This comment has been minimized.
|
sgtm, this is now 2 unrelated changes, is it?
I think we should do both. Generally try to only do changes in the same PR if they build on each other |
|
ah, with the |
Yeah, I can split them. My thinking was that once we kept the eager failure, we already had an error to report, so I dropped the extra obligations for higher-ranked aliases in the fallback. That's why I bundled the two changes. I'd prefer to keep this one focused on normalize_with_universes returning Err and work through the visitor behavior separately.
yep, I removed too much there. I figured keeping the eager failure gave us the error we needed, so I dropped the higher-ranked projection obligations during recovery ;/. But that first failure doesn't cover every alias the visitor walks. I'll keep emitting the Projection obligation while leaving the alias in the returned type. I think handling that separately will make it easier to reason about, so I'll keep this PR focused on normalize_with_universes returning Err. |
we entirely drop all failed obligations from the first normalizaiton attempt, don't we? rust/compiler/rustc_trait_selection/src/solve/normalize.rs Lines 81 to 83 in a4c1445 so to make sure we actually error, |
This comment has been minimized.
This comment has been minimized.
Return failed projection obligations from deep normalization instead of retrying aliases through infallible fallback. Keep regular normalization recovery by rebuilding projection obligations from the original aliases.
a6771bf to
26be04b
Compare
Yep, I was mixing up two paths here. For deep normalization we want to return the eager failure. For the infallible
I think this split makes more sense. Deep normalization gets a real error instead of hiding it, while regular normalization keeps its recovery behavior and lets fulfillment report the projection failure. It also gets rid of the duplicate diagnostic we were seeing. |
|
hey @lcnr, I did the split you asked for, so here's where this ended up the visitor is back to what main does. in my first version I dropped the projection obligations for higher ranked aliases in the fallback, because I thought the eager failure was already enough to get an error. but like you said, the failed obligations from the first attempt get thrown away, so without that obligation nothing actually errors. so I put it back. the only real change left is why I went this way.. in the nested IAT case the eager attempt fails the leak check on the outer alias, and the old fallback retried the original aliases and got away with it because the lifetime stuff ends up in nested goals the parent leak check never sees. that's where the I think this is the cleanest split. deep normalization gets the strict behavior it says it has, and regular normalization keeps recovering like it always did. it also got rid of the duplicate diagnostic we had. one thing I'm not super happy with is the new error on the next solver, it says "type mismatch resolving" which is less clear than the old solver's "one type is more general than the other", but I'd rather not mess with diagnostics in this PR also, earlier you said the visitor leaks placeholders. do you want a separate PR for that, or is keeping the r? lcnr |
|
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
|
r? @adwinwhite rustbot has assigned @adwinwhite. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
@bors r+ rollup |
…normalization_failure, r=lcnr trait_selection: Preserve eager normalization failures Fixes rust-lang#160875 This started from rust-lang#161407 and the Zulip discussion around eager normalization failures. The nested inherent associated type case takes two paths. Eager normalization handles the inner alias first, then the outer alias fails the leak check. The old fallback throws that attempt away and retries the original aliases. That retry can succeed because the lifetime constraints come back through nested goals and the parent leak check does not see them. My first take was to resolve the inference variable after fulfillment. That made the debug assertion go away, but it was only hiding the failed relation. I do not think we should return a value from a path that already failed the leak check. `normalize_with_universes` now returns the failed obligation. Deep normalization passes that failure back instead of falling into recovery. Regular `normalize` stays infallible and keeps the fallback behavior because its callers already expect obligations. The fallback still has to rebuild those obligations. For higher ranked aliases, `ReplaceAliasWithInfer` leaves the alias in the folded value, replaces bound vars with placeholders only for the `Projection` obligation, and does not put the fresh inference term in the returned type. I missed that part in my first version and dropped too much. I think this is the cleanest split. Deep normalization gets the strict behavior it promises, while regular normalization still recovers in the same general way as before. The UI tests cover the nested IAT case and the affected diagnostics.
…uwer Rollup of 9 pull requests Successful merges: - #163461 (Improve diagnostic deduplication) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - #163483 (Bump bootstrap compiler to 1.100.0 beta) - #161380 (only rerun const eval in next-solver if the const actually references opaques) - #162900 (Some refactorings around metadata encoding) - #163461 (Improve diagnostic deduplication) - #163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - #163584 ([triagebot] Ping me for debugger visualizer changes) - #159021 (windows-gnu: enable native TLS) - #161467 (wfcheck: name the item that discards an unused type parameter) - #162618 (trait_selection: Preserve eager normalization failures) - #162904 (Fix ICE for ambiguous candidates on method probing) - #163064 (Avoid computing overflowed goal chains for crate dependencies) - #163281 (Add `f16` inline ASM support to `spirv.rs`) - #163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - #163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - #163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - #163405 (Remove some #[linkage] options) - #163530 (`const impl PartialEq` for `f16b`) - #163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - #163590 (Make `AllocatorNightly` less clever) - #163599 (Add union pattern reference change to relnotes)
Rollup merge of #162618 - Dnreikronos:trait_solver_preserve_normalization_failure, r=lcnr trait_selection: Preserve eager normalization failures Fixes #160875 This started from #161407 and the Zulip discussion around eager normalization failures. The nested inherent associated type case takes two paths. Eager normalization handles the inner alias first, then the outer alias fails the leak check. The old fallback throws that attempt away and retries the original aliases. That retry can succeed because the lifetime constraints come back through nested goals and the parent leak check does not see them. My first take was to resolve the inference variable after fulfillment. That made the debug assertion go away, but it was only hiding the failed relation. I do not think we should return a value from a path that already failed the leak check. `normalize_with_universes` now returns the failed obligation. Deep normalization passes that failure back instead of falling into recovery. Regular `normalize` stays infallible and keeps the fallback behavior because its callers already expect obligations. The fallback still has to rebuild those obligations. For higher ranked aliases, `ReplaceAliasWithInfer` leaves the alias in the folded value, replaces bound vars with placeholders only for the `Projection` obligation, and does not put the fresh inference term in the returned type. I missed that part in my first version and dropped too much. I think this is the cleanest split. Deep normalization gets the strict behavior it promises, while regular normalization still recovers in the same general way as before. The UI tests cover the nested IAT case and the affected diagnostics.
…uwer Rollup of 20 pull requests Successful merges: - rust-lang/rust#163483 (Bump bootstrap compiler to 1.100.0 beta) - rust-lang/rust#161380 (only rerun const eval in next-solver if the const actually references opaques) - rust-lang/rust#162900 (Some refactorings around metadata encoding) - rust-lang/rust#163461 (Improve diagnostic deduplication) - rust-lang/rust#163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - rust-lang/rust#163584 ([triagebot] Ping me for debugger visualizer changes) - rust-lang/rust#159021 (windows-gnu: enable native TLS) - rust-lang/rust#161467 (wfcheck: name the item that discards an unused type parameter) - rust-lang/rust#162618 (trait_selection: Preserve eager normalization failures) - rust-lang/rust#162904 (Fix ICE for ambiguous candidates on method probing) - rust-lang/rust#163064 (Avoid computing overflowed goal chains for crate dependencies) - rust-lang/rust#163281 (Add `f16` inline ASM support to `spirv.rs`) - rust-lang/rust#163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - rust-lang/rust#163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - rust-lang/rust#163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - rust-lang/rust#163405 (Remove some #[linkage] options) - rust-lang/rust#163530 (`const impl PartialEq` for `f16b`) - rust-lang/rust#163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - rust-lang/rust#163590 (Make `AllocatorNightly` less clever) - rust-lang/rust#163599 (Add union pattern reference change to relnotes)
…uwer Rollup of 20 pull requests Successful merges: - rust-lang/rust#163483 (Bump bootstrap compiler to 1.100.0 beta) - rust-lang/rust#161380 (only rerun const eval in next-solver if the const actually references opaques) - rust-lang/rust#162900 (Some refactorings around metadata encoding) - rust-lang/rust#163461 (Improve diagnostic deduplication) - rust-lang/rust#163580 (Provide better doc code example for `UnixDatagram::bind_addr` and `UnixListener::bind_addr`) - rust-lang/rust#163584 ([triagebot] Ping me for debugger visualizer changes) - rust-lang/rust#159021 (windows-gnu: enable native TLS) - rust-lang/rust#161467 (wfcheck: name the item that discards an unused type parameter) - rust-lang/rust#162618 (trait_selection: Preserve eager normalization failures) - rust-lang/rust#162904 (Fix ICE for ambiguous candidates on method probing) - rust-lang/rust#163064 (Avoid computing overflowed goal chains for crate dependencies) - rust-lang/rust#163281 (Add `f16` inline ASM support to `spirv.rs`) - rust-lang/rust#163314 (move `#[macro_export]` on declarative macro check to `rustc_attr_parsing`) - rust-lang/rust#163360 ([rustdoc] Correctly handle rustc_allow_incoherent_impl on primitive methods) - rust-lang/rust#163385 (GVN transmutes of Immediate::Uninit to Immediate::Uninit) - rust-lang/rust#163405 (Remove some #[linkage] options) - rust-lang/rust#163530 (`const impl PartialEq` for `f16b`) - rust-lang/rust#163581 (do not suggest precise capturing when the opaque span is in a macro expansion) - rust-lang/rust#163590 (Make `AllocatorNightly` less clever) - rust-lang/rust#163599 (Add union pattern reference change to relnotes)
Fixes #160875
This started from #161407 and the Zulip discussion around eager normalization failures.
The nested inherent associated type case takes two paths. Eager normalization handles the inner alias first, then the outer alias fails the leak check. The old fallback throws that attempt away and retries the original aliases. That retry can succeed because the lifetime constraints come back through nested goals and the parent leak check does not see them.
My first take was to resolve the inference variable after fulfillment. That made the debug assertion go away, but it was only hiding the failed relation. I do not think we should return a value from a path that already failed the leak check.
normalize_with_universesnow returns the failed obligation. Deep normalization passes that failure back instead of falling into recovery. Regularnormalizestays infallible and keeps the fallback behavior because its callers already expect obligations.The fallback still has to rebuild those obligations. For higher ranked aliases,
ReplaceAliasWithInferleaves the alias in the folded value, replaces bound vars with placeholders only for theProjectionobligation, and does not put the fresh inference term in the returned type. I missed that part in my first version and dropped too much.I think this is the cleanest split. Deep normalization gets the strict behavior it promises, while regular normalization still recovers in the same general way as before.
The UI tests cover the nested IAT case and the affected diagnostics.