Make body_owned_by return the body directly.

Almost all callers want this anyway, and now we can use it to also return fed bodies
This commit is contained in:
Oli Scherer 2024-05-29 10:03:40 +00:00
parent ceb45d5519
commit a34c26e7ec
38 changed files with 136 additions and 131 deletions

View File

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

View File

@ -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
};

View File

@ -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::<rustc_span::Span>;
match expr.kind {
hir::ExprKind::MethodCall(.., args, _) => {

View File

@ -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 {

View File

@ -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()

View File

@ -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;
};

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

View File

@ -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);

View File

@ -544,9 +544,8 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
root_ctxt: &'a TypeckRootCtxt<'tcx>,
body_id: LocalDefId,
) -> 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");
let body = root_ctxt.tcx.hir().body(body_id);
let mut res = UnordMap::default();
struct UnsafeInferVarsVisitor<'a, 'tcx, 'r> {

View File

@ -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 {

View File

@ -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(

View File

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

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 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 {

View File

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

View File

@ -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()

View File

@ -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<BodyId> {
self.tcx.hir_node_by_def_id(id).body_id()
pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<Cow<'hir, Body<'hir>>> {
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!(

View File

@ -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;

View File

@ -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| {

View File

@ -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<Thir<'_>>, 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.

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.
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())
}
}

View File

@ -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) {

View File

@ -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))

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

View File

@ -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:

View File

@ -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>,
}

View File

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

View File

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

View File

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

View File

@ -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)) {

View File

@ -820,7 +820,10 @@ impl FromWithTcx<clean::Static> 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(),
}
}
}

View File

@ -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;

View File

@ -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),

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 {
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

View File

@ -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);

View File

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

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