diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index f9b08efad88cf..548d99a5f96c0 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -340,6 +340,9 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries { self.inner.borrow_mut().opaque_types().num_entries() } + fn num_opaques_in_storage(&self) -> usize { + self.inner.borrow_mut().opaque_types().num_opaques() + } fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect() } diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index 066d12be320a2..085e81c6f5b37 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -72,6 +72,10 @@ impl<'tcx> OpaqueTypeStorage<'tcx> { } } + pub fn num_opaques(&self) -> usize { + self.opaque_types.len() + } + pub fn opaque_types_added_since( &self, prev_entries: OpaqueTypeStorageEntries, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 60813f00dd4c9..037de93a076a2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -24,7 +24,7 @@ use rustc_type_ir::{ use thin_vec::ThinVec; use tracing::{Level, debug, instrument, trace, warn}; -use super::has_only_region_constraints; +use super::has_only_region_constraints_or_opaques; use crate::canonical::{ canonicalize_goal, canonicalize_response, instantiate_and_apply_query_response, response_no_constraints_raw, @@ -671,7 +671,7 @@ where ) .entered(); - let (result, orig_values, canonical_goal, succeeded_in_erased) = 'retry_canonicalize: { + let (result, orig_values, succeeded_in_erased) = 'retry_canonicalize: { let skip_erased_attempt = match typing_mode { TypingMode::Reflection | TypingMode::Coherence => true, TypingMode::Typeck { .. } @@ -737,7 +737,6 @@ where break 'retry_canonicalize ( canonical_result, orig_values, - canonical_goal, SucceededInErased::Yes { accessed_opaques }, ); } @@ -746,7 +745,6 @@ where break 'retry_canonicalize ( canonical_result, orig_values, - canonical_goal, // If we're propagating up, we should never retry the goal. // That means `No` is fine to return, it doesn't really matter. SucceededInErased::No, @@ -770,7 +768,7 @@ where "we run without TypingMode::ErasedNotCoherence, so opaques are available, and we don't retry if the outer typing mode is ErasedNotCoherence: {accessed_opaques:?} after {goal:?}" ); - (canonical_result, orig_values, canonical_goal, SucceededInErased::No) + (canonical_result, orig_values, SucceededInErased::No) }; debug!(?result); @@ -787,8 +785,11 @@ where drop(tracing_span); - let has_changed = - if !has_only_region_constraints(response) { HasChanged::Yes } else { HasChanged::No }; + let has_changed = if !has_only_region_constraints_or_opaques(response) { + HasChanged::Yes + } else { + HasChanged::No + }; let (normalization_nested_goals, certainty) = instantiate_and_apply_query_response( self.delegate, @@ -816,12 +817,9 @@ where // that is not resolved. Only when *these* have changed is it meaningful // to recompute this goal. HasChanged::Yes => None, - HasChanged::No => Some(self.build_stalled_on( - canonical_goal, - maybe_info, - orig_values, - succeeded_in_erased, - )), + HasChanged::No => { + Some(self.build_stalled_on(maybe_info, orig_values, succeeded_in_erased)) + } }, }; @@ -833,7 +831,6 @@ where fn build_stalled_on( &self, - canonical_goal: I::CanonicalInput, maybe_info: MaybeInfo, stalled_vars: ThinVec, previously_succeeded_in_erased: SucceededInErased, @@ -870,11 +867,7 @@ where sub_roots, stalled_maybe_info: maybe_info, opaques: GoalStalledOnOpaques::Yes { - num_opaques_in_storage: canonical_goal - .canonical - .value - .predefined_opaques_in_body - .len(), + num_opaques_in_storage: self.delegate.num_opaques_in_storage(), previously_succeeded_in_erased, }, } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 8d20bcf4c7a6d..faf1b7e91f0f4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -79,6 +79,17 @@ fn has_only_region_constraints(response: ty::Canonical( + response: ty::Canonical>, +) -> bool { + let ExternalConstraintsData { + region_constraints: _, + opaque_types: _, + ref normalization_nested_goals, + } = *response.value.external_constraints; + response.value.var_values.is_identity_modulo_regions() && normalization_nested_goals.is_empty() +} + impl<'a, D, I> EvalCtxt<'a, D> where D: SolverDelegate, diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 8e0fe21b46c65..0f2051938462c 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -549,6 +549,7 @@ pub trait InferCtxtLike: Sized { type OpaqueTypeStorageEntries: OpaqueTypeStorageEntries; fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries; + fn num_opaques_in_storage(&self) -> usize; fn clone_opaque_types_lookup_table( &self, ) -> Vec<(ty::OpaqueTypeKey, ::Ty)>; diff --git a/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.rs b/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.rs index 29c4d8a6a02a3..eebbbaeb314f3 100644 --- a/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.rs +++ b/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.rs @@ -19,6 +19,6 @@ impl Trait for () { #[define_opaque(Foo)] fn foo() -> Foo {} -//~^ ERROR item does not constrain `Foo::{opaque#0}` +//~^ ERROR type annotations needed fn main() {} diff --git a/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.stderr b/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.stderr index 87b225e58c06b..ee8b67fda43c6 100644 --- a/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.stderr +++ b/tests/ui/assumptions_on_binders/canonical-response-placeholder-assumptions-issue-159889.stderr @@ -1,15 +1,9 @@ -error: item does not constrain `Foo::{opaque#0}` - --> $DIR/canonical-response-placeholder-assumptions-issue-159889.rs:21:4 +error[E0282]: type annotations needed + --> $DIR/canonical-response-placeholder-assumptions-issue-159889.rs:21:13 | LL | fn foo() -> Foo {} - | ^^^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/canonical-response-placeholder-assumptions-issue-159889.rs:13:12 - | -LL | type Foo = impl for<'a> Trait = FooAssoc<'a>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ cannot infer type error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0282`.