diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs index fdd501723fb5..fc2bd87ee429 100644 --- a/crates/hir-ty/src/method_resolution/probe.rs +++ b/crates/hir-ty/src/method_resolution/probe.rs @@ -285,11 +285,15 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { let infcx = self.infcx; let (self_ty, var_values) = infcx.instantiate_canonical(&query_input); debug!(?self_ty, ?query_input, "probe_op: Mode::Path"); + let prev_opaque_entries = + self.infcx.inner.borrow_mut().opaque_types().num_entries(); MethodAutoderefStepsResult { steps: smallvec![CandidateStep { - self_ty: self - .infcx - .make_query_response_ignoring_pending_obligations(var_values, self_ty), + self_ty: self.infcx.make_query_response_ignoring_pending_obligations( + var_values, + self_ty, + prev_opaque_entries + ), self_ty_is_opaque: false, autoderefs: 0, from_unsafe_deref: false, @@ -376,6 +380,8 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { // infer var is not an opaque. let infcx = self.infcx; let (self_ty, inference_vars) = infcx.instantiate_canonical(self_ty); + let prev_opaque_entries = infcx.inner.borrow_mut().opaque_types().num_entries(); + let self_ty_is_opaque = |ty: Ty<'_>| { if let TyKind::Infer(InferTy::TyVar(vid)) = ty.kind() { infcx.has_opaques_with_sub_unified_hidden_type(vid) @@ -414,6 +420,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { self_ty: infcx.make_query_response_ignoring_pending_obligations( inference_vars, ty, + prev_opaque_entries, ), self_ty_is_opaque: self_ty_is_opaque(ty), autoderefs: d, @@ -437,6 +444,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { self_ty: infcx.make_query_response_ignoring_pending_obligations( inference_vars, ty, + prev_opaque_entries, ), self_ty_is_opaque: self_ty_is_opaque(ty), autoderefs: d, @@ -461,13 +469,17 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { ty: infcx.make_query_response_ignoring_pending_obligations( inference_vars, final_ty, + prev_opaque_entries, ), }) } TyKind::Error(_) => Some(MethodAutoderefBadTy { reached_raw_pointer, - ty: infcx - .make_query_response_ignoring_pending_obligations(inference_vars, final_ty), + ty: infcx.make_query_response_ignoring_pending_obligations( + inference_vars, + final_ty, + prev_opaque_entries, + ), }), TyKind::Array(elem_ty, _) => { let autoderefs = steps.iter().filter(|s| s.reachable_via_deref).count() - 1; @@ -475,6 +487,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { self_ty: infcx.make_query_response_ignoring_pending_obligations( inference_vars, Ty::new_slice(infcx.interner, elem_ty), + prev_opaque_entries, ), self_ty_is_opaque: false, autoderefs, diff --git a/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs b/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs index b758042e85b0..61d1e9774622 100644 --- a/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs +++ b/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs @@ -15,6 +15,7 @@ use crate::next_solver::{ infer::{ InferCtxt, InferOk, InferResult, canonical::{QueryRegionConstraints, QueryResponse, canonicalizer::OriginalQueryValues}, + opaque_types::table::OpaqueTypeStorageEntries, traits::{ObligationCause, PredicateObligations}, }, }; @@ -194,6 +195,7 @@ impl<'db> InferCtxt<'db> { &self, inference_vars: CanonicalVarValues<'db>, answer: T, + prev_entries: OpaqueTypeStorageEntries, ) -> Canonical<'db, QueryResponse<'db, T>> where T: TypeFoldable>, @@ -209,7 +211,7 @@ impl<'db> InferCtxt<'db> { .inner .borrow_mut() .opaque_type_storage - .iter_opaque_types() + .opaque_types_added_since(prev_entries) .map(|(k, v)| (k, v.ty)) .collect(); diff --git a/crates/hir-ty/src/tests/opaque_types.rs b/crates/hir-ty/src/tests/opaque_types.rs index ca986336ff30..21d830ed51e3 100644 --- a/crates/hir-ty/src/tests/opaque_types.rs +++ b/crates/hir-ty/src/tests/opaque_types.rs @@ -1,5 +1,7 @@ use expect_test::expect; +use crate::tests::check_infer; + use super::{check_infer_with_mismatches, check_no_mismatches, check_types}; #[test] @@ -176,3 +178,37 @@ fn main() { "#, ); } + +#[test] +fn regression_21455() { + check_infer( + r#" +//- minicore: copy + +struct Vec(T); +impl Vec { + pub fn new() -> Self { loop {} } +} + +pub struct Miku {} + +impl Miku { + pub fn all_paths_to(&self) -> impl Copy { + Miku { + full_paths: Vec::new(), + } + } +} + "#, + expect![[r#" + 61..72 '{ loop {} }': Vec + 63..70 'loop {}': ! + 68..70 '{}': () + 133..137 'self': &'? Miku + 152..220 '{ ... }': Miku + 162..214 'Miku {... }': Miku + 193..201 'Vec::new': fn new<{unknown}>() -> Vec<{unknown}> + 193..203 'Vec::new()': Vec<{unknown}> + "#]], + ); +}