Auto merge of #125711 - oli-obk:const_block_ice2, r=Nadrieril

Make `body_owned_by` return the `Body` instead of just the `BodyId`

fixes #125677

Almost all `body_owned_by` callers immediately called `body`, too, so just return `Body` directly.

This makes the inline-const query feeding more robust, as all calls to `body_owned_by` will now yield a body for inline consts, too.

I have not yet figured out a good way to make `tcx.hir().body()` return an inline-const body, but that can be done as a follow-up
This commit is contained in:
bors 2024-05-30 08:00:11 +00:00
commit d43930dab3
54 changed files with 163 additions and 162 deletions

View File

@ -399,8 +399,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
let hir = self.infcx.tcx.hir(); let hir = self.infcx.tcx.hir();
if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) { if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) {
let expr = hir.body(body_id).value; let expr = body.value;
let place = &self.move_data.move_paths[mpi].place; 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 span = place.as_local().map(|local| self.body.local_decls[local].source_info.span);
let mut finder = ExpressionFinder { 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 // 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. // for the branching codepaths that aren't covered, to point at them.
let map = self.infcx.tcx.hir(); let map = self.infcx.tcx.hir();
let body_id = map.body_owned_by(self.mir_def_id()); let body = map.body_owned_by(self.mir_def_id());
let body = map.body(body_id);
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; 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 mut show_assign_sugg = false;
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment 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 }; let mut visitor = LetVisitor { decl_span, sugg_span: None };
visitor.visit_body(body); visitor.visit_body(&body);
if let Some(span) = visitor.sugg_span { if let Some(span) = visitor.sugg_span {
self.suggest_assign_value(&mut err, moved_place, span); self.suggest_assign_value(&mut err, moved_place, span);
} }

View File

@ -647,8 +647,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let hir_map = self.infcx.tcx.hir(); let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id(); let def_id = self.body.source.def_id();
let Some(local_def_id) = def_id.as_local() else { return }; 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 Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return };
let body = self.infcx.tcx.hir().body(body_id);
let mut v = SuggestIndexOperatorAlternativeVisitor { let mut v = SuggestIndexOperatorAlternativeVisitor {
assign_span: span, assign_span: span,
@ -656,7 +655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty, ty,
suggested: false, suggested: false,
}; };
v.visit_body(body); v.visit_body(&body);
if !v.suggested { if !v.suggested {
err.help(format!( err.help(format!(
"to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API", "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)` // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`
let def_id = self.body.source.def_id(); let def_id = self.body.source.def_id();
if let Some(local_def_id) = def_id.as_local() 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) && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value()
&& let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value()
&& let node = self.infcx.tcx.hir_node(hir_id) && let node = self.infcx.tcx.hir_node(hir_id)
&& let hir::Node::LetStmt(hir::LetStmt { && let hir::Node::LetStmt(hir::LetStmt {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, 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()) if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id())
&& let Block(block, _) = hir_map.body(body_id).value.kind && let Block(block, _) = body.value.kind
{ {
// `span` corresponds to the expression being iterated, find the `for`-loop desugared // `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 // 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, _)) => { Some((false, err_label_span, message, _)) => {
let def_id = self.body.source.def_id(); let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local() 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 { } else {
None None
}; };

View File

@ -1183,8 +1183,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) {
let map = self.infcx.tcx.hir(); let map = self.infcx.tcx.hir();
let body_id = map.body_owned_by(self.mir_def_id()); let body = map.body_owned_by(self.mir_def_id());
let expr = &map.body(body_id).value.peel_blocks(); let expr = &body.value.peel_blocks();
let mut closure_span = None::<rustc_span::Span>; let mut closure_span = None::<rustc_span::Span>;
match expr.kind { match expr.kind {
hir::ExprKind::MethodCall(.., args, _) => { hir::ExprKind::MethodCall(.., args, _) => {

View File

@ -169,7 +169,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> {
self.tcx self.tcx
.hir() .hir()
.maybe_body_owned_by(expr.hir_id.owner.def_id) .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 { if let Some(typeck_results) = typeck_results {

View File

@ -299,7 +299,7 @@ pub trait Visitor<'v>: Sized {
walk_item(self, i) walk_item(self, i)
} }
fn visit_body(&mut self, b: &'v Body<'v>) -> Self::Result { fn visit_body(&mut self, b: &Body<'v>) -> Self::Result {
walk_body(self, b) walk_body(self, b)
} }
@ -578,7 +578,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
V::Result::output() V::Result::output()
} }
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) -> V::Result { pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &Body<'v>) -> V::Result {
walk_list!(visitor, visit_param, body.params); walk_list!(visitor, visit_param, body.params);
visitor.visit_expr(body.value) visitor.visit_expr(body.value)
} }

View File

@ -818,7 +818,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
resolve_block(self, b); resolve_block(self, b);
} }
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { fn visit_body(&mut self, body: &hir::Body<'tcx>) {
let body_id = body.id(); let body_id = body.id();
let owner_id = self.tcx.hir().body_owner_def_id(body_id); let owner_id = self.tcx.hir().body_owner_def_id(body_id);
@ -896,7 +896,7 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
return tcx.region_scope_tree(typeck_root_def_id); 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 { let mut visitor = RegionResolutionVisitor {
tcx, tcx,
scope_tree: ScopeTree::default(), scope_tree: ScopeTree::default(),
@ -907,9 +907,8 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
fixup_scopes: vec![], fixup_scopes: vec![],
}; };
let body = tcx.hir().body(body_id);
visitor.scope_tree.root_body = Some(body.value.hir_id); visitor.scope_tree.root_body = Some(body.value.hir_id);
visitor.visit_body(body); visitor.visit_body(&body);
visitor.scope_tree visitor.scope_tree
} else { } else {
ScopeTree::default() ScopeTree::default()

View File

@ -207,10 +207,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let hir = self.tcx.hir(); let hir = self.tcx.hir();
// First, check that we're actually in the tail of a function. // 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; return;
}; };
let body = hir.body(body_id);
let hir::ExprKind::Block(block, _) = body.value.kind else { let hir::ExprKind::Block(block, _) = body.value.kind else {
return; return;
}; };

View File

@ -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 mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() };
let body = let body = hir.body_owned_by(self.body_id);
hir.body(hir.maybe_body_owned_by(self.body_id).expect("expected item to have body"));
expr_finder.visit_expr(body.value); expr_finder.visit_expr(body.value);
// Replaces all of the variables in the given type with a fresh inference variable. // Replaces all of the variables in the given type with a fresh inference variable.

View File

@ -909,8 +909,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the first place. // the first place.
assert_ne!(encl_item_id.def_id, encl_body_owner_id); 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_owned_by(encl_body_owner_id);
let encl_body = self.tcx.hir().body(encl_body_id);
err.encl_body_span = Some(encl_body.value.span); err.encl_body_span = Some(encl_body.value.span);
err.encl_fn_span = Some(*encl_fn_span); err.encl_fn_span = Some(*encl_fn_span);

View File

@ -544,9 +544,8 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
root_ctxt: &'a TypeckRootCtxt<'tcx>, root_ctxt: &'a TypeckRootCtxt<'tcx>,
body_id: LocalDefId, body_id: LocalDefId,
) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> { ) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> {
let body_id = let body =
root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); 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(); let mut res = UnordMap::default();
struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> { struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> {

View File

@ -1973,8 +1973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
*expr *expr
} else { } else {
let body_def_id = hir.enclosing_body_owner(expr.hir_id); 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_owned_by(body_def_id);
let body = hir.body(body_id);
// Get tail expr of the body // Get tail expr of the body
match body.value.kind { match body.value.kind {

View File

@ -505,9 +505,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::def::Res::Local(recv_id) = path.res && let hir::def::Res::Local(recv_id) = path.res
&& let Some(segment) = path.segments.first() && let Some(segment) = path.segments.first()
{ {
let map = self.infcx.tcx.hir(); let body = self.tcx.hir().body_owned_by(self.body_id);
let body_id = self.tcx.hir().body_owned_by(self.body_id);
let body = map.body(body_id);
if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) {
let mut let_visitor = LetVisitor { let mut let_visitor = LetVisitor {
@ -518,7 +516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
method_name, method_name,
sugg_let: None, sugg_let: None,
}; };
let_visitor.visit_body(body); let_visitor.visit_body(&body);
if let Some(sugg_let) = let_visitor.sugg_let if let Some(sugg_let) = let_visitor.sugg_let
&& let Some(self_ty) = self.node_ty_opt(sugg_let.init_hir_id) && 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, seg1.ident.span,
StashKey::CallAssocMethod, StashKey::CallAssocMethod,
|err| { |err| {
let map = self.infcx.tcx.hir(); let body = self.tcx.hir().body_owned_by(self.body_id);
let body_id = self.tcx.hir().body_owned_by(self.body_id);
let body = map.body(body_id);
struct LetVisitor { struct LetVisitor {
ident_name: Symbol, 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) if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id)
&& let ControlFlow::Break(Some(expr)) = && 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 Some(self_ty) = self.node_ty_opt(expr.hir_id)
{ {
let probe = self.lookup_probe_for_diagnostic( let probe = self.lookup_probe_for_diagnostic(

View File

@ -457,10 +457,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}; };
let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); 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(), 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); local_visitor.visit_expr(expr);
} }
@ -1163,7 +1163,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
/// For closures, we first visit the parameters and then the content, /// For closures, we first visit the parameters and then the content,
/// as we prefer those. /// as we prefer those.
fn visit_body(&mut self, body: &'tcx Body<'tcx>) { fn visit_body(&mut self, body: &Body<'tcx>) {
for param in body.params { for param in body.params {
debug!( debug!(
"param: span {:?}, ty_span {:?}, pat.span {:?}", "param: span {:?}, ty_span {:?}, pat.span {:?}",

View File

@ -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 fn_decl = hir.fn_decl_by_hir_id(owner_id)?;
let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let poly_fn_sig = tcx.fn_sig(id).instantiate_identity();
let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig);
let body = hir.body(body_id);
body.params body.params
.iter() .iter()
.take(if fn_sig.c_variadic { .take(if fn_sig.c_variadic {

View File

@ -578,16 +578,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
walk_stmt(self, ex) walk_stmt(self, ex)
} }
} }
fn visit_body(&mut self, body: &'v hir::Body<'v>) -> Self::Result {
hir::intravisit::walk_body(self, body)
}
} }
self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body_id| { self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body| {
let body = self.tcx.hir().body(body_id);
IfVisitor { err_span: span, found_if: false } IfVisitor { err_span: span, found_if: false }
.visit_body(body) .visit_body(&body)
.is_break() .is_break()
.then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() }) .then(|| TypeErrorAdditionalDiags::AddLetForLetChains { span: span.shrink_to_lo() })
}) })

View File

@ -125,7 +125,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
}); });
} }
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { fn visit_body(&mut self, body: &hir::Body<'tcx>) {
lint_callback!(self, check_body, body); lint_callback!(self, check_body, body);
hir_visit::walk_body(self, body); hir_visit::walk_body(self, body);
lint_callback!(self, check_body_post, body); lint_callback!(self, check_body_post, body);

View File

@ -68,11 +68,11 @@ impl_lint_pass!(NonLocalDefinitions => [NON_LOCAL_DEFINITIONS]);
// instead check_mod is called after every body has been handled. // instead check_mod is called after every body has been handled.
impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
fn check_body(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) { fn check_body(&mut self, _cx: &LateContext<'tcx>, _body: &Body<'tcx>) {
self.body_depth += 1; self.body_depth += 1;
} }
fn check_body_post(&mut self, _cx: &LateContext<'tcx>, _body: &'tcx Body<'tcx>) { fn check_body_post(&mut self, _cx: &LateContext<'tcx>, _body: &Body<'tcx>) {
self.body_depth -= 1; self.body_depth -= 1;
} }

View File

@ -7,8 +7,8 @@ use rustc_session::lint::LintPass;
macro_rules! late_lint_methods { macro_rules! late_lint_methods {
($macro:path, $args:tt) => ( ($macro:path, $args:tt) => (
$macro!($args, [ $macro!($args, [
fn check_body(a: &'tcx rustc_hir::Body<'tcx>); fn check_body(a: &rustc_hir::Body<'tcx>);
fn check_body_post(a: &'tcx rustc_hir::Body<'tcx>); fn check_body_post(a: &rustc_hir::Body<'tcx>);
fn check_crate(); fn check_crate();
fn check_crate_post(); fn check_crate_post();
fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId); fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId);

View File

@ -1677,9 +1677,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
if should_encode_const(tcx.def_kind(def_id)) { if should_encode_const(tcx.def_kind(def_id)) {
let qualifs = tcx.mir_const_qualif(def_id); let qualifs = tcx.mir_const_qualif(def_id);
record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
let body_id = tcx.hir().maybe_body_owned_by(def_id); let body = tcx.hir().maybe_body_owned_by(def_id);
if let Some(body_id) = body_id { if let Some(body) = body {
let const_data = rendered_const(self.tcx, body_id); let const_data = rendered_const(self.tcx, &body, def_id);
record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); 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 /// Whenever possible, prefer to evaluate the constant first and try to
/// use a different method for pretty-printing. Ideally this function /// use a different method for pretty-printing. Ideally this function
/// should only ever be used as a fallback. /// 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 hir = tcx.hir();
let value = &hir.body(body).value; let value = body.value;
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
enum Classification { 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 // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and
// other formatting artifacts. // 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 // 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 // with a repeated element (an `ExprKind::Repeat`) as in such case it
// would not actually need any disambiguation. // would not actually need any disambiguation.
Complex => { 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() "{ _ }".to_owned()
} else { } else {
"_".to_owned() "_".to_owned()

View File

@ -1,3 +1,5 @@
use std::borrow::Cow;
use crate::hir::ModuleItems; use crate::hir::ModuleItems;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate; use crate::query::LocalCrate;
@ -254,13 +256,26 @@ impl<'hir> Map<'hir> {
/// Given a `LocalDefId`, returns the `BodyId` associated with it, /// Given a `LocalDefId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`. /// if the node is a body owner, otherwise returns `None`.
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<BodyId> { pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<Cow<'hir, Body<'hir>>> {
self.tcx.hir_node_by_def_id(id).body_id() 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. /// Given a body owner's id, returns the `BodyId` associated with it.
#[track_caller] #[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(|| { self.maybe_body_owned_by(id).unwrap_or_else(|| {
let hir_id = self.tcx.local_def_id_to_hir_id(id); let hir_id = self.tcx.local_def_id_to_hir_id(id);
span_bug!( span_bug!(

View File

@ -194,8 +194,7 @@ pub fn provide(providers: &mut Providers) {
}; };
providers.fn_arg_names = |tcx, def_id| { providers.fn_arg_names = |tcx, def_id| {
let hir = tcx.hir(); let hir = tcx.hir();
let hir_id = tcx.local_def_id_to_hir_id(def_id); if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() {
if let Some(body_id) = hir.maybe_body_owned_by(def_id) {
tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) tcx.arena.alloc_from_iter(hir.body_param_names(body_id))
} else if let Node::TraitItem(&TraitItem { } else if let Node::TraitItem(&TraitItem {
kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), kind: TraitItemKind::Fn(_, TraitFn::Required(idents)),
@ -204,11 +203,15 @@ pub fn provide(providers: &mut Providers) {
| Node::ForeignItem(&ForeignItem { | Node::ForeignItem(&ForeignItem {
kind: ForeignItemKind::Fn(_, idents, _), kind: ForeignItemKind::Fn(_, idents, _),
.. ..
}) = tcx.hir_node(hir_id) }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id))
{ {
idents idents
} else { } 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; providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls;

View File

@ -452,7 +452,7 @@ fn construct_fn<'tcx>(
assert_eq!(expr.as_usize(), thir.exprs.len() - 1); assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
// Figure out what primary body this item has. // 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 span_with_body = tcx.hir().span_with_body(fn_id);
let return_ty_span = tcx let return_ty_span = tcx
.hir() .hir()
@ -512,9 +512,9 @@ fn construct_fn<'tcx>(
); );
let call_site_scope = 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 = 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 source_info = builder.source_info(span);
let call_site_s = (call_site_scope, source_info); let call_site_s = (call_site_scope, source_info);
unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {

View File

@ -13,10 +13,10 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_hir::Node; use rustc_hir::Node;
use rustc_middle::bug;
use rustc_middle::middle::region; use rustc_middle::middle::region;
use rustc_middle::thir::*; use rustc_middle::thir::*;
use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
use rustc_middle::{bug, span_bug};
use tracing::instrument; use tracing::instrument;
pub(crate) fn thir_body( pub(crate) fn thir_body(
@ -24,22 +24,7 @@ pub(crate) fn thir_body(
owner_def: LocalDefId, owner_def: LocalDefId,
) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> { ) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
let hir = tcx.hir(); let hir = tcx.hir();
let body; let body = hir.body_owned_by(owner_def);
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 mut cx = Cx::new(tcx, owner_def); let mut cx = Cx::new(tcx, owner_def);
if let Some(reported) = cx.typeck_results.tainted_by_errors { if let Some(reported) = cx.typeck_results.tainted_by_errors {
return Err(reported); return Err(reported);
@ -49,7 +34,7 @@ pub(crate) fn thir_body(
let owner_id = tcx.local_def_id_to_hir_id(owner_def); 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) { 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 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(); 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. // The resume argument may be missing, in that case we need to provide it here.

View File

@ -226,7 +226,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
// typeck instead of during ast lowering, like all other bodies so far. // typeck instead of during ast lowering, like all other bodies so far.
for def_id in tcx.hir().body_owners() { for def_id in tcx.hir().body_owners() {
// Incremental performance optimization: only load typeck results for things that actually have inline consts // 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()) set.extend(tcx.typeck(def_id).inline_consts.values())
} }
} }

View File

@ -196,7 +196,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
} }
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { fn visit_body(&mut self, body: &hir::Body<'tcx>) {
let owner = self.tcx.hir().body_owner_def_id(body.id()); let owner = self.tcx.hir().body_owner_def_id(body.id());
let kind = self.tcx.hir().body_const_context(owner); let kind = self.tcx.hir().body_const_context(owner);
self.recurse_into(kind, Some(owner), |this| intravisit::walk_body(this, body)); self.recurse_into(kind, Some(owner), |this| intravisit::walk_body(this, body));

View File

@ -246,7 +246,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_item(self, i) hir_visit::walk_item(self, i)
} }
fn visit_body(&mut self, b: &'v hir::Body<'v>) { fn visit_body(&mut self, b: &hir::Body<'v>) {
self.record("Body", Id::None, b); self.record("Body", Id::None, b);
hir_visit::walk_body(self, b); hir_visit::walk_body(self, b);
} }

View File

@ -158,9 +158,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
} }
let mut maps = IrMaps::new(tcx); let mut maps = IrMaps::new(tcx);
let body_id = tcx.hir().body_owned_by(def_id); let body = tcx.hir().body_owned_by(def_id);
let hir_id = tcx.hir().body_owner(body_id); let hir_id = tcx.hir().body_owner(body.id());
let body = tcx.hir().body(body_id);
if let Some(upvars) = tcx.upvars_mentioned(def_id) { if let Some(upvars) = tcx.upvars_mentioned(def_id) {
for &var_hir_id in upvars.keys() { 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, // gather up the various local variables, significant expressions,
// and so forth: // and so forth:
maps.visit_body(body); maps.visit_body(&body);
// compute liveness // compute liveness
let mut lsets = Liveness::new(&mut maps, def_id); let mut lsets = Liveness::new(&mut maps, def_id);
let entry_ln = lsets.compute(body, hir_id); let entry_ln = lsets.compute(&body, hir_id);
lsets.log_liveness(entry_ln, body_id.hir_id); lsets.log_liveness(entry_ln, body.id().hir_id);
// check for various error conditions // check for various error conditions
lsets.visit_body(body); lsets.visit_body(&body);
lsets.warn_about_unused_upvars(entry_ln); 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) { pub fn provide(providers: &mut Providers) {

View File

@ -16,17 +16,17 @@ pub fn provide(providers: &mut Providers) {
} }
let local_def_id = def_id.expect_local(); 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(); let mut local_collector = LocalCollector::default();
local_collector.visit_body(body); local_collector.visit_body(&body);
let mut capture_collector = CaptureCollector { let mut capture_collector = CaptureCollector {
tcx, tcx,
locals: &local_collector.locals, locals: &local_collector.locals,
upvars: FxIndexMap::default(), upvars: FxIndexMap::default(),
}; };
capture_collector.visit_body(body); capture_collector.visit_body(&body);
if !capture_collector.upvars.is_empty() { if !capture_collector.upvars.is_empty() {
Some(tcx.arena.alloc(capture_collector.upvars)) Some(tcx.arena.alloc(capture_collector.upvars))

View File

@ -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); 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) { 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());
} }
} }

View File

@ -907,10 +907,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span.remove_mark(); span.remove_mark();
} }
let mut expr_finder = FindExprBySpan::new(span, self.tcx); 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; return;
}; };
let body = self.tcx.hir().body(body_id);
expr_finder.visit_expr(body.value); expr_finder.visit_expr(body.value);
let Some(expr) = expr_finder.result else { let Some(expr) = expr_finder.result else {
return; return;
@ -1369,12 +1368,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Issue #104961, we need to add parentheses properly for compound expressions // Issue #104961, we need to add parentheses properly for compound expressions
// for example, `x.starts_with("hi".to_string() + "you")` // for example, `x.starts_with("hi".to_string() + "you")`
// should be `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) self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
else { else {
return false; return false;
}; };
let body = self.tcx.hir().body(body_id);
let mut expr_finder = FindExprBySpan::new(span, self.tcx); let mut expr_finder = FindExprBySpan::new(span, self.tcx);
expr_finder.visit_expr(body.value); expr_finder.visit_expr(body.value);
let Some(expr) = expr_finder.result else { let Some(expr) = expr_finder.result else {
@ -1476,10 +1474,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span.remove_mark(); span.remove_mark();
} }
let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); 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; return false;
}; };
let body = self.tcx.hir().body(body_id);
expr_finder.visit_expr(body.value); expr_finder.visit_expr(body.value);
let mut maybe_suggest = |suggested_ty, count, suggestions| { let mut maybe_suggest = |suggested_ty, count, suggestions| {
// Remapping bound vars here // 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(); let mut visitor = ReturnsVisitor::default();
visitor.visit_body(body); visitor.visit_body(&body);
let mut sugg = let mut sugg =
vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())]; vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())];
@ -2348,13 +2345,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
?span, ?span,
); );
let coroutine_body = coroutine_did let coroutine_body =
.as_local() coroutine_did.as_local().and_then(|def_id| hir.maybe_body_owned_by(def_id));
.and_then(|def_id| hir.maybe_body_owned_by(def_id))
.map(|body_id| hir.body(body_id));
let mut visitor = AwaitsVisitor::default(); let mut visitor = AwaitsVisitor::default();
if let Some(body) = coroutine_body { if let Some(body) = coroutine_body {
visitor.visit_body(body); visitor.visit_body(&body);
} }
debug!(awaits = ?visitor.awaits); debug!(awaits = ?visitor.awaits);
@ -4748,7 +4743,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
} }
} }
fn visit_body(&mut self, body: &'v hir::Body<'v>) { fn visit_body(&mut self, body: &hir::Body<'v>) {
assert!(!self.in_block_tail); assert!(!self.in_block_tail);
self.in_block_tail = true; self.in_block_tail = true;
hir::intravisit::walk_body(self, body); hir::intravisit::walk_body(self, body);

View File

@ -2451,11 +2451,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack())
&& let Some(body_id) = && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
{ {
let mut expr_finder = FindExprBySpan::new(span, self.tcx); 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 { if let Some(hir::Expr {
kind: kind:

View File

@ -109,7 +109,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
#[instrument(level = "trace", skip(self))] #[instrument(level = "trace", skip(self))]
fn collect_taits_declared_in_body(&mut 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> { struct TaitInBodyFinder<'a, 'tcx> {
collector: &'a mut OpaqueTypeCollector<'tcx>, collector: &'a mut OpaqueTypeCollector<'tcx>,
} }

View File

@ -2133,7 +2133,9 @@ impl Discriminant {
/// Will be `None` in the case of cross-crate reexports, and may be /// Will be `None` in the case of cross-crate reexports, and may be
/// simplified /// simplified
pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> { pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option<String> {
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 { pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String {
print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() print_evaluated_const(tcx, self.value, with_underscores, false).unwrap()
@ -2419,7 +2421,7 @@ impl ConstantKind {
ConstantKind::TyConst { ref expr } => expr.to_string(), ConstantKind::TyConst { ref expr } => expr.to_string(),
ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
rendered_const(tcx, body) rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body))
} }
} }
} }

View File

@ -342,7 +342,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
match n.kind() { match n.kind() {
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => {
let s = if let Some(def) = def.as_local() { 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 { } else {
inline::print_inlined_const(cx.tcx, def) inline::print_inlined_const(cx.tcx, def)
}; };

View File

@ -284,9 +284,9 @@ pub(crate) fn create_config(
} }
let hir = tcx.hir(); 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:?}"); 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) (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
}; };
}), }),

View File

@ -162,9 +162,7 @@ impl<'tcx> SpanMapVisitor<'tcx> {
// compiled (because of cfg)! // compiled (because of cfg)!
// //
// See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
let typeck_results = self let typeck_results = self.tcx.typeck_body(hir.body_owned_by(body_id).id());
.tcx
.typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"));
// Interestingly enough, for method calls, we need the whole expression whereas for static // Interestingly enough, for method calls, we need the whole expression whereas for static
// method/function calls, we need the call expression specifically. // 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)) { if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) {

View File

@ -820,7 +820,10 @@ impl FromWithTcx<clean::Static> for Static {
Static { Static {
type_: stat.type_.into_tcx(tcx), type_: stat.type_.into_tcx(tcx),
mutable: stat.mutability == ast::Mutability::Mut, 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(),
} }
} }
} }

View File

@ -614,7 +614,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
// Unneeded. // Unneeded.
} }
fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) { fn visit_body(&mut self, b: &hir::Body<'tcx>) {
let prev = mem::replace(&mut self.inside_body, true); let prev = mem::replace(&mut self.inside_body, true);
walk_body(self, b); walk_body(self, b);
self.inside_body = prev; self.inside_body = prev;

View File

@ -49,7 +49,7 @@ declare_clippy_lint! {
declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);
impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback { impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback {
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
let hir = cx.tcx.hir(); let hir = cx.tcx.hir();
let is_parent_const = matches!( let is_parent_const = matches!(
hir.body_const_context(hir.body_owner_def_id(body.id())), hir.body_const_context(hir.body_owner_def_id(body.id())),

View File

@ -641,7 +641,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
} }
} }
fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) {
if Some(body.id()) == self.current_body { if Some(body.id()) == self.current_body {
for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) { for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
let replacements = pat.replacements; let replacements = pat.replacements;

View File

@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies; type NestedFilter = nested_filter::OnlyBodies;
fn visit_body(&mut self, body: &'tcx Body<'_>) { fn visit_body(&mut self, body: &Body<'tcx>) {
let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body.id())); let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body.id()));
walk_body(self, body); walk_body(self, body);
self.maybe_typeck_results = old_maybe_typeck_results; self.maybe_typeck_results = old_maybe_typeck_results;

View File

@ -186,7 +186,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BodyVisitor<'a, 'tcx> {
} }
impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe { impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe {
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx rustc_hir::Body<'tcx>) { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) {
if is_lint_allowed(cx, MACRO_METAVARS_IN_UNSAFE, body.value.hir_id) { if is_lint_allowed(cx, MACRO_METAVARS_IN_UNSAFE, body.value.hir_id) {
return; return;
} }

View File

@ -59,8 +59,8 @@ pub(super) fn check<'tcx>(
}; };
let map = cx.tcx.hir(); let map = cx.tcx.hir();
let body = map.body(map.body_owned_by(map.enclosing_body_owner(expr.hir_id))); let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id));
reference_visitor.visit_body(body); reference_visitor.visit_body(&body);
if reference_visitor.found_reference { if reference_visitor.found_reference {
return; return;

View File

@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
} }
} }
fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) {
if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| { if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
local_def_id == cx.tcx.hir().body_owner_def_id(body.id()) local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
}) { }) {

View File

@ -221,7 +221,7 @@ pub struct OnlyUsedInRecursion {
} }
impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
if body.value.span.from_expansion() { if body.value.span.from_expansion() {
return; return;
} }
@ -350,7 +350,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
} }
} }
fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
if self.entered_body == Some(body.value.hir_id) { if self.entered_body == Some(body.value.hir_id) {
self.entered_body = None; self.entered_body = None;
self.params.flag_for_linting(); self.params.flag_for_linting();

View File

@ -868,11 +868,11 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
self.arithmetic_context.expr_post(e.hir_id); self.arithmetic_context.expr_post(e.hir_id);
} }
fn check_body(&mut self, cx: &LateContext<'tcx>, b: &'tcx Body<'_>) { fn check_body(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) {
self.arithmetic_context.enter_body(cx, b); self.arithmetic_context.enter_body(cx, b);
} }
fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &'tcx Body<'_>) { fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) {
self.arithmetic_context.body_post(cx, b); self.arithmetic_context.body_post(cx, b);
} }
} }

