Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/layout.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir.rs | 3 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/borrowck.rs | 11 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/lower/tests.rs | 59 |
6 files changed, 73 insertions, 7 deletions
diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index d6d63891bb..308c01865a 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -43,6 +43,7 @@ impl<'db> HirPlace<'db> { for p in &self.projections { ty = p.projected_ty( &ctx.table.infer_ctxt, + ctx.table.param_env, ty, |_, _, _| { unreachable!("Closure field only happens in MIR"); @@ -839,6 +840,7 @@ impl<'db> InferenceContext<'_, 'db> { for (i, p) in capture.place.projections.iter().enumerate() { ty = p.projected_ty( &self.table.infer_ctxt, + self.table.param_env, ty, |_, _, _| { unreachable!("Closure field only happens in MIR"); diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index 565063fb13..4b20d6eb32 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -25,7 +25,7 @@ use crate::{ consteval::try_const_usize, db::HirDatabase, next_solver::{ - DbInterner, GenericArgs, ParamEnv, Ty, TyKind, TypingMode, + DbInterner, GenericArgs, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, traits::ObligationCause}, }, }; @@ -170,7 +170,7 @@ pub fn layout_of_ty_query<'db>( let cx = LayoutCx::new(dl); let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); - let ty = infer_ctxt.at(&cause, ParamEnv::empty()).deeply_normalize(ty).unwrap_or(ty); + let ty = infer_ctxt.at(&cause, trait_env.param_env).deeply_normalize(ty).unwrap_or(ty); let result = match ty.kind() { TyKind::Adt(def, args) => { match def.inner().id { diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index 3cafb6aa25..836c20a433 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -157,6 +157,7 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { pub fn projected_ty( &self, infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, mut base: Ty<'db>, closure_field: impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db>, krate: Crate, @@ -173,8 +174,6 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> { if matches!(base.kind(), TyKind::Alias(..)) { let mut ocx = ObligationCtxt::new(infcx); - // FIXME: we should get this from caller - let env = ParamEnv::empty(); match ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, base) { Ok(it) => base = it, Err(_) => return Ty::new_error(interner, ErrorGuaranteed), diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs index 4d76a9f3fb..b39c9bc065 100644 --- a/crates/hir-ty/src/mir/borrowck.rs +++ b/crates/hir-ty/src/mir/borrowck.rs @@ -106,7 +106,7 @@ pub fn borrowck_query<'db>( // FIXME(next-solver): Opaques. let infcx = interner.infer_ctxt().build(typing_mode); res.push(BorrowckResult { - mutability_of_locals: mutability_of_locals(&infcx, &body), + mutability_of_locals: mutability_of_locals(&infcx, env, &body), moved_out_of_ref: moved_out_of_ref(&infcx, env, &body), partially_moved: partially_moved(&infcx, env, &body), borrow_regions: borrow_regions(db, &body), @@ -146,6 +146,7 @@ fn moved_out_of_ref<'db>( } ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -242,6 +243,7 @@ fn partially_moved<'db>( for proj in p.projection.lookup(&body.projection_store) { ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -374,6 +376,7 @@ enum ProjectionCase { fn place_case<'db>( infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, lvalue: &Place<'db>, ) -> ProjectionCase { @@ -395,6 +398,7 @@ fn place_case<'db>( } ty = proj.projected_ty( infcx, + env, ty, make_fetch_closure_field(db), body.owner.module(db).krate(db), @@ -535,6 +539,7 @@ fn record_usage_for_operand<'db>( fn mutability_of_locals<'db>( infcx: &InferCtxt<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, ) -> ArenaMap<LocalId<'db>, MutabilityReason> { let db = infcx.interner.db; @@ -547,7 +552,7 @@ fn mutability_of_locals<'db>( for statement in &block.statements { match &statement.kind { StatementKind::Assign(place, value) => { - match place_case(infcx, body, place) { + match place_case(infcx, env, body, place) { ProjectionCase::Direct => { if ever_init_map.get(place.local).copied().unwrap_or_default() { push_mut_span(place.local, statement.span, &mut result); @@ -596,7 +601,7 @@ fn mutability_of_locals<'db>( }, p, ) = value - && place_case(infcx, body, p) != ProjectionCase::Indirect + && place_case(infcx, env, body, p) != ProjectionCase::Indirect { push_mut_span(p.local, statement.span, &mut result); } diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 35b45174c2..3b4913cae3 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -722,6 +722,7 @@ impl<'db> Evaluator<'db> { let (ty, proj) = pair; let r = proj.projected_ty( &self.infcx, + self.param_env.param_env, ty, |c, subst, f| { let InternedClosure(def, _) = self.db.lookup_intern_closure(c); diff --git a/crates/hir-ty/src/mir/lower/tests.rs b/crates/hir-ty/src/mir/lower/tests.rs index 357f617a21..73399dab7f 100644 --- a/crates/hir-ty/src/mir/lower/tests.rs +++ b/crates/hir-ty/src/mir/lower/tests.rs @@ -1,3 +1,4 @@ +use hir_def::DefWithBodyId; use test_fixture::WithFixture; use crate::{db::HirDatabase, setup_tracing, test_db::TestDB}; @@ -49,3 +50,61 @@ fn foo() { "#, ); } + +fn check_borrowck(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + let _tracing = setup_tracing(); + let (db, file_ids) = TestDB::with_many_files(ra_fixture); + crate::attach_db(&db, || { + let file_id = *file_ids.last().unwrap(); + let module_id = db.module_for_file(file_id.file_id(&db)); + let def_map = module_id.def_map(&db); + let scope = &def_map[module_id].scope; + + let mut bodies: Vec<DefWithBodyId> = Vec::new(); + + for decl in scope.declarations() { + if let hir_def::ModuleDefId::FunctionId(f) = decl { + bodies.push(f.into()); + } + } + + for impl_id in scope.impls() { + let impl_items = impl_id.impl_items(&db); + for (_, item) in impl_items.items.iter() { + if let hir_def::AssocItemId::FunctionId(f) = item { + bodies.push((*f).into()); + } + } + } + + for body in bodies { + let _ = db.borrowck(body); + } + }) +} + +#[test] +fn regression_21173_const_generic_impl_with_assoc_type() { + check_borrowck( + r#" +pub trait Tr { + type Assoc; + fn f(&self, handle: Self::Assoc) -> i32; +} + +pub struct ConstGeneric<const N: usize>; + +impl<const N: usize> Tr for &ConstGeneric<N> { + type Assoc = AssocTy; + + fn f(&self, a: Self::Assoc) -> i32 { + a.x + } +} + +pub struct AssocTy { + x: i32, +} + "#, + ); +} |