Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Consider a goal as NOT changed if its response is identity modulo reg…
…ions
  • Loading branch information
compiler-errors committed Jul 27, 2023
commit 1ffc6ca9a513d1a3a928cc1d32b21d55d6326bb3
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() {}