View File

@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
} }
} }
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
let hir = cx.tcx.hir(); let hir = cx.tcx.hir();
let mut parents = hir.parent_iter(body.value.hir_id); let mut parents = hir.parent_iter(body.value.hir_id);
let (item_id, sig, is_trait_item) = match parents.next() { let (item_id, sig, is_trait_item) = match parents.next() {
@ -525,7 +525,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
}) })
} }
fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Option<&'tcx Body<'_>>) { fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Option<&Body<'tcx>>) {
if let FnRetTy::Return(ty) = sig.decl.output if let FnRetTy::Return(ty) = sig.decl.output
&& let Some((out, Mutability::Mut, _)) = get_ref_lm(ty) && let Some((out, Mutability::Mut, _)) = get_ref_lm(ty)
{ {
@ -559,7 +559,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
} }
#[expect(clippy::too_many_lines)] #[expect(clippy::too_many_lines)]
fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: &[PtrArg<'tcx>]) -> Vec<PtrArgResult> { fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[PtrArg<'tcx>]) -> Vec<PtrArgResult> {
struct V<'cx, 'tcx> { struct V<'cx, 'tcx> {
cx: &'cx LateContext<'tcx>, cx: &'cx LateContext<'tcx>,
/// Map from a local id to which argument it came from (index into `Self::args` and /// Map from a local id to which argument it came from (index into `Self::args` and

View File

@ -370,11 +370,11 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
} }
} }
fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) { fn check_body(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) {
self.try_block_depth_stack.push(0); self.try_block_depth_stack.push(0);
} }
fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) { fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) {
self.try_block_depth_stack.pop(); self.try_block_depth_stack.pop();
} }

