rustc_trait_selection: fix trait solver hang caused by degenerate obligations#159774
rustc_trait_selection: fix trait solver hang caused by degenerate obligations#159774InvalidPathException wants to merge 1 commit into
Conversation
|
r? @mu001999 rustbot has assigned @mu001999. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
@rustbot reroll |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…try> rustc_trait_selection: fix trait solver hang caused by degenerate obligations
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (41450ef): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -8.4%, secondary -2.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 2.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 485.902s -> 492.139s (1.28%) |
| }) | ||
| }) | ||
| } { | ||
| stalled_on.clear(); |
There was a problem hiding this comment.
This really could be expressed better. Something like
ProjectAndUnifyResult::Holds(os) if os.is_empty() =>ProcessResult::Changed(mk_pending(obligation, os)),
ProjectAndUnifyResult::Holds(os) => {
let input_projection_term = infcx
.resolve_vars_if_possible(project_obligation.predicate)
.map_bound(|p| p.projection_term);
let all_same_term = os.iter().all(|o| {
let Some(proj_clause) = o.predicate.as_projection_clause() else { return false };
infcx.resolve_vars_if_possible(proj_clause).map_bound(|p| p.projection_term) == input
});
if all_same_term {
...
} else {
ProcessResult::Changed(mk_pending(obligation, os))
}
}| // Every nested obligation is a copy of the obligation we are processing, | ||
| // registering would make fulfillment process the same obligation forever. | ||
| // So, stall until an inference variable in the predicate is constrained. |
There was a problem hiding this comment.
A concrete example in a comment here would be useful.
This is also slightly stronger than the comment, anyways: every nested obligation has the same projection term.
I did consider this, there should not be anything that compiles because of this today, the stall path is reachable only when
At that point it must error regardless of how it resolves later on (as of today). But stalling gives a (maybe) better message as we allow more info to come in, since this path is relatively rare, it seems at least not problematic to stall. trait Bound {}
impl Bound for u32 {}
trait Driver {
type Object<Ctx: Bound>: Bound;
}
fn make<T: Driver, C: Bound>(c: C) -> T::Object<C> {
todo!()
}
fn any<X>() -> X {
todo!()
}
fn f<T: Driver>() {
let mut x = any(); // x: ?x
x = make::<T, _>(x); // forces <T as Driver>::Object<?x> == ?x
}
fn main() {}Stall: Error immediately: |
|
Given that the new solver is coming soon and completely overhauls normalization, I'm not inclined to potentially introduce more things that could compile, particularly if the reasoning is just better diagnostics. Even still, the diagnostics in the error immediately case are not really bad. So, let's go that route. |
|
Sorry, can you squash? And then r=me |
fab2c18 to
f2e0edf
Compare
|
r? @jackh726 |
…r-hang, r=jackh726 rustc_trait_selection: fix trait solver hang caused by degenerate obligations Closes rust-lang#157516 and rust-lang#159750. Bisection pointed to rust-lang#142712 but the problem has always been present. Fulfillment can go on forever if a degenerate obligation causes additional obligations from `poly_project_and_unify_term` to be copies of the degenerate one. Current fix is checking if the obligation is degenerate, ~making the degenerate case stall, waiting for other obligations to constrain its inference variables, so it can actually normalize or error instead of propagating this.~ error immediately since the code will not compile anyways. I am not sure if this is ideal, might need to check perf due to the added heavy-ish condition check.
…uwer Rollup of 24 pull requests Successful merges: - #159638 (bootstrap: Split the `Step` trait into multiple traits) - #159774 (rustc_trait_selection: fix trait solver hang caused by degenerate obligations) - #159837 (line-tables-only test: check that the line number matches the function name) - #159946 (Update Enzyme submodule to imporve llvm-cov) - #159617 (Fix up `#[linkage]` target checking) - #159733 (std: Switch implementations of `thread_local!` for WASI) - #159783 (Check unsafe impls on safe EIIs) - #159810 (Add tuple never coercion collection regression test) - #159821 (Update expect message using the recommended style in binary_heap module) - #159826 (Remove redundant `#[rustc_paren_sugar]` feature gate) - #159846 (Implement `str::copy_from_str`) - #159849 (rustc_parse: Stop returning `Option` from statement parsing) - #159853 (Updated expect messages for `CString` struct and method documentation) - #159875 (More cleanup in `rustc_attr_parsing`) - #159882 (Update expect messages in library/alloc/boxed.rs and library/alloc/string.rs to follow the style guide) - #159891 (Split multiline derives into std/rustc macros) - #159893 (Fix `find_attr` hygiene and `rustc_hir` cleanups) - #159895 (rustc-dev-guide subtree update) - #159902 (Clarify that the expected runtime symbols signature is for the current target only) - #159914 (Fix error in diagnostic on_unmatched_args) - #159917 (spare capacity mut constification) - #159918 (rename abort_unwind → abort_on_unwind) - #159936 (Minor `rustc_ast::ast` doc cleanups) - #159945 (Update expect messages in library/core/src/ptr/non_null.rs)
…uwer Rollup of 24 pull requests Successful merges: - #159638 (bootstrap: Split the `Step` trait into multiple traits) - #159774 (rustc_trait_selection: fix trait solver hang caused by degenerate obligations) - #159837 (line-tables-only test: check that the line number matches the function name) - #159946 (Update Enzyme submodule to imporve llvm-cov) - #159617 (Fix up `#[linkage]` target checking) - #159733 (std: Switch implementations of `thread_local!` for WASI) - #159783 (Check unsafe impls on safe EIIs) - #159810 (Add tuple never coercion collection regression test) - #159821 (Update expect message using the recommended style in binary_heap module) - #159826 (Remove redundant `#[rustc_paren_sugar]` feature gate) - #159846 (Implement `str::copy_from_str`) - #159849 (rustc_parse: Stop returning `Option` from statement parsing) - #159853 (Updated expect messages for `CString` struct and method documentation) - #159875 (More cleanup in `rustc_attr_parsing`) - #159882 (Update expect messages in library/alloc/boxed.rs and library/alloc/string.rs to follow the style guide) - #159891 (Split multiline derives into std/rustc macros) - #159893 (Fix `find_attr` hygiene and `rustc_hir` cleanups) - #159895 (rustc-dev-guide subtree update) - #159902 (Clarify that the expected runtime symbols signature is for the current target only) - #159914 (Fix error in diagnostic on_unmatched_args) - #159917 (spare capacity mut constification) - #159918 (rename abort_unwind → abort_on_unwind) - #159936 (Minor `rustc_ast::ast` doc cleanups) - #159945 (Update expect messages in library/core/src/ptr/non_null.rs)
…r-hang, r=jackh726 rustc_trait_selection: fix trait solver hang caused by degenerate obligations Closes rust-lang#157516 and rust-lang#159750. Bisection pointed to rust-lang#142712 but the problem has always been present. Fulfillment can go on forever if a degenerate obligation causes additional obligations from `poly_project_and_unify_term` to be copies of the degenerate one. Current fix is checking if the obligation is degenerate, ~making the degenerate case stall, waiting for other obligations to constrain its inference variables, so it can actually normalize or error instead of propagating this.~ error immediately since the code will not compile anyways. I am not sure if this is ideal, might need to check perf due to the added heavy-ish condition check.
…r-hang, r=jackh726 rustc_trait_selection: fix trait solver hang caused by degenerate obligations Closes rust-lang#157516 and rust-lang#159750. Bisection pointed to rust-lang#142712 but the problem has always been present. Fulfillment can go on forever if a degenerate obligation causes additional obligations from `poly_project_and_unify_term` to be copies of the degenerate one. Current fix is checking if the obligation is degenerate, ~making the degenerate case stall, waiting for other obligations to constrain its inference variables, so it can actually normalize or error instead of propagating this.~ error immediately since the code will not compile anyways. I am not sure if this is ideal, might need to check perf due to the added heavy-ish condition check.
|
@bors try jobs=optional-x86_64-gnu-parallel-frontend |
This comment has been minimized.
This comment has been minimized.
…try> rustc_trait_selection: fix trait solver hang caused by degenerate obligations try-job: optional-x86_64-gnu-parallel-frontend
|
The job Click to see the possible cause of the failure (guessed by this bot) |
…uwer Rollup of 28 pull requests Successful merges: - #159638 (bootstrap: Split the `Step` trait into multiple traits) - #159774 (rustc_trait_selection: fix trait solver hang caused by degenerate obligations) - #159837 (line-tables-only test: check that the line number matches the function name) - #159946 (Update Enzyme submodule to imporve llvm-cov) - #159962 (miri subtree update) - #156570 (tests: extend remap-path-prefix-std to all stdlib rlibs) - #159617 (Fix up `#[linkage]` target checking) - #159633 (Improve workings of attribute suggestions) - #159733 (std: Switch implementations of `thread_local!` for WASI) - #159783 (Check unsafe impls on safe EIIs) - #159810 (Add tuple never coercion collection regression test) - #159826 (Remove redundant `#[rustc_paren_sugar]` feature gate) - #159846 (Implement `str::copy_from_str`) - #159849 (rustc_parse: Stop returning `Option` from statement parsing) - #159853 (Updated expect messages for `CString` struct and method documentation) - #159875 (More cleanup in `rustc_attr_parsing`) - #159882 (Update expect messages in library/alloc/boxed.rs and library/alloc/string.rs to follow the style guide) - #159891 (Split multiline derives into std/rustc macros) - #159893 (Fix `find_attr` hygiene and `rustc_hir` cleanups) - #159895 (rustc-dev-guide subtree update) - #159902 (Clarify that the expected runtime symbols signature is for the current target only) - #159914 (Fix error in diagnostic on_unmatched_args) - #159917 (spare capacity mut constification) - #159918 (rename abort_unwind → abort_on_unwind) - #159927 (Remove sve2 from the ImpliedFeatures of AArch64 v9a.) - #159936 (Minor `rustc_ast::ast` doc cleanups) - #159945 (Update expect messages in library/core/src/ptr/non_null.rs) - #159950 (Add CFI tests for return types and never type)
|
This pr seems to cause a failure in the optional parallel frontend @bors try jobs=x86_64-mingw |
This comment has been minimized.
This comment has been minimized.
…try> rustc_trait_selection: fix trait solver hang caused by degenerate obligations try-job: x86_64-mingw
|
💔 Test for d3ffc12 failed: CI. Failed job:
|
|
@bors try jobs=x86_64-mingw |
This comment has been minimized.
This comment has been minimized.
…try> rustc_trait_selection: fix trait solver hang caused by degenerate obligations try-job: x86_64-mingw
|
it looks like the output is actually "correct", the cause of the failure is a race, i.e. which of the two impls' well-formedness checks got reported as the cycle's entry point Expected Actual: |
|
💔 Test for 0766bd9 failed: CI. Failed job:
|
|
@bors try jobs=x86_64-mingw |
|
@InvalidPathException: 🔑 Insufficient privileges: not in try users |
|
A job failed! Check out the build log: (web) (plain enhanced) (plain) Click to see the possible cause of the failure (guessed by this bot) |
|
A job failed! Check out the build log: (web) (plain enhanced) (plain) Click to see the possible cause of the failure (guessed by this bot) |
|
@bors try jobs=x86_64-mingw-1 |
|
⌛ Trying commit f2e0edf with merge f97b318… To cancel the try build, run the command Workflow: https://github.com/rust-lang/rust/actions/runs/30213658965 |
…try> rustc_trait_selection: fix trait solver hang caused by degenerate obligations try-job: x86_64-mingw-1
View all comments
Closes #157516 and #159750.
Bisection pointed to #142712 but the problem has always been present. Fulfillment can go on forever if a degenerate obligation causes additional obligations from
poly_project_and_unify_termto be copies of the degenerate one.Current fix is checking if the obligation is degenerate,
making the degenerate case stall, waiting for other obligations to constrain its inference variables, so it can actually normalize or error instead of propagating this.error immediately since the code will not compile anyways.I am not sure if this is ideal, might need to check perf due to the added heavy-ish condition check.