@@ -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 ( ) ) ;
0 commit comments