View File

@ -79,7 +79,6 @@ impl SingleCallFn {
.tcx .tcx
.hir() .hir()
.maybe_body_owned_by(fn_def_id) .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)) .map_or(true, |body| is_in_test_function(cx.tcx, body.value.hir_id))
|| match cx.tcx.hir_node(fn_hir_id) { || match cx.tcx.hir_node(fn_hir_id) {
Node::Item(item) => is_from_proc_macro(cx, item), Node::Item(item) => is_from_proc_macro(cx, item),

View File

@ -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 { fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); 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) { if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) {
let body = cx.tcx.hir().body(body_id); let body = cx.tcx.hir().body(body.id());
return body.value.peel_blocks().hir_id == expr_hir_id; return body.value.peel_blocks().hir_id == expr_hir_id;
} }
false false

View File

@ -336,7 +336,7 @@ impl UnconditionalRecursion {
// We need to use typeck here to infer the actual function being called. // 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 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 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) && 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); self.default_impl_for_type.insert(self_def_id, call_def_id);

View File

@ -137,9 +137,9 @@ impl<'tcx> LateLintPass<'tcx> for Author {
fn check_item(cx: &LateContext<'_>, hir_id: HirId) { fn check_item(cx: &LateContext<'_>, hir_id: HirId) {
let hir = cx.tcx.hir(); 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| { check_node(cx, hir_id, |v| {
v.expr(&v.bind("expr", hir.body(body_id).value)); v.expr(&v.bind("expr", body.value));
}); });
} }
} }

View File

@ -0,0 +1,6 @@
fn main() {
let _my_usize = const {
let x: bool;
while x {} //~ ERROR: `x` isn't initialized
};
}

View File

@ -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`.