Skip to content

Commit 6aa169d

Browse files
authored
Merge pull request #21818 from Veykril/push-ystsymytyxkl
internal: Refactor `MirLowerCtx` to use `&ExpressionStore` instead of `&Body`
2 parents 6254616 + 4568cfa commit 6aa169d

5 files changed

Lines changed: 92 additions & 54 deletions

File tree

crates/hir-ty/src/consteval.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::{
2828
traits::StoredParamEnvAndCrate,
2929
};
3030

31-
use super::mir::{interpret_mir, lower_to_mir, pad16};
31+
use super::mir::{interpret_mir, lower_body_to_mir, pad16};
3232

3333
pub fn unknown_const<'db>(_ty: Ty<'db>) -> Const<'db> {
3434
Const::new(DbInterner::conjure(), rustc_type_ir::ConstKind::Error(ErrorGuaranteed))
@@ -333,7 +333,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd
333333
return c;
334334
}
335335
}
336-
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
336+
if let Ok(mir_body) = lower_body_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
337337
&& let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None)
338338
{
339339
return result;

crates/hir-ty/src/mir.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ pub use borrowck::{BorrowckResult, MutabilityReason, borrowck_query};
4040
pub use eval::{
4141
Evaluator, MirEvalError, VTableMap, interpret_mir, pad16, render_const_using_debug_impl,
4242
};
43-
pub use lower::{MirLowerError, lower_to_mir, mir_body_for_closure_query, mir_body_query};
43+
pub use lower::{
44+
MirLowerError, lower_body_to_mir, lower_to_mir_with_store, mir_body_for_closure_query,
45+
mir_body_query,
46+
};
4447
pub use monomorphization::{
4548
monomorphized_mir_body_for_closure_query, monomorphized_mir_body_query,
4649
};

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

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct MirLowerCtx<'a, 'db> {
8282
labeled_loop_blocks: FxHashMap<LabelId, LoopBlocks>,
8383
discr_temp: Option<Place>,
8484
db: &'db dyn HirDatabase,
85-
body: &'a Body,
85+
store: &'a ExpressionStore,
8686
infer: &'a InferenceResult,
8787
types: &'db crate::next_solver::DefaultAny<'db>,
8888
resolver: Resolver<'db>,
@@ -285,7 +285,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
285285
fn new(
286286
db: &'db dyn HirDatabase,
287287
owner: DefWithBodyId,
288-
body: &'a Body,
288+
store: &'a ExpressionStore,
289289
infer: &'a InferenceResult,
290290
) -> Self {
291291
let mut basic_blocks = Arena::new();
@@ -316,7 +316,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
316316
result: mir,
317317
db,
318318
infer,
319-
body,
319+
store,
320320
types: crate::next_solver::default_types(db),
321321
owner,
322322
resolver,
@@ -354,7 +354,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
354354
current: BasicBlockId,
355355
) -> Result<'db, Option<(Operand, BasicBlockId)>> {
356356
if !self.has_adjustments(expr_id)
357-
&& let Expr::Literal(l) = &self.body[expr_id]
357+
&& let Expr::Literal(l) = &self.store[expr_id]
358358
{
359359
let ty = self.expr_ty_without_adjust(expr_id);
360360
return Ok(Some((self.lower_literal_to_operand(ty, l)?, current)));
@@ -461,7 +461,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
461461
place: Place,
462462
mut current: BasicBlockId,
463463
) -> Result<'db, Option<BasicBlockId>> {
464-
match &self.body[expr_id] {
464+
match &self.store[expr_id] {
465465
Expr::OffsetOf(_) => {
466466
not_supported!("builtin#offset_of")
467467
}
@@ -500,7 +500,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
500500
} else {
501501
let resolver_guard =
502502
self.resolver.update_to_inner_scope(self.db, self.owner, expr_id);
503-
let hygiene = self.body.expr_path_hygiene(expr_id);
503+
let hygiene = self.store.expr_path_hygiene(expr_id);
504504
let result = self
505505
.resolver
506506
.resolve_path_in_value_ns_fully(self.db, p, hygiene)
@@ -509,7 +509,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
509509
self.db,
510510
p,
511511
DisplayTarget::from_crate(self.db, self.krate()),
512-
self.body,
512+
self.store,
513513
)
514514
})?;
515515
self.resolver.reset_to_guard(resolver_guard);
@@ -882,7 +882,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
882882
let variant_id =
883883
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
884884
Some(p) => MirLowerError::UnresolvedName(
885-
hir_display_with_store(&**p, self.body)
885+
hir_display_with_store(&**p, self.store)
886886
.display(self.db, self.display_target())
887887
.to_string(),
888888
),
@@ -1382,7 +1382,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
13821382
}
13831383

