Skip to content

Commit 7d052bd

Browse files
Merge pull request #21235 from benodiwal/fix-const-generic-param-env-panic
fix: resolve const generic param-env panic in type projection
2 parents e8ac252 + d6271ab commit 7d052bd

File tree

6 files changed

+73
-7
lines changed

6 files changed

+73
-7
lines changed

crates/hir-ty/src/infer/closure/analysis.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl<'db> HirPlace<'db> {
4343
for p in &self.projections {
4444
ty = p.projected_ty(
4545
&ctx.table.infer_ctxt,
46+
ctx.table.param_env,
4647
ty,
4748
|_, _, _| {
4849
unreachable!("Closure field only happens in MIR");
@@ -839,6 +840,7 @@ impl<'db> InferenceContext<'_, 'db> {
839840
for (i, p) in capture.place.projections.iter().enumerate() {
840841
ty = p.projected_ty(
841842
&self.table.infer_ctxt,
843+
self.table.param_env,
842844
ty,
843845
|_, _, _| {
844846
unreachable!("Closure field only happens in MIR");

crates/hir-ty/src/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::{
2525
consteval::try_const_usize,
2626
db::HirDatabase,
2727
next_solver::{
28-
DbInterner, GenericArgs, ParamEnv, Ty, TyKind, TypingMode,
28+
DbInterner, GenericArgs, Ty, TyKind, TypingMode,
2929
infer::{DbInternerInferExt, traits::ObligationCause},
3030
},
3131
};
@@ -170,7 +170,7 @@ pub fn layout_of_ty_query<'db>(
170170
let cx = LayoutCx::new(dl);
171171
let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis);
172172
let cause = ObligationCause::dummy();
173-
let ty = infer_ctxt.at(&cause, ParamEnv::empty()).deeply_normalize(ty).unwrap_or(ty);
173+
let ty = infer_ctxt.at(&cause, trait_env.param_env).deeply_normalize(ty).unwrap_or(ty);
174174
let result = match ty.kind() {
175175
TyKind::Adt(def, args) => {
176176
match def.inner().id {

crates/hir-ty/src/mir.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> {
157157
pub fn projected_ty(
158158
&self,
159159
infcx: &InferCtxt<'db>,
160+
env: ParamEnv<'db>,
160161
mut base: Ty<'db>,
161162
closure_field: impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db>,
162163
krate: Crate,
@@ -173,8 +174,6 @@ impl<'db, V: PartialEq> ProjectionElem<'db, V> {
173174

174175
if matches!(base.kind(), TyKind::Alias(..)) {
175176
let mut ocx = ObligationCtxt::new(infcx);
176-
// FIXME: we should get this from caller
177-
let env = ParamEnv::empty();
178177
match ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, base) {
179178
Ok(it) => base = it,
180179
Err(_) => return Ty::new_error(interner, ErrorGuaranteed),

crates/hir-ty/src/mir/borrowck.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub fn borrowck_query<'db>(
106106
// FIXME(next-solver): Opaques.
107107
let infcx = interner.infer_ctxt().build(typing_mode);
108108
res.push(BorrowckResult {
109-
mutability_of_locals: mutability_of_locals(&infcx, &body),
109+
mutability_of_locals: mutability_of_locals(&infcx, env, &body),
110110
moved_out_of_ref: moved_out_of_ref(&infcx, env, &body),
111111
partially_moved: partially_moved(&infcx, env, &body),
112112
borrow_regions: borrow_regions(db, &body),
@@ -146,6 +146,7 @@ fn moved_out_of_ref<'db>(
146146
}
147147
ty = proj.projected_ty(
148148
infcx,
149+
env,
149150
ty,
150151
make_fetch_closure_field(db),
151152
body.owner.module(db).krate(db),
@@ -242,6 +243,7 @@ fn partially_moved<'db>(
242243
for proj in p.projection.lookup(&body.projection_store) {
243244
ty = proj.projected_ty(
244245
infcx,
246+
env,
245247
ty,
246248
make_fetch_closure_field(db),
247249
body.owner.module(db).krate(db),
@@ -374,6 +376,7 @@ enum ProjectionCase {
374376

375377
fn place_case<'db>(
376378
infcx: &InferCtxt<'db>,
379+
env: ParamEnv<'db>,
377380
body: &MirBody<'db>,
378381
lvalue: &Place<'db>,
379382
) -> ProjectionCase {
@@ -395,6 +398,7 @@ fn place_case<'db>(
395398
}
396399
ty = proj.projected_ty(
397400
infcx,
401+
env,
398402
ty,
399403
make_fetch_closure_field(db),
400404
body.owner.module(db).krate(db),
@@ -535,6 +539,7 @@ fn record_usage_for_operand<'db>(
535539

536540
fn mutability_of_locals<'db>(
537541
infcx: &InferCtxt<'db>,
542+
env: ParamEnv<'db>,
538543
body: &MirBody<'db>,
539544
) -> ArenaMap<LocalId<'db>, MutabilityReason> {
540545
let db = infcx.interner.db;
@@ -547,7 +552,7 @@ fn mutability_of_locals<'db>(
547552
for statement in &block.statements {
548553
match &statement.kind {
549554
StatementKind::Assign(place, value) => {
550-
match place_case(infcx, body, place) {
555+
match place_case(infcx, env, body, place) {
551556
ProjectionCase::Direct => {
552557
if ever_init_map.get(place.local).copied().unwrap_or_default() {
553558
push_mut_span(place.local, statement.span, &mut result);
@@ -596,7 +601,7 @@ fn mutability_of_locals<'db>(
596601
},
597602
p,
598603
) = value
599-
&& place_case(infcx, body, p) != ProjectionCase::Indirect
604+
&& place_case(infcx, env, body, p) != ProjectionCase::Indirect
600605
{
601606
push_mut_span(p.local, statement.span, &mut result);
602607
}

crates/hir-ty/src/mir/eval.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ impl<'db> Evaluator<'db> {
722722
let (ty, proj) = pair;
723723
let r = proj.projected_ty(
724724
&self.infcx,
725+
self.param_env.param_env,
725726
ty,
726727
|c, subst, f| {
727728
let InternedClosure(def, _) = self.db.lookup_intern_closure(c);

crates/hir-ty/src/mir/lower/tests.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use hir_def::DefWithBodyId;
12
use test_fixture::WithFixture;
23

34
use crate::{db::HirDatabase, setup_tracing, test_db::TestDB};
@@ -49,3 +50,61 @@ fn foo() {
4950
"#,
5051
);
5152
}
53+
54+
fn check_borrowck(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
55+
let _tracing = setup_tracing();
56+
let (db, file_ids) = TestDB::with_many_files(ra_fixture);
57+
crate::attach_db(&db, || {
58+
let file_id = *file_ids.last().unwrap();
59+
let module_id = db.module_for_file(file_id.file_id(&db));
60+
let def_map = module_id.def_map(&db);
61+
let scope = &def_map[module_id].scope;
62+
63+
let mut bodies: Vec<DefWithBodyId> = Vec::new();
64+
65+
for decl in scope.declarations() {
66+
if let hir_def::ModuleDefId::FunctionId(f) = decl {
67+
bodies.push(f.into());
68+
}
69+
}
70+
71+
for impl_id in scope.impls() {
72+
let impl_items = impl_id.impl_items(&db);
73+
for (_, item) in impl_items.items.iter() {
74+
if let hir_def::AssocItemId::FunctionId(f) = item {
75+
bodies.push((*f).into());
76+
}
77+
}
78+
}
79+
80+
for body in bodies {
81+
let _ = db.borrowck(body);
82+
}
83+
})
84+
}
85+
86+
#[test]
87+
fn regression_21173_const_generic_impl_with_assoc_type() {
88+
check_borrowck(
89+
r#"
90+
pub trait Tr {
91+
type Assoc;
92+
fn f(&self, handle: Self::Assoc) -> i32;
93+
}
94+
95+
pub struct ConstGeneric<const N: usize>;
96+
97+
impl<const N: usize> Tr for &ConstGeneric<N> {
98+
type Assoc = AssocTy;
99+
100+
fn f(&self, a: Self::Assoc) -> i32 {
101+
a.x
102+
}
103+
}
104+
105+
pub struct AssocTy {
106+
x: i32,
107+
}
108+
"#,
109+
);
110+
}

0 commit comments

Comments
 (0)