diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2f1b2ce9c4c..7c60d3b4bd8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -399,8 +399,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } let hir = self.infcx.tcx.hir(); - if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) { - let expr = hir.body(body_id).value; + if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) { + let expr = body.value; let place = &self.move_data.move_paths[mpi].place; let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); let mut finder = ExpressionFinder { @@ -556,11 +556,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. let map = self.infcx.tcx.hir(); - let body_id = map.body_owned_by(self.mir_def_id()); - let body = map.body(body_id); + let body = map.body_owned_by(self.mir_def_id()); let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; - visitor.visit_body(body); + visitor.visit_body(&body); let mut show_assign_sugg = false; let isnt_initialized = if let InitializationRequiringAction::PartialAssignment @@ -665,7 +664,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let mut visitor = LetVisitor { decl_span, sugg_span: None }; - visitor.visit_body(body); + visitor.visit_body(&body); if let Some(span) = visitor.sugg_span { self.suggest_assign_value(&mut err, moved_place, span); } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 79b48508585..78798545c26 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -647,8 +647,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let Some(local_def_id) = def_id.as_local() else { return }; - let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return }; - let body = self.infcx.tcx.hir().body(body_id); + let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return }; let mut v = SuggestIndexOperatorAlternativeVisitor { assign_span: span, @@ -656,7 +655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ty, suggested: false, }; - v.visit_body(body); + v.visit_body(&body); if !v.suggested { err.help(format!( "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API", @@ -746,9 +745,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) - && let body = self.infcx.tcx.hir().body(body_id) - && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value() + && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, @@ -867,8 +865,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } } - if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id()) - && let Block(block, _) = hir_map.body(body_id).value.kind + if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id()) + && let Block(block, _) = body.value.kind { // `span` corresponds to the expression being iterated, find the `for`-loop desugared // expression with that span in order to identify potential fixes when encountering a @@ -1189,10 +1187,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some((false, err_label_span, message, _)) => { let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) { - let body = self.infcx.tcx.hir().body(body_id); - BindingFinder { span: err_label_span }.visit_body(body).break_value() + BindingFinder { span: err_label_span }.visit_body(&body).break_value() } else { None }; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e11e4a7247c..15a8764aab3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1183,8 +1183,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { let map = self.infcx.tcx.hir(); - let body_id = map.body_owned_by(self.mir_def_id()); - let expr = &map.body(body_id).value.peel_blocks(); + let body = map.body_owned_by(self.mir_def_id()); + let expr = &body.value.peel_blocks(); let mut closure_span = None::; match expr.kind { hir::ExprKind::MethodCall(.., args, _) => { diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index fe426b8111c..8acba57b7a6 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -169,7 +169,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { self.tcx .hir() .maybe_body_owned_by(expr.hir_id.owner.def_id) - .map(|body_id| self.tcx.typeck_body(body_id)) + .map(|body_id| self.tcx.typeck_body(body_id.id())) }); if let Some(typeck_results) = typeck_results { diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index dcddb266208..30b03b43872 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -896,7 +896,7 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { let mut visitor = RegionResolutionVisitor { tcx, scope_tree: ScopeTree::default(), @@ -907,9 +907,8 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { fixup_scopes: vec![], }; - let body = tcx.hir().body(body_id); visitor.scope_tree.root_body = Some(body.value.hir_id); - visitor.visit_body(body); + visitor.visit_body(&body); visitor.scope_tree } else { ScopeTree::default() diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index c2e62e4c003..a599e8d05fd 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -207,10 +207,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir = self.tcx.hir(); // First, check that we're actually in the tail of a function. - let Some(body_id) = hir.maybe_body_owned_by(self.body_id) else { + let Some(body) = hir.maybe_body_owned_by(self.body_id) else { return; }; - let body = hir.body(body_id); let hir::ExprKind::Block(block, _) = body.value.kind else { return; }; diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 7916366ef08..fa147f9bfcf 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -327,8 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; - let body = - hir.body(hir.maybe_body_owned_by(self.body_id).expect("expected item to have body")); + let body = hir.body_owned_by(self.body_id); expr_finder.visit_expr(body.value); // Replaces all of the variables in the given type with a fresh inference variable. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 364f0fec202..061d9507a35 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -909,8 +909,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the first place. assert_ne!(encl_item_id.def_id, encl_body_owner_id); - let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id); - let encl_body = self.tcx.hir().body(encl_body_id); + let encl_body = self.tcx.hir().body_owned_by(encl_body_owner_id); err.encl_body_span = Some(encl_body.value.span); err.encl_fn_span = Some(*encl_fn_span); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index e8533c68c79..7d6fdc9392e 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -544,9 +544,8 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( root_ctxt: &'a TypeckRootCtxt<'tcx>, body_id: LocalDefId, ) -> UnordMap { - let body_id = + let body = root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); - let body = root_ctxt.tcx.hir().body(body_id); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 0d7f59c4871..7cefe189bd6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1973,8 +1973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { *expr } else { let body_def_id = hir.enclosing_body_owner(expr.hir_id); - let body_id = hir.body_owned_by(body_def_id); - let body = hir.body(body_id); + let body = hir.body_owned_by(body_def_id); // Get tail expr of the body match body.value.kind { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 54af8354c4c..af7b68bc36b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -505,9 +505,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::def::Res::Local(recv_id) = path.res && let Some(segment) = path.segments.first() { - let map = self.infcx.tcx.hir(); - let body_id = self.tcx.hir().body_owned_by(self.body_id); - let body = map.body(body_id); + let body = self.tcx.hir().body_owned_by(self.body_id); if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { let mut let_visitor = LetVisitor { @@ -518,7 +516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name, sugg_let: None, }; - let_visitor.visit_body(body); + let_visitor.visit_body(&body); if let Some(sugg_let) = let_visitor.sugg_let && let Some(self_ty) = self.node_ty_opt(sugg_let.init_hir_id) { @@ -2429,9 +2427,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { seg1.ident.span, StashKey::CallAssocMethod, |err| { - let map = self.infcx.tcx.hir(); - let body_id = self.tcx.hir().body_owned_by(self.body_id); - let body = map.body(body_id); + let body = self.tcx.hir().body_owned_by(self.body_id); struct LetVisitor { ident_name: Symbol, } @@ -2453,7 +2449,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id) && let ControlFlow::Break(Some(expr)) = - (LetVisitor { ident_name: seg1.ident.name }).visit_body(body) + (LetVisitor { ident_name: seg1.ident.name }).visit_body(&body) && let Some(self_ty) = self.node_ty_opt(expr.hir_id) { let probe = self.lookup_probe_for_diagnostic( diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 63d41a1faf3..fb8c843f309 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -457,10 +457,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); - if let Some(body_id) = self.tcx.hir().maybe_body_owned_by( + if let Some(body) = self.tcx.hir().maybe_body_owned_by( self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), ) { - let expr = self.tcx.hir().body(body_id).value; + let expr = body.value; local_visitor.visit_expr(expr); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 5f3f1081ca8..83145e4f7b2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -62,14 +62,13 @@ pub fn find_param_with_region<'tcx>( _ => {} } - let body_id = hir.maybe_body_owned_by(def_id)?; + let body = hir.maybe_body_owned_by(def_id)?; - let owner_id = hir.body_owner(body_id); + let owner_id = hir.body_owner(body.id()); let fn_decl = hir.fn_decl_by_hir_id(owner_id)?; let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); - let body = hir.body(body_id); body.params .iter() .take(if fn_sig.c_variadic { diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index c333f024ad1..17fb760295a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -580,10 +580,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body_id| { - let body = self.tcx.hir().body(body_id); + self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body| { IfVisitor { err_span: span, found_if: false } - .visit_body(body) + .visit_body(&body) .is_break() .then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() }) }) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4587a4315e3..4f186981a76 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1677,9 +1677,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); - let body_id = tcx.hir().maybe_body_owned_by(def_id); - if let Some(body_id) = body_id { - let const_data = rendered_const(self.tcx, body_id); + let body = tcx.hir().maybe_body_owned_by(def_id); + if let Some(body) = body { + let const_data = rendered_const(self.tcx, &body, def_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); } } @@ -2368,9 +2368,9 @@ pub fn provide(providers: &mut Providers) { /// Whenever possible, prefer to evaluate the constant first and try to /// use a different method for pretty-printing. Ideally this function /// should only ever be used as a fallback. -pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { +pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body<'_>, def_id: LocalDefId) -> String { let hir = tcx.hir(); - let value = &hir.body(body).value; + let value = body.value; #[derive(PartialEq, Eq)] enum Classification { @@ -2426,13 +2426,13 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String { // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and // other formatting artifacts. - Literal | Simple => id_to_string(&hir, body.hir_id), + Literal | Simple => id_to_string(&hir, body.id().hir_id), // FIXME: Omit the curly braces if the enclosing expression is an array literal // with a repeated element (an `ExprKind::Repeat`) as in such case it // would not actually need any disambiguation. Complex => { - if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst { + if tcx.def_kind(def_id) == DefKind::AnonConst { "{ _ }".to_owned() } else { "_".to_owned() diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ff8d2919705..665cd883d44 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use crate::hir::ModuleItems; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::query::LocalCrate; @@ -254,13 +256,26 @@ impl<'hir> Map<'hir> { /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. - pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option { - self.tcx.hir_node_by_def_id(id).body_id() + pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option>> { + Some(match self.tcx.def_kind(id) { + // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler. + DefKind::InlineConst => { + let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id)); + Cow::Owned(Body { + params: &[], + value: match e.kind { + ExprKind::ConstBlock(body) => body, + _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"), + }, + }) + } + _ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)), + }) } /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] - pub fn body_owned_by(self, id: LocalDefId) -> BodyId { + pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> { self.maybe_body_owned_by(id).unwrap_or_else(|| { let hir_id = self.tcx.local_def_id_to_hir_id(id); span_bug!( diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index d39422b2b04..b0c14cdfec9 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -194,8 +194,7 @@ pub fn provide(providers: &mut Providers) { }; providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); - let hir_id = tcx.local_def_id_to_hir_id(def_id); - if let Some(body_id) = hir.maybe_body_owned_by(def_id) { + if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() { tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) } else if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), @@ -204,11 +203,15 @@ pub fn provide(providers: &mut Providers) { | Node::ForeignItem(&ForeignItem { kind: ForeignItemKind::Fn(_, idents, _), .. - }) = tcx.hir_node(hir_id) + }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id)) { idents } else { - span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", def_id); + span_bug!( + hir.span(tcx.local_def_id_to_hir_id(def_id)), + "fn_arg_names: unexpected item {:?}", + def_id + ); } }; providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 13112f2b12c..14d1b502474 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -452,7 +452,7 @@ fn construct_fn<'tcx>( assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body_id = tcx.hir().body_owned_by(fn_def); + let body = tcx.hir().body_owned_by(fn_def); let span_with_body = tcx.hir().span_with_body(fn_id); let return_ty_span = tcx .hir() @@ -512,9 +512,9 @@ fn construct_fn<'tcx>( ); let call_site_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite }; + region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::CallSite }; let arg_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments }; + region::Scope { id: body.id().hir_id.local_id, data: region::ScopeData::Arguments }; let source_info = builder.source_info(span); let call_site_s = (call_site_scope, source_info); unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index bd72ef28cb3..bd9e34ae80f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -13,10 +13,10 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::HirId; use rustc_hir::Node; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; -use rustc_middle::{bug, span_bug}; use tracing::instrument; pub(crate) fn thir_body( @@ -24,22 +24,7 @@ pub(crate) fn thir_body( owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); - let body; - let body = match tcx.def_kind(owner_def) { - // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler. - DefKind::InlineConst => { - let e = hir.expect_expr(tcx.local_def_id_to_hir_id(owner_def)); - body = hir::Body { - params: &[], - value: match e.kind { - hir::ExprKind::ConstBlock(body) => body, - _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"), - }, - }; - &body - } - _ => hir.body(hir.body_owned_by(owner_def)), - }; + let body = hir.body_owned_by(owner_def); let mut cx = Cx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); @@ -49,7 +34,7 @@ pub(crate) fn thir_body( let owner_id = tcx.local_def_id_to_hir_id(owner_def); if let Some(fn_decl) = hir.fn_decl_by_hir_id(owner_id) { let closure_env_param = cx.closure_env_param(owner_def, owner_id); - let explicit_params = cx.explicit_params(owner_id, fn_decl, body); + let explicit_params = cx.explicit_params(owner_id, fn_decl, &body); cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect(); // The resume argument may be missing, in that case we need to provide it here. diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 93ae105150c..a8741254ffb 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -226,7 +226,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // typeck instead of during ast lowering, like all other bodies so far. for def_id in tcx.hir().body_owners() { // Incremental performance optimization: only load typeck results for things that actually have inline consts - if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).hir_id.owner).has_inline_consts { + if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).id().hir_id.owner).has_inline_consts + { set.extend(tcx.typeck(def_id).inline_consts.values()) } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 1f966be26ff..698f15015c4 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -158,9 +158,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let mut maps = IrMaps::new(tcx); - let body_id = tcx.hir().body_owned_by(def_id); - let hir_id = tcx.hir().body_owner(body_id); - let body = tcx.hir().body(body_id); + let body = tcx.hir().body_owned_by(def_id); + let hir_id = tcx.hir().body_owner(body.id()); if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { @@ -171,17 +170,17 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // gather up the various local variables, significant expressions, // and so forth: - maps.visit_body(body); + maps.visit_body(&body); // compute liveness let mut lsets = Liveness::new(&mut maps, def_id); - let entry_ln = lsets.compute(body, hir_id); - lsets.log_liveness(entry_ln, body_id.hir_id); + let entry_ln = lsets.compute(&body, hir_id); + lsets.log_liveness(entry_ln, body.id().hir_id); // check for various error conditions - lsets.visit_body(body); + lsets.visit_body(&body); lsets.warn_about_unused_upvars(entry_ln); - lsets.warn_about_unused_args(body, entry_ln); + lsets.warn_about_unused_args(&body, entry_ln); } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 2eed58d10bb..f2454514e4d 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -16,17 +16,17 @@ pub fn provide(providers: &mut Providers) { } let local_def_id = def_id.expect_local(); - let body = tcx.hir().body(tcx.hir().maybe_body_owned_by(local_def_id)?); + let body = tcx.hir().maybe_body_owned_by(local_def_id)?; let mut local_collector = LocalCollector::default(); - local_collector.visit_body(body); + local_collector.visit_body(&body); let mut capture_collector = CaptureCollector { tcx, locals: &local_collector.locals, upvars: FxIndexMap::default(), }; - capture_collector.visit_body(body); + capture_collector.visit_body(&body); if !capture_collector.upvars.is_empty() { Some(tcx.arena.alloc(capture_collector.upvars)) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index f631ae76de5..698b28c626d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1695,7 +1695,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id) { - visitor.visit_nested_body(body_id); + visitor.visit_nested_body(body_id.id()); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 18d91a5b9a8..9336148fd67 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -907,10 +907,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span.remove_mark(); } let mut expr_finder = FindExprBySpan::new(span, self.tcx); - let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return; }; - let body = self.tcx.hir().body(body_id); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { return; @@ -1369,12 +1368,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body_id) = + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; - let body = self.tcx.hir().body(body_id); let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { @@ -1476,10 +1474,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span.remove_mark(); } let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); - let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; - let body = self.tcx.hir().body(body_id); expr_finder.visit_expr(body.value); let mut maybe_suggest = |suggested_ty, count, suggestions| { // Remapping bound vars here @@ -1805,10 +1802,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } - let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(obligation.cause.body_id)); + let body = self.tcx.hir().body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); - visitor.visit_body(body); + visitor.visit_body(&body); let mut sugg = vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())]; @@ -2348,13 +2345,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ?span, ); - let coroutine_body = coroutine_did - .as_local() - .and_then(|def_id| hir.maybe_body_owned_by(def_id)) - .map(|body_id| hir.body(body_id)); + let coroutine_body = + coroutine_did.as_local().and_then(|def_id| hir.maybe_body_owned_by(def_id)); let mut visitor = AwaitsVisitor::default(); if let Some(body) = coroutine_body { - visitor.visit_body(body); + visitor.visit_body(&body); } debug!(awaits = ?visitor.awaits); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 46953a61296..8101f6cf295 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2451,11 +2451,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) - && let Some(body_id) = - self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); - expr_finder.visit_expr(self.tcx.hir().body(body_id).value); + expr_finder.visit_expr(&body.value); if let Some(hir::Expr { kind: diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index ccc522053a6..686f2f04ad9 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -109,7 +109,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { - let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(self.item)).value; + let body = self.tcx.hir().body_owned_by(self.item).value; struct TaitInBodyFinder<'a, 'tcx> { collector: &'a mut OpaqueTypeCollector<'tcx>, } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7490688e36c..711aef34c27 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2133,7 +2133,9 @@ impl Discriminant { /// Will be `None` in the case of cross-crate reexports, and may be /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option { - self.expr.map(|body| rendered_const(tcx, body)) + self.expr.map(|body| { + rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) + }) } pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String { print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() @@ -2419,7 +2421,7 @@ impl ConstantKind { ConstantKind::TyConst { ref expr } => expr.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - rendered_const(tcx, body) + rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) } } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index aa923cc6117..803650beaf6 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -342,7 +342,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { - rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def)) + rendered_const(cx.tcx, &cx.tcx.hir().body_owned_by(def), def) } else { inline::print_inlined_const(cx.tcx, def) }; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 93229527076..ccd5dadb20a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -284,9 +284,9 @@ pub(crate) fn create_config( } let hir = tcx.hir(); - let body = hir.body(hir.body_owned_by(def_id)); + let body = hir.body_owned_by(def_id); debug!("visiting body for {def_id:?}"); - EmitIgnoredResolutionErrors::new(tcx).visit_body(body); + EmitIgnoredResolutionErrors::new(tcx).visit_body(&body); (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id) }; }), diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 8ee35db56f8..0535246ae10 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -162,9 +162,7 @@ impl<'tcx> SpanMapVisitor<'tcx> { // compiled (because of cfg)! // // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 - let typeck_results = self - .tcx - .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body")); + let typeck_results = self.tcx.typeck_body(hir.body_owned_by(body_id).id()); // Interestingly enough, for method calls, we need the whole expression whereas for static // method/function calls, we need the call expression specifically. if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index f856b4e9f16..7f5c12219b8 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -820,7 +820,10 @@ impl FromWithTcx for Static { Static { type_: stat.type_.into_tcx(tcx), mutable: stat.mutability == ast::Mutability::Mut, - expr: stat.expr.map(|e| rendered_const(tcx, e)).unwrap_or_default(), + expr: stat + .expr + .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) + .unwrap_or_default(), } } } diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index efec9dd716d..ca331f3e756 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -59,8 +59,8 @@ pub(super) fn check<'tcx>( }; let map = cx.tcx.hir(); - let body = map.body(map.body_owned_by(map.enclosing_body_owner(expr.hir_id))); - reference_visitor.visit_body(body); + let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); + reference_visitor.visit_body(&body); if reference_visitor.found_reference { return; diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index 2ce7e714c64..f8e09d517f5 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -79,7 +79,6 @@ impl SingleCallFn { .tcx .hir() .maybe_body_owned_by(fn_def_id) - .map(|body| cx.tcx.hir().body(body)) .map_or(true, |body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs index cc6ff1cf3b4..f98ea59a15d 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -30,8 +30,8 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); - if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id) { - let body = cx.tcx.hir().body(body_id); + if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let body = cx.tcx.hir().body(body.id()); return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 0c4e2c91aec..5e41b3f4914 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -336,7 +336,7 @@ impl UnconditionalRecursion { // We need to use typeck here to infer the actual function being called. && let body_def_id = cx.tcx.hir().enclosing_body_owner(call_expr.hir_id) && let Some(body_owner) = cx.tcx.hir().maybe_body_owned_by(body_def_id) - && let typeck = cx.tcx.typeck_body(body_owner) + && let typeck = cx.tcx.typeck_body(body_owner.id()) && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id) { self.default_impl_for_type.insert(self_def_id, call_def_id); diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 4448c9ae3df..18a31abddd0 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -137,9 +137,9 @@ impl<'tcx> LateLintPass<'tcx> for Author { fn check_item(cx: &LateContext<'_>, hir_id: HirId) { let hir = cx.tcx.hir(); - if let Some(body_id) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { + if let Some(body) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { check_node(cx, hir_id, |v| { - v.expr(&v.bind("expr", hir.body(body_id).value)); + v.expr(&v.bind("expr", body.value)); }); } } diff --git a/tests/ui/inline-const/uninit_local.rs b/tests/ui/inline-const/uninit_local.rs new file mode 100644 index 00000000000..548c053affc --- /dev/null +++ b/tests/ui/inline-const/uninit_local.rs @@ -0,0 +1,6 @@ +fn main() { + let _my_usize = const { + let x: bool; + while x {} //~ ERROR: `x` isn't initialized + }; +} diff --git a/tests/ui/inline-const/uninit_local.stderr b/tests/ui/inline-const/uninit_local.stderr new file mode 100644 index 00000000000..37b78e337e7 --- /dev/null +++ b/tests/ui/inline-const/uninit_local.stderr @@ -0,0 +1,16 @@ +error[E0381]: used binding `x` isn't initialized + --> $DIR/uninit_local.rs:4:15 + | +LL | let x: bool; + | - binding declared here but left uninitialized +LL | while x {} + | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x: bool = false; + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`.