13841384
fn push_field_projection(&mut self, place: &mut Place, expr_id: ExprId) -> Result<'db, ()> {
1385-
if let Expr::Field { expr, name } = &self.body[expr_id] {
1385+
if let Expr::Field { expr, name } = &self.store[expr_id] {
13861386
if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind() {
13871387
let index =
13881388
name.as_tuple_index().ok_or(MirLowerError::TypeError("named field on tuple"))?
@@ -1411,7 +1411,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
14111411
ty: Ty<'db>,
14121412
loc: &ExprId,
14131413
) -> Result<'db, Operand> {
1414-
match &self.body[*loc] {
1414+
match &self.store[*loc] {
14151415
Expr::Literal(l) => self.lower_literal_to_operand(ty, l),
14161416
Expr::Path(c) => {
14171417
let owner = self.owner;
@@ -1421,7 +1421,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
14211421
self.db,
14221422
c,
14231423
DisplayTarget::from_crate(db, owner.krate(db)),
1424-
self.body,
1424+
self.store,
14251425
)
14261426
};
14271427
let pr = self
@@ -1859,7 +1859,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
18591859
}
18601860
} else {
18611861
let mut err = None;
1862-
self.body.walk_bindings_in_pat(*pat, |b| {
1862+
self.store.walk_bindings_in_pat(*pat, |b| {
18631863
if let Err(e) = self.push_storage_live(b, current) {
18641864
err = Some(e);
18651865
}
@@ -1913,9 +1913,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
19131913
self.result.param_locals.extend(params.clone().map(|(it, ty)| {
19141914
let local_id = self.result.locals.alloc(Local { ty: ty.store() });
19151915
self.drop_scopes.last_mut().unwrap().locals.push(local_id);
1916-
if let Pat::Bind { id, subpat: None } = self.body[it]
1916+
if let Pat::Bind { id, subpat: None } = self.store[it]
19171917
&& matches!(
1918-
self.body[id].mode,
1918+
self.store[id].mode,
19191919
BindingAnnotation::Unannotated | BindingAnnotation::Mutable
19201920
)
19211921
{
@@ -1924,7 +1924,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
19241924
local_id
19251925
}));
19261926
// and then rest of bindings
1927-
for (id, _) in self.body.bindings() {
1927+
for (id, _) in self.store.bindings() {
19281928
if !pick_binding(id) {
19291929
continue;
19301930
}
@@ -1953,7 +1953,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
19531953
.into_iter()
19541954
.skip(base_param_count + self_binding.is_some() as usize);
19551955
for ((param, _), local) in params.zip(local_params) {
1956-
if let Pat::Bind { id, .. } = self.body[param]
1956+
if let Pat::Bind { id, .. } = self.store[param]
19571957
&& local == self.binding_local(id)?
19581958
{
19591959
continue;
@@ -2115,7 +2115,7 @@ pub fn mir_body_for_closure_query<'db>(
21152115
implementation_error!("closure expression is not closure");
21162116
};
21172117
let (captures, kind) = infer.closure_info(closure);
2118-
let mut ctx = MirLowerCtx::new(db, owner, &body, infer);
2118+
let mut ctx = MirLowerCtx::new(db, owner, &body.store, infer);
21192119
// 0 is return local
21202120
ctx.result.locals.alloc(Local { ty: infer.expr_ty(*root).store() });
21212121
let closure_local = ctx.result.locals.alloc(Local {
@@ -2205,7 +2205,7 @@ pub fn mir_body_for_closure_query<'db>(
22052205
.result
22062206
.binding_locals
22072207
.into_iter()
2208-
.filter(|it| ctx.body.binding_owner(it.0) == Some(expr))
2208+
.filter(|it| ctx.store.binding_owner(it.0) == Some(expr))
22092209
.collect();
22102210
if let Some(err) = err {
22112211
return Err(MirLowerError::UnresolvedUpvar(err));
@@ -2245,7 +2245,7 @@ pub fn mir_body_query<'db>(
22452245
let _p = tracing::info_span!("mir_body_query", ?detail).entered();
22462246
let body = db.body(def);
22472247
let infer = InferenceResult::for_body(db, def);
2248-
let mut result = lower_to_mir(db, def, &body, infer, body.body_expr)?;
2248+
let mut result = lower_body_to_mir(db, def, &body, infer, body.body_expr)?;
22492249
result.shrink_to_fit();
22502250
Ok(Arc::new(result))
22512251
}
@@ -2258,44 +2258,74 @@ pub(crate) fn mir_body_cycle_result<'db>(
22582258
Err(MirLowerError::Loop)
22592259
}
22602260

2261-
pub fn lower_to_mir<'db>(
2261+
/// Extracts params from `body.params`/`body.self_param` and the callable signature,
2262+
/// then delegates to [`lower_to_mir_with_store`].
2263+
pub fn lower_body_to_mir<'db>(
22622264
db: &'db dyn HirDatabase,
22632265
owner: DefWithBodyId,
22642266
body: &Body,
22652267
infer: &InferenceResult,
2266-
// FIXME: root_expr should always be the body.body_expr, but since `X` in `[(); X]` doesn't have its own specific body yet, we
2267-
// need to take this input explicitly.
2268+
// FIXME: root_expr should always be the body.body_expr,
2269+
// but this is currently also used for `X` in `[(); X]` which live in the same expression store
22682270
root_expr: ExprId,
2271+
) -> Result<'db, MirBody> {
2272+
let is_root = root_expr == body.body_expr;
2273+
// Extract params and self_param only when lowering the body's root expression for a function.
2274+
if is_root && let DefWithBodyId::FunctionId(fid) = owner {
2275+
let callable_sig =
2276+
db.callable_item_signature(fid.into()).instantiate_identity().skip_binder();
2277+
let mut param_tys = callable_sig.inputs().iter().copied();
2278+
let self_param = body.self_param.and_then(|id| Some((id, param_tys.next()?)));
2279+
2280+
lower_to_mir_with_store(
2281+
db,
2282+
owner,
2283+
&body.store,
2284+
infer,
2285+
root_expr,
2286+
body.params.iter().copied().zip(param_tys),
2287+
self_param,
2288+
is_root,
2289+
)
2290+
} else {
2291+
lower_to_mir_with_store(
2292+
db,
2293+
owner,
2294+
&body.store,
2295+
infer,
2296+
root_expr,
2297+
iter::empty(),
2298+
None,
2299+
is_root,
2300+
)
2301+
}
2302+
}
2303+
2304+
/// # Parameters
2305+
/// - `is_root`: `true` when `root_expr` is the body's top-level expression (picks
2306+
/// bindings with no owner); `false` when lowering an inline const or anonymous
2307+
/// const (picks bindings owned by `root_expr`).
2308+
pub fn lower_to_mir_with_store<'db>(
2309+
db: &'db dyn HirDatabase,
2310+
owner: DefWithBodyId,
2311+
store: &ExpressionStore,
2312+
infer: &InferenceResult,
2313+
root_expr: ExprId,
2314+
params: impl Iterator<Item = (PatId, Ty<'db>)> + Clone,
2315+
self_param: Option<(BindingId, Ty<'db>)>,
2316+
is_root: bool,
22692317
) -> Result<'db, MirBody> {
22702318
if infer.type_mismatches().next().is_some() || infer.is_erroneous() {
22712319
return Err(MirLowerError::HasErrors);
22722320
}
2273-
let mut ctx = MirLowerCtx::new(db, owner, body, infer);
2321+
let mut ctx = MirLowerCtx::new(db, owner, store, infer);
22742322
// 0 is return local
22752323
ctx.result.locals.alloc(Local { ty: ctx.expr_ty_after_adjustments(root_expr).store() });
22762324
let binding_picker = |b: BindingId| {
2277-
let owner = ctx.body.binding_owner(b);
2278-
if root_expr == body.body_expr { owner.is_none() } else { owner == Some(root_expr) }
2279-
};
2280-
// 1 to param_len is for params
2281-
// FIXME: replace with let chain once it becomes stable
2282-
let current = 'b: {
2283-
if body.body_expr == root_expr {
2284-
// otherwise it's an inline const, and has no parameter
2285-
if let DefWithBodyId::FunctionId(fid) = owner {
2286-
let callable_sig =
2287-
db.callable_item_signature(fid.into()).instantiate_identity().skip_binder();
2288-
let mut params = callable_sig.inputs().iter().copied();
2289-
let self_param = body.self_param.and_then(|id| Some((id, params.next()?)));
2290-
break 'b ctx.lower_params_and_bindings(
2291-
body.params.iter().zip(params).map(|(it, y)| (*it, y)),
2292-
self_param,
2293-
binding_picker,
2294-
)?;
2295-
}
2296-
}
2297-
ctx.lower_params_and_bindings([].into_iter(), None, binding_picker)?
2325+
let owner = ctx.store.binding_owner(b);
2326+
if is_root { owner.is_none() } else { owner == Some(root_expr) }
22982327
};
2328+
let current = ctx.lower_params_and_bindings(params, self_param, binding_picker)?;
22992329
if let Some(current) = ctx.lower_expr_to_place(root_expr, return_slot().into(), current)? {
23002330
let current = ctx.pop_drop_scope_assert_finished(current, root_expr.into())?;
23012331
ctx.set_terminator(current, TerminatorKind::Return, root_expr.into());

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ impl<'db> MirLowerCtx<'_, 'db> {
137137
}
138138
this.lower_expr_to_some_place_without_adjust(expr_id, current)
139139
};
140-
match &self.body[expr_id] {
140+
match &self.store[expr_id] {
141141
Expr::Path(p) => {
142142
let resolver_guard =
143143
self.resolver.update_to_inner_scope(self.db, self.owner, expr_id);
144-
let hygiene = self.body.expr_path_hygiene(expr_id);
144+
let hygiene = self.store.expr_path_hygiene(expr_id);
145145
let resolved = self.resolver.resolve_path_in_value_ns_fully(self.db, p, hygiene);
146146
self.resolver.reset_to_guard(resolver_guard);
147147
let Some(pr) = resolved else {

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
131131
.collect::<Vec<_>>()
132132
.into(),
133133
);
134-
Ok(match &self.body[pattern] {
134+
Ok(match &self.store[pattern] {
135135
Pat::Missing => return Err(MirLowerError::IncompletePattern),
136136
Pat::Wild => (current, current_else),
137137
Pat::Tuple { args, ellipsis } => {
@@ -322,7 +322,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
322322
}
323323
if let &Some(slice) = slice
324324
&& mode != MatchingMode::Check
325-
&& let Pat::Bind { id, subpat: _ } = self.body[slice]
325+
&& let Pat::Bind { id, subpat: _ } = self.store[slice]
326326
{
327327
let next_place = cond_place.project(
328328
ProjectionElem::Subslice {
@@ -363,9 +363,14 @@ impl<'db> MirLowerCtx<'_, 'db> {
363363
)?,
364364
None => {
365365
let unresolved_name = || {
366-
MirLowerError::unresolved_path(self.db, p, self.display_target(), self.body)
366+
MirLowerError::unresolved_path(
367+
self.db,
368+
p,
369+
self.display_target(),
370+
self.store,
371+
)
367372
};
368-
let hygiene = self.body.pat_path_hygiene(pattern);
373+
let hygiene = self.store.pat_path_hygiene(pattern);
369374
let pr = self
370375
.resolver
371376
.resolve_path_in_value_ns(self.db, p, hygiene)
@@ -432,7 +437,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
432437
(next, Some(else_target))
433438
}
434439
},
435-
Pat::Lit(l) => match &self.body[*l] {
440+
Pat::Lit(l) => match &self.store[*l] {
436441
Expr::Literal(l) => {
437442
if mode == MatchingMode::Check {
438443
let c = self.lower_literal_to_operand(self.infer.pat_ty(pattern), l)?;

0 commit comments

Comments
 (0)