Skip to content

Commit

Permalink
Rollup merge of rust-lang#112163 - bvanjoi:fix-105231-2, r=compiler-e…
Browse files Browse the repository at this point in the history
…rrors

fix: inline `predicate_may_hold_fatal` and remove expect call in it

- Fixes rust-lang#105231
- Discussion: rust-lang#111985 (comment)

r? `@compiler-errors`
  • Loading branch information
Dylan-DPC authored Jun 16, 2023
2 parents c84d5e7 + b792198 commit 1e90cb9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
7 changes: 6 additions & 1 deletion compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,12 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate)
})
.chain(obligations)
.find(|o| !selcx.predicate_may_hold_fatal(o));
.find(|o| {
selcx.evaluate_root_obligation(o).map_or(
false, // Overflow has occurred, and treat the obligation as possibly holding.
|result| !result.may_apply(),
)
});

if let Some(failing_obligation) = opt_failing_obligation {
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
Expand Down
13 changes: 0 additions & 13 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,19 +518,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// The result is "true" if the obligation *may* hold and "false" if
// we can be sure it does not.

/// Evaluates whether the obligation `obligation` can be satisfied (by any means).
pub fn predicate_may_hold_fatal(&mut self, obligation: &PredicateObligation<'tcx>) -> bool {
debug!(?obligation, "predicate_may_hold_fatal");

// This fatal query is a stopgap that should only be used in standard mode,
// where we do not expect overflow to be propagated.
assert!(self.query_mode == TraitQueryMode::Standard);

self.evaluate_root_obligation(obligation)
.expect("Overflow should be caught earlier in standard query mode")
.may_apply()
}

/// Evaluates whether the obligation `obligation` can be satisfied
/// and returns an `EvaluationResult`. This is meant for the
/// *initial* call.
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/traits/issue-105231.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
struct A<T>(B<T>);
//~^ ERROR recursive types `A` and `B` have infinite size
struct B<T>(A<A<T>>);
trait Foo {}
impl<T> Foo for T where T: Send {}
impl Foo for B<u8> {}

fn main() {}
29 changes: 29 additions & 0 deletions tests/ui/traits/issue-105231.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0072]: recursive types `A` and `B` have infinite size
--> $DIR/issue-105231.rs:2:1
|
LL | struct A<T>(B<T>);
| ^^^^^^^^^^^ ---- recursive without indirection
LL |
LL | struct B<T>(A<A<T>>);
| ^^^^^^^^^^^ ------- recursive without indirection
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
LL ~ struct A<T>(Box<B<T>>);
LL |
LL ~ struct B<T>(Box<A<A<T>>>);
|

error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/issue-105231.rs:4:8
|
LL | struct B<T>(A<A<T>>);
| ^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0072, E0275.
For more information about an error, try `rustc --explain E0072`.

0 comments on commit 1e90cb9

Please sign in to comment.