Skip to content

Commit

Permalink
Consider a goal as NOT changed if its response is identity modulo reg…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
compiler-errors committed Jul 27, 2023
1 parent 99f60ec commit 1ffc6ca
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
Ok(response) => response,
};

let has_changed = !canonical_response.value.var_values.is_identity()
let has_changed = !canonical_response.value.var_values.is_identity_modulo_regions()
|| !canonical_response.value.external_constraints.opaque_types.is_empty();
let (certainty, nested_goals) = match self.instantiate_and_apply_query_response(
goal.param_env,
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/autoderef.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// revisions: current next
//[next] compile-flag: -Ztrait-solver=next
//[next] compile-flags: -Ztrait-solver=next
// check-pass

use std::path::Path;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// compile-flags: -Ztrait-solver=next
// check-pass

trait Eq<'a, 'b, T> {}

trait Ambig {}
impl Ambig for () {}

impl<'a, T> Eq<'a, 'a, T> for () where T: Ambig {}

fn eq<'a, 'b, T>(t: T)
where
(): Eq<'a, 'b, T>,
{
}

fn test<'r>() {
let mut x = Default::default();

// When we evaluate `(): Eq<'r, 'r, ?0>` we uniquify the regions.
// That leads us to evaluate `(): Eq<'?0, '?1, ?0>`. The response of this
// will be ambiguous (because `?0: Ambig` is ambig) and also not an "identity"
// response, since the region constraints will contain `'?0 == '?1` (so
// `is_changed` will return true). Since it's both ambig and changed,
// fulfillment will both re-register the goal AND loop again. This hits the
// overflow limit. This should neither be considered overflow, nor ICE.
eq::<'r, 'r, _>(x);

x = ();
}

fn main() {}

0 comments on commit 1ffc6ca

Please sign in to comment.