Auto merge of #122555 - GuillaumeGomez:rollup-tr6wu54, r=GuillaumeGomez

Rollup of 6 pull requests

Successful merges:

 - #114651 (rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests)
 - #122468 (Cleanup `MirBorrowckCtxt::prefixes`)
 - #122496 (Greatly reduce GCC build logs)
 - #122512 (Cursor.rs documentation fix)
 - #122513 (hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id`)
 - #122530 (less symbol interner locks)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-03-15 16:39:42 +00:00
commit 72d78970ec
50 changed files with 248 additions and 303 deletions

View file

@ -39,7 +39,7 @@ use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt};
use crate::{
borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
InitializationRequiringAction, MirBorrowckCtxt, WriteKind,
};
use super::{
@ -114,7 +114,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.buffer_error(err);
} else {
if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) {
if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
if used_place.is_prefix_of(*reported_place) {
debug!(
"report_use_of_moved_or_uninitialized place: error suppressed mois={:?}",
move_out_indices
@ -422,8 +422,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let node =
self.infcx.tcx.hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let node = self.infcx.tcx.hir_node_by_def_id(def_id)
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
@ -1995,21 +1994,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
kind: Option<WriteKind>,
) {
let drop_span = place_span.1;
let root_place =
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
let borrowed_local = borrow.borrowed_place.local;
let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.var_or_use_path_span();
assert!(root_place.projection.is_empty());
let proper_span = self.body.local_decls[root_place.local].source_info.span;
let proper_span = self.body.local_decls[borrowed_local].source_info.span;
let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection);
if self.access_place_error_reported.contains(&(
Place { local: root_place.local, projection: root_place_projection },
borrow_span,
)) {
if self.access_place_error_reported.contains(&(Place::from(borrowed_local), borrow_span)) {
debug!(
"suppressing access_place error when borrow doesn't live long enough for {:?}",
borrow_span
@ -2017,12 +2009,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return;
}
self.access_place_error_reported.insert((
Place { local: root_place.local, projection: root_place_projection },
borrow_span,
));
self.access_place_error_reported.insert((Place::from(borrowed_local), borrow_span));
let borrowed_local = borrow.borrowed_place.local;
if self.body.local_decls[borrowed_local].is_ref_to_thread_local() {
let err =
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
@ -2544,9 +2532,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
(format!("{local_kind}`{place_desc}`"), format!("`{place_desc}` is borrowed here"))
} else {
let root_place =
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
let local = root_place.local;
let local = borrow.borrowed_place.local;
match self.body.local_kind(local) {
LocalKind::Arg => (
"function parameter".to_string(),

View file

@ -672,11 +672,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
(
true,
td.as_local().and_then(|tld| match self.infcx.tcx.opt_hir_node_by_def_id(tld) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, items),
..
})) => {
td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => {
let mut f_in_trait_opt = None;
for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
let hi = fi.hir_id();
@ -1475,11 +1472,9 @@ fn get_mut_span_in_struct_field<'tcx>(
if let ty::Ref(_, ty, _) = ty.kind()
&& let ty::Adt(def, _) = ty.kind()
&& let field = def.all_fields().nth(field.index())?
// Use the HIR types to construct the diagnostic message.
&& let node = tcx.opt_hir_node_by_def_id(field.did.as_local()?)?
// Now we're dealing with the actual struct that we're going to suggest a change to,
// we can expect a field that is an immutable reference to a type.
&& let hir::Node::Field(field) = node
&& let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.as_local()?)
&& let hir::TyKind::Ref(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind
{
return Some(lt.ident.span.between(ty.span));

View file

@ -1,7 +1,4 @@
//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] "
//!
//! From the NLL RFC:
//! "Shallow prefixes are found by stripping away fields, but stop at
//! any dereference. So: writing a path like `a` is illegal if `a.b`
//! is borrowed. But: writing `a` is legal if `*a` is borrowed,
@ -9,9 +6,7 @@
use super::MirBorrowckCtxt;
use rustc_hir as hir;
use rustc_middle::mir::{Body, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::mir::{PlaceRef, ProjectionElem};
pub trait IsPrefixOf<'tcx> {
fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
}
}
pub(super) struct Prefixes<'cx, 'tcx> {
body: &'cx Body<'tcx>,
tcx: TyCtxt<'tcx>,
pub(super) struct Prefixes<'tcx> {
kind: PrefixSet,
next: Option<PlaceRef<'tcx>>,
}
@ -39,24 +32,18 @@ pub(super) enum PrefixSet {
All,
/// Stops at any dereference.
Shallow,
/// Stops at the deref of a shared reference.
Supporting,
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Returns an iterator over the prefixes of `place`
/// (inclusive) from longest to smallest, potentially
/// terminating the iteration early based on `kind`.
pub(super) fn prefixes(
&self,
place_ref: PlaceRef<'tcx>,
kind: PrefixSet,
) -> Prefixes<'cx, 'tcx> {
Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx }
pub(super) fn prefixes(&self, place_ref: PlaceRef<'tcx>, kind: PrefixSet) -> Prefixes<'tcx> {
Prefixes { next: Some(place_ref), kind }
}
}
impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
impl<'tcx> Iterator for Prefixes<'tcx> {
type Item = PlaceRef<'tcx>;
fn next(&mut self) -> Option<Self::Item> {
let mut cursor = self.next?;
@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
panic!("Subtype projection is not allowed before borrow check")
}
ProjectionElem::Deref => {
// (handled below)
match self.kind {
PrefixSet::Shallow => {
// Shallow prefixes are found by stripping away
// fields, but stop at *any* dereference.
// So we can just stop the traversal now.
self.next = None;
return Some(cursor);
}
PrefixSet::All => {
// All prefixes: just blindly enqueue the base
// of the projection.
self.next = Some(cursor_base);
return Some(cursor);
}
}
}
}
assert_eq!(elem, ProjectionElem::Deref);
match self.kind {
PrefixSet::Shallow => {
// Shallow prefixes are found by stripping away
// fields, but stop at *any* dereference.
// So we can just stop the traversal now.
self.next = None;
return Some(cursor);
}
PrefixSet::All => {
// All prefixes: just blindly enqueue the base
// of the projection.
self.next = Some(cursor_base);
return Some(cursor);
}
PrefixSet::Supporting => {
// Fall through!
}
}
assert_eq!(self.kind, PrefixSet::Supporting);
// Supporting prefixes: strip away fields and
// derefs, except we stop at the deref of a shared
// reference.
let ty = cursor_base.ty(self.body, self.tcx).ty;
match ty.kind() {
ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => {
// don't continue traversing over derefs of raw pointers or shared
// borrows.
self.next = None;
return Some(cursor);
}
ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => {
self.next = Some(cursor_base);
return Some(cursor);
}
ty::Adt(..) if ty.is_box() => {
self.next = Some(cursor_base);
return Some(cursor);
}
_ => panic!("unknown type fed to Projection Deref."),
}
}
}
}

View file

@ -42,8 +42,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
generics.params.is_empty().not().then_some(generics.span)
}
@ -57,8 +56,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
Some(generics.where_clause_span)
}
@ -79,8 +77,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
if !def_id.is_local() {
return None;
}
let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
match tcx.hir_node(hir_id) {
match tcx.hir_node_by_def_id(def_id.expect_local()) {
Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. }) => {
Some(fn_sig.decl.output.span())
}

View file

@ -130,7 +130,7 @@ fn get_owner_return_paths(
) -> Option<(LocalDefId, ReturnsVisitor<'_>)> {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let parent_id = tcx.hir().get_parent_item(hir_id).def_id;
tcx.opt_hir_node_by_def_id(parent_id).and_then(|node| node.body_id()).map(|body_id| {
tcx.hir_node_by_def_id(parent_id).body_id().map(|body_id| {
let body = tcx.hir().body(body_id);
let mut visitor = ReturnsVisitor::default();
visitor.visit_body(body);

View file

@ -1969,13 +1969,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// Match the existing behavior.
if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
let pred = self.normalize(span, None, pred);
let hir_node = tcx.opt_hir_node_by_def_id(self.body_def_id);
// only use the span of the predicate clause (#90869)
if let Some(hir::Generics { predicates, .. }) =
hir_node.and_then(|node| node.generics())
{
let hir_node = tcx.hir_node_by_def_id(self.body_def_id);
if let Some(hir::Generics { predicates, .. }) = hir_node.generics() {
span = predicates
.iter()
// There seems to be no better way to find out which predicate we are in

View file

@ -609,10 +609,8 @@ pub(super) fn implied_predicates_with_filter(
return tcx.super_predicates_of(trait_def_id);
};
let trait_hir_id = tcx.local_def_id_to_hir_id(trait_def_id);
let Node::Item(item) = tcx.hir_node(trait_hir_id) else {
bug!("trait_node_id {} is not an item", trait_hir_id);
let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else {
bug!("trait_def_id {trait_def_id:?} is not an item");
};
let (generics, bounds) = match item.kind {

View file

@ -371,11 +371,10 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
return mir_opaque_ty.ty;
}
let scope = tcx.local_def_id_to_hir_id(owner_def_id);
debug!(?scope);
debug!(?owner_def_id);
let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
match tcx.hir_node(scope) {
match tcx.hir_node_by_def_id(owner_def_id) {
Node::Item(it) => intravisit::walk_item(&mut locator, it),
Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it),
Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),

View file

@ -234,11 +234,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
// Next, make sure that we have no type expectation.
let Some(ret) = self
.tcx
.opt_hir_node_by_def_id(self.body_id)
.and_then(|owner| owner.fn_decl())
.map(|decl| decl.output.span())
let Some(ret) =
self.tcx.hir_node_by_def_id(self.body_id).fn_decl().map(|decl| decl.output.span())
else {
return;
};

View file

@ -890,21 +890,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(..),
span: encl_fn_span,
..
}))
| Some(hir::Node::TraitItem(hir::TraitItem {
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(..), span: encl_fn_span, ..
})
| hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
span: encl_fn_span,
..
}))
| Some(hir::Node::ImplItem(hir::ImplItem {
})
| hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(..),
span: encl_fn_span,
..
})) = self.tcx.opt_hir_node_by_def_id(encl_item_id.def_id)
}) = self.tcx.hir_node_by_def_id(encl_item_id.def_id)
{
// We are inside a function body, so reporting "return statement
// outside of function body" needs an explanation.

View file

@ -2172,16 +2172,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Try to find earlier invocations of this closure to find if the type mismatch
// is because of inference. If we find one, point at them.
let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] };
let node = self
.tcx
.opt_local_def_id_to_hir_id(
self.tcx.hir().get_parent_item(call_expr.hir_id).def_id,
)
.map(|hir_id| self.tcx.hir_node(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),
Some(hir::Node::ImplItem(item)) => call_finder.visit_impl_item(item),
let parent_def_id = self.tcx.hir().get_parent_item(call_expr.hir_id).def_id;
match self.tcx.hir_node_by_def_id(parent_def_id) {
hir::Node::Item(item) => call_finder.visit_item(item),
hir::Node::TraitItem(item) => call_finder.visit_trait_item(item),
hir::Node::ImplItem(item) => call_finder.visit_impl_item(item),
_ => {}
}
let typeck = self.typeck_results.borrow();

View file

@ -2126,8 +2126,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let TypeError::FixedArraySize(sz) = terr else {
return None;
};
let tykind = match self.tcx.opt_hir_node_by_def_id(trace.cause.body_id) {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => {
let body = hir.body(*body_id);
struct LetVisitor {
span: Span,
@ -2156,7 +2156,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
LetVisitor { span }.visit_body(body).break_value()
}
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. })) => {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }) => {
Some(&ty.peel_refs().kind)
}
_ => None,
@ -2527,15 +2527,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
.map(|p| p.name)
.collect::<Vec<_>>();
if let Some(hir_id) = self.tcx.opt_local_def_id_to_hir_id(lifetime_scope) {
// consider late-bound lifetimes ...
used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map(|p| {
match p {
ty::BoundVariableKind::Region(lt) => lt.get_name(),
_ => None,
}
}))
}
let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope);
// consider late-bound lifetimes ...
used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map(
|p| match p {
ty::BoundVariableKind::Region(lt) => lt.get_name(),
_ => None,
},
));
(b'a'..=b'z')
.map(|c| format!("'{}", c as char))
.find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate))

View file

@ -459,7 +459,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
if let Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), ..
}) = tcx.opt_hir_node_by_def_id(impl_did)?
}) = tcx.hir_node_by_def_id(impl_did)
&& trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
// type in the `UnifyReceiver` context, but for now, use

View file

@ -804,23 +804,22 @@ fn foo(&self) -> Self::T { String::new() }
) -> bool {
let tcx = self.tcx;
let Some(hir_id) = body_owner_def_id.as_local() else {
return false;
};
let Some(hir_id) = tcx.opt_local_def_id_to_hir_id(hir_id) else {
let Some(def_id) = body_owner_def_id.as_local() else {
return false;
};
// When `body_owner` is an `impl` or `trait` item, look in its associated types for
// `expected` and point at it.
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let parent_id = tcx.hir().get_parent_item(hir_id);
let item = tcx.opt_hir_node_by_def_id(parent_id.def_id);
let item = tcx.hir_node_by_def_id(parent_id.def_id);
debug!("expected_projection parent item {:?}", item);
let param_env = tcx.param_env(body_owner_def_id);
match item {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. })) => {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. }) => {
// FIXME: account for `#![feature(specialization)]`
for item in &items[..] {
match item.kind {
@ -845,10 +844,10 @@ fn foo(&self) -> Self::T { String::new() }
}
}
}
Some(hir::Node::Item(hir::Item {
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { items, .. }),
..
})) => {
}) => {
for item in &items[..] {
if let hir::AssocItemKind::Type = item.kind {
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();

View file

@ -1339,8 +1339,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
is_doc_hidden: false,
};
let attr_iter = tcx
.opt_local_def_id_to_hir_id(def_id)
.map_or(Default::default(), |hir_id| tcx.hir().attrs(hir_id))
.hir()
.attrs(tcx.local_def_id_to_hir_id(def_id))
.iter()
.filter(|attr| analyze_attr(attr, &mut state));

View file

@ -158,12 +158,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.hir_owner_nodes(owner_id).node()
}
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
Some(self.hir_node_by_def_id(id))
}
/// Retrieves the `hir::Node` corresponding to `id`.
pub fn hir_node(self, id: HirId) -> Node<'tcx> {
self.hir_owner_nodes(id.owner).nodes[id.local_id].node
@ -239,8 +233,7 @@ impl<'hir> Map<'hir> {
}
pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
id.as_local()
.and_then(|id| Some(self.tcx.hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?)))
id.as_local().map(|id| self.tcx.hir_node_by_def_id(id))
}
pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
@ -304,7 +297,7 @@ 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> {
let node = self.tcx.opt_hir_node_by_def_id(id)?;
let node = self.tcx.hir_node_by_def_id(id);
let (_, body_id) = associated_body(node)?;
Some(body_id)
}

View file

@ -1265,11 +1265,9 @@ impl<'tcx> TyCtxt<'tcx> {
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
};
let is_impl_item = match self.opt_hir_node_by_def_id(suitable_region_binding_scope) {
Some(Node::Item(..) | Node::TraitItem(..)) => false,
Some(Node::ImplItem(..)) => {
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
}
let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
Node::Item(..) | Node::TraitItem(..) => false,
Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
_ => false,
};
@ -2355,10 +2353,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.intrinsic_raw(def_id)
}
pub fn opt_local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> Option<HirId> {
Some(self.local_def_id_to_hir_id(local_def_id))
}
pub fn next_trait_solver_globally(self) -> bool {
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
}

View file

@ -33,15 +33,13 @@ use crate::errors::{
// may need to be marked as live.
fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
matches!(
tcx.opt_hir_node_by_def_id(def_id),
Some(
Node::Item(..)
| Node::ImplItem(..)
| Node::ForeignItem(..)
| Node::TraitItem(..)
| Node::Variant(..)
| Node::AnonConst(..)
)
tcx.hir_node_by_def_id(def_id),
Node::Item(..)
| Node::ImplItem(..)
| Node::ForeignItem(..)
| Node::TraitItem(..)
| Node::Variant(..)
| Node::AnonConst(..)
)
}
@ -316,33 +314,31 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
// tuple struct constructor function
let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
if let Some(node) = self.tcx.opt_hir_node_by_def_id(id) {
// When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement
// by declaring fn calls, statics, ... within said items as live, as well as
// the item itself, although technically this is not the case.
//
// This means that the lint for said items will never be fired.
//
// This doesn't make any difference for the item declared with `#[allow]`, as
// the lint firing will be a nop, as it will be silenced by the `#[allow]` of
// the item.
//
// However, for `#[expect]`, the presence or absence of the lint is relevant,
// so we don't add it to the list of live symbols when it comes from a
// `#[expect]`. This means that we will correctly report an item as live or not
// for the `#[expect]` case.
//
// Note that an item can and will be duplicated on the worklist with different
// `ComesFromAllowExpect`, particularly if it was added from the
// `effective_visibilities` query or from the `#[allow]`/`#[expect]` checks,
// this "duplication" is essential as otherwise a function with `#[expect]`
// called from a `pub fn` may be falsely reported as not live, falsely
// triggering the `unfulfilled_lint_expectations` lint.
if comes_from_allow_expect != ComesFromAllowExpect::Yes {
self.live_symbols.insert(id);
}
self.visit_node(node);
// When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement
// by declaring fn calls, statics, ... within said items as live, as well as
// the item itself, although technically this is not the case.
//
// This means that the lint for said items will never be fired.
//
// This doesn't make any difference for the item declared with `#[allow]`, as
// the lint firing will be a nop, as it will be silenced by the `#[allow]` of
// the item.
//
// However, for `#[expect]`, the presence or absence of the lint is relevant,
// so we don't add it to the list of live symbols when it comes from a
// `#[expect]`. This means that we will correctly report an item as live or not
// for the `#[expect]` case.
//
// Note that an item can and will be duplicated on the worklist with different
// `ComesFromAllowExpect`, particularly if it was added from the
// `effective_visibilities` query or from the `#[allow]`/`#[expect]` checks,
// this "duplication" is essential as otherwise a function with `#[expect]`
// called from a `pub fn` may be falsely reported as not live, falsely
// triggering the `unfulfilled_lint_expectations` lint.
if comes_from_allow_expect != ComesFromAllowExpect::Yes {
self.live_symbols.insert(id);
}
self.visit_node(self.tcx.hir_node_by_def_id(id));
}
}
@ -739,8 +735,8 @@ fn check_item<'tcx>(
for local_def_id in local_def_ids {
// check the function may construct Self
let mut may_construct_self = true;
if let Some(hir_id) = tcx.opt_local_def_id_to_hir_id(local_def_id)
&& let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id)
if let Some(fn_sig) =
tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id))
{
may_construct_self =
matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None);

View file

@ -127,7 +127,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
{
// non-local main imports are handled below
if let Some(def_id) = def_id.as_local()
&& matches!(tcx.opt_hir_node_by_def_id(def_id), Some(Node::ForeignItem(_)))
&& matches!(tcx.hir_node_by_def_id(def_id), Node::ForeignItem(_))
{
tcx.dcx().emit_err(ExternMain { span: tcx.def_span(def_id) });
return None;

View file

@ -116,26 +116,25 @@ impl<'tcx> ReachableContext<'tcx> {
return false;
};
match self.tcx.opt_hir_node_by_def_id(def_id) {
Some(Node::Item(item)) => match item.kind {
match self.tcx.hir_node_by_def_id(def_id) {
Node::Item(item) => match item.kind {
hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()),
_ => false,
},
Some(Node::TraitItem(trait_method)) => match trait_method.kind {
Node::TraitItem(trait_method) => match trait_method.kind {
hir::TraitItemKind::Const(_, ref default) => default.is_some(),
hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => true,
hir::TraitItemKind::Fn(_, hir::TraitFn::Required(_))
| hir::TraitItemKind::Type(..) => false,
},
Some(Node::ImplItem(impl_item)) => match impl_item.kind {
Node::ImplItem(impl_item) => match impl_item.kind {
hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Fn(..) => {
item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id())
}
hir::ImplItemKind::Type(_) => false,
},
Some(_) => false,
None => false, // This will happen for default methods.
_ => false,
}
}
@ -147,9 +146,7 @@ impl<'tcx> ReachableContext<'tcx> {
continue;
}
if let Some(ref item) = self.tcx.opt_hir_node_by_def_id(search_item) {
self.propagate_node(item, search_item);
}
self.propagate_node(&self.tcx.hir_node_by_def_id(search_item), search_item);
}
}

View file

@ -167,12 +167,13 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
///
/// Note: remove the trailing newline where appropriate
pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
let s = frag.doc.as_str();
let mut iter = s.lines();
if s.is_empty() {
if frag.doc == kw::Empty {
out.push('\n');
return;
}
let s = frag.doc.as_str();
let mut iter = s.lines();
while let Some(line) = iter.next() {
if line.chars().any(|c| !c.is_whitespace()) {
assert!(line.len() >= frag.indent);

View file

@ -91,7 +91,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// Used to set on_unimplemented's `ItemContext`
/// to be the enclosing (async) block/function/closure
fn describe_enclosure(&self, def_id: LocalDefId) -> Option<&'static str> {
match self.tcx.opt_hir_node_by_def_id(def_id)? {
match self.tcx.hir_node_by_def_id(def_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }) => Some("a function"),
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) => {
Some("a trait method")

View file

@ -261,7 +261,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
// don't suggest `T: Sized + ?Sized`.
while let Some(node) = self.tcx.opt_hir_node_by_def_id(body_id) {
loop {
let node = self.tcx.hir_node_by_def_id(body_id);
match node {
hir::Node::Item(hir::Item {
ident,
@ -1725,8 +1726,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
let hir = self.tcx.hir();
let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node
let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = node
&& let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind
&& sig.decl.output.span().overlaps(span)
&& blk.expr.is_none()
@ -1760,8 +1761,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) =
self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id)
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. }) =
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
else {
return None;
};
@ -1853,10 +1854,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
let hir = self.tcx.hir();
let node = self.tcx.opt_hir_node_by_def_id(obligation.cause.body_id);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) =
node
{
let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) = node {
let body = hir.body(*body_id);
// Point at all the `return`s in the function as they have failed trait bounds.
let mut visitor = ReturnsVisitor::default();
@ -4490,7 +4489,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
return;
};
let Some(hir::Node::TraitItem(item)) = self.tcx.opt_hir_node_by_def_id(fn_def_id) else {
let hir::Node::TraitItem(item) = self.tcx.hir_node_by_def_id(fn_def_id) else {
return;
};

View file

@ -2497,11 +2497,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.code(E0790);
if let Some(local_def_id) = data.trait_ref.def_id.as_local()
&& let Some(hir::Node::Item(hir::Item {
&& let hir::Node::Item(hir::Item {
ident: trait_name,
kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs),
..
})) = self.tcx.opt_hir_node_by_def_id(local_def_id)
}) = self.tcx.hir_node_by_def_id(local_def_id)
&& let Some(method_ref) = trait_item_refs
.iter()
.find(|item_ref| item_ref.ident == *assoc_item_name)

View file

@ -325,11 +325,7 @@ fn associated_type_for_impl_trait_in_impl(
) -> LocalDefId {
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
let decl = tcx
.opt_hir_node_by_def_id(impl_fn_def_id)
.expect("expected item")
.fn_decl()
.expect("expected decl");
let decl = tcx.hir_node_by_def_id(impl_fn_def_id).fn_decl().expect("expected decl");
let span = match decl.output {
hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id),
hir::FnRetTy::Return(ty) => ty.span,

View file

@ -51,6 +51,8 @@ use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
/// // We might want to use a BufReader here for efficiency, but let's
/// // keep this example focused.
/// let mut file = File::create("foo.txt")?;
/// // First, we need to allocate 10 bytes to be able to write into.
/// file.set_len(10)?;
///
/// write_ten_bytes_at_end(&mut file)?;
/// # Ok(())

View file

@ -1,9 +1,11 @@
#!/bin/sh
#!/usr/bin/env bash
set -ex
cd $1
source shared.sh
# Setting up folders for GCC
git clone https://github.com/antoyo/gcc gcc-src
cd gcc-src
@ -14,15 +16,17 @@ mkdir ../gcc-build ../gcc-install
cd ../gcc-build
# Building GCC.
../gcc-src/configure \
hide_output \
../gcc-src/configure \
--enable-host-shared \
--enable-languages=jit \
--enable-checking=release \
--disable-bootstrap \
--disable-multilib \
--prefix=$(pwd)/../gcc-install
make
make install
--prefix=$(pwd)/../gcc-install \
hide_output make -j$(nproc)
hide_output make install
rm -rf ../gcc-src
ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so

View file

@ -59,8 +59,9 @@ ENV RUST_CONFIGURE_ARGS \
COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
RUN sh /scripts/build-gccjit.sh /scripts
RUN /scripts/build-gccjit.sh /scripts
ENV SCRIPT /tmp/script.sh

View file

@ -58,8 +58,9 @@ ENV RUST_CONFIGURE_ARGS \
COPY host-x86_64/x86_64-gnu-llvm-16/script.sh /tmp/
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
RUN sh /scripts/build-gccjit.sh /scripts
RUN /scripts/build-gccjit.sh /scripts
ENV SCRIPT /tmp/script.sh

View file

@ -95,9 +95,10 @@ ENV RUST_CONFIGURE_ARGS \
ENV HOST_TARGET x86_64-unknown-linux-gnu
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
RUN sh /scripts/build-gccjit.sh /scripts
RUN /scripts/build-gccjit.sh /scripts
ENV SCRIPT /tmp/checktools.sh ../x.py && \
NODE_PATH=`npm root -g` python3 ../x.py test tests/rustdoc-gui --stage 2 \

View file

@ -427,3 +427,32 @@ This flag is **deprecated** and **has no effect**.
Rustdoc only supports Rust source code and Markdown input formats. If the
file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
Otherwise, it assumes that the input file is Rust.
## `--test-builder`: `rustc`-like program to build tests
Using this flag looks like this:
```bash
$ rustdoc --test-builder /path/to/rustc src/lib.rs
```
Rustdoc will use the provided program to compile tests instead of the default `rustc` program from
the sysroot.
## `--test-builder-wrapper`: wrap calls to the test builder
Using this flag looks like this:
```bash
$ rustdoc --test-builder-wrapper /path/to/rustc-wrapper src/lib.rs
$ rustdoc \
--test-builder-wrapper rustc-wrapper1 \
--test-builder-wrapper rustc-wrapper2 \
--test-builder rustc \
src/lib.rs
```
Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper program.
The first argument to the program will be the test builder program.
This flag can be passed multiple times to nest wrappers.

View file

@ -149,8 +149,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
fn is_glob_import(tcx: TyCtxt<'_>, import_id: LocalDefId) -> bool {
if let Some(node) = tcx.opt_hir_node_by_def_id(import_id)
&& let hir::Node::Item(item) = node
if let hir::Node::Item(item) = tcx.hir_node_by_def_id(import_id)
&& let hir::ItemKind::Use(_, use_kind) = item.kind
{
use_kind == hir::UseKind::Glob
@ -1612,8 +1611,7 @@ fn first_non_private<'tcx>(
'reexps: for reexp in child.reexport_chain.iter() {
if let Some(use_def_id) = reexp.id()
&& let Some(local_use_def_id) = use_def_id.as_local()
&& let Some(hir::Node::Item(item)) =
cx.tcx.opt_hir_node_by_def_id(local_use_def_id)
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_use_def_id)
&& !item.ident.name.is_empty()
&& let hir::ItemKind::Use(path, _) = item.kind
{

View file

@ -664,9 +664,10 @@ pub(crate) fn inherits_doc_hidden(
def_id = id;
if tcx.is_doc_hidden(def_id.to_def_id()) {
return true;
} else if let Some(node) = tcx.opt_hir_node_by_def_id(def_id)
&& matches!(node, hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),)
{
} else if matches!(
tcx.hir_node_by_def_id(def_id),
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. })
) {
// `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
// on them, they don't inherit it from the parent context.
return false;

View file

@ -130,6 +130,9 @@ pub(crate) struct Options {
/// default to loading from `$sysroot/bin/rustc`.
pub(crate) test_builder: Option<PathBuf>,
/// Run these wrapper instead of rustc directly
pub(crate) test_builder_wrappers: Vec<PathBuf>,
// Options that affect the documentation process
/// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
/// with and without documentation.
@ -204,6 +207,7 @@ impl fmt::Debug for Options {
.field("enable-per-target-ignores", &self.enable_per_target_ignores)
.field("run_check", &self.run_check)
.field("no_run", &self.no_run)
.field("test_builder_wrappers", &self.test_builder_wrappers)
.field("nocapture", &self.nocapture)
.field("scrape_examples_options", &self.scrape_examples_options)
.field("unstable_features", &self.unstable_features)
@ -521,6 +525,8 @@ impl Options {
dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
}
let test_builder_wrappers =
matches.opt_strs("test-builder-wrapper").iter().map(PathBuf::from).collect();
let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
let output = match (out_dir, output) {
@ -727,6 +733,7 @@ impl Options {
test_builder,
run_check,
no_run,
test_builder_wrappers,
nocapture,
crate_name,
output_format,

View file

@ -25,7 +25,7 @@ use tempfile::Builder as TempFileBuilder;
use std::env;
use std::io::{self, Write};
use std::panic;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
@ -306,6 +306,18 @@ fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
input + &exe_suffix
}
fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command {
let mut args = rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary].into_iter());
let exe = args.next().expect("unable to create rustc command");
let mut command = Command::new(exe);
for arg in args {
command.arg(arg);
}
command
}
fn run_test(
test: &str,
crate_name: &str,
@ -334,7 +346,7 @@ fn run_test(
.test_builder
.as_deref()
.unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
let mut compiler = Command::new(&rustc_binary);
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
compiler.arg("--crate-type").arg("bin");
for cfg in &rustdoc_options.cfgs {
compiler.arg("--cfg").arg(&cfg);

View file

@ -1698,9 +1698,10 @@ fn render_impl(
let id = cx.derive_id(format!("{item_type}.{name}"));
let source_id = trait_
.and_then(|trait_| {
trait_.items.iter().find(|item| {
item.name.map(|n| n.as_str().eq(name.as_str())).unwrap_or(false)
})
trait_
.items
.iter()
.find(|item| item.name.map(|n| n == *name).unwrap_or(false))
})
.map(|item| format!("{}.{name}", item.type_()));
write!(w, "<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">");

View file

@ -530,6 +530,14 @@ fn opts() -> Vec<RustcOptGroup> {
unstable("test-builder", |o| {
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
}),
unstable("test-builder-wrapper", |o| {
o.optmulti(
"",
"test-builder-wrapper",
"Wrapper program to pass test-builder and arguments",
"PATH",
)
}),
unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
unstable("generate-redirect-map", |o| {
o.optflagmulti(

View file

@ -80,9 +80,8 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
// check if parent is trait impl
if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id)
&& let Some(parent_node) = cx.tcx.opt_hir_node_by_def_id(parent_def_id)
&& matches!(
parent_node,
cx.tcx.hir_node_by_def_id(parent_def_id),
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }),
..

View file

@ -76,10 +76,9 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
.hir()
.get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id))
.def_id;
let parent_node = cx.tcx.opt_hir_node_by_def_id(parent_id);
let mut trait_self_ty = None;
if let Some(Node::Item(item)) = parent_node {
if let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_id) {
// If the method is an impl for a trait, don't warn.
if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind {
return;

View file

@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
&& let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
&& cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
&& let parent = cx.tcx.hir().get_parent_item(e.hir_id).def_id
&& let Some(Node::Item(Item{kind: ItemKind::Fn(..), ..})) = cx.tcx.opt_hir_node_by_def_id(parent)
&& let Node::Item(Item{kind: ItemKind::Fn(..), ..}) = cx.tcx.hir_node_by_def_id(parent)
// If the next item up is a function we check if it is an entry point
// and only then emit a linter warning
&& !is_entrypoint_fn(cx, parent.to_def_id())

View file

@ -92,7 +92,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty
.expect("already checked this is adt")
.did()
.as_local()
&& let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(local_def_id)
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id)
&& let hir::ItemKind::Enum(ref def, _) = item.kind
{
let variants_size = AdtVariantInfo::new(cx, *adt, subst);

View file

@ -225,10 +225,9 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
&& let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
&& let Some(local_did) = field.did.as_local()
&& let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(local_did)
&& !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
{
(hir_id, ident)
(cx.tcx.local_def_id_to_hir_id(local_did), ident)
} else {
return;
}

View file

@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
&& let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs()
&& let Some(self_adt) = self_ty.ty_adt_def()
&& let Some(self_def_id) = self_adt.did().as_local()
&& let Some(Node::Item(self_item)) = cx.tcx.opt_hir_node_by_def_id(self_def_id)
&& let Node::Item(self_item) = cx.tcx.hir_node_by_def_id(self_def_id)
// NB: can't call cx.typeck_results() as we are not in a body
&& let typeck_results = cx.tcx.typeck_body(*body_id)
&& should_lint(cx, typeck_results, block)

View file

@ -112,10 +112,7 @@ fn check_closures<'tcx>(
}
ctx.prev_bind = None;
ctx.prev_move_to_closure.clear();
if let Some(body) = cx
.tcx
.opt_hir_node_by_def_id(closure)
.and_then(associated_body)
if let Some(body) = associated_body(cx.tcx.hir_node_by_def_id(closure))
.map(|(_, body_id)| hir.body(body_id))
{
euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);

View file

@ -72,8 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if let Some(self_def) = self_ty.ty_adt_def()
&& let Some(self_local_did) = self_def.did().as_local()
&& let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
&& let Node::Item(x) = cx.tcx.hir_node(self_id)
&& let Node::Item(x) = cx.tcx.hir_node_by_def_id(self_local_did)
&& let type_name = x.ident.name.as_str().to_lowercase()
&& (impl_item.ident.name.as_str() == type_name
|| impl_item.ident.name.as_str().replace('_', "") == type_name)

View file

@ -95,7 +95,7 @@ impl SingleCallFn {
/// to be considered.
fn is_valid_item_kind(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
matches!(
cx.tcx.hir_node(cx.tcx.local_def_id_to_hir_id(def_id)),
cx.tcx.hir_node_by_def_id(def_id),
Node::Item(_) | Node::ImplItem(_) | Node::TraitItem(_)
)
}

View file

@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
_: Span,
def_id: LocalDefId,
) {
let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(
let is_in_trait_impl = if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(
cx.tcx
.hir()
.get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id))
@ -366,9 +366,9 @@ impl<'tcx> LateLintPass<'tcx> for Types {
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) {
match item.kind {
ImplItemKind::Const(ty, _) => {
let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx
let is_in_trait_impl = if let hir::Node::Item(item) = cx
.tcx
.opt_hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id)
.hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id)
{
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
} else {

View file

@ -74,7 +74,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues {
fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {
let parent_id = cx.tcx.hir().get_parent_item(hir_id);
let second_parent_id = cx.tcx.hir().get_parent_item(parent_id.into()).def_id;
if let Some(Node::Item(item)) = cx.tcx.opt_hir_node_by_def_id(second_parent_id) {
if let Node::Item(item) = cx.tcx.hir_node_by_def_id(second_parent_id) {
if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind {
return true;
}

View file

@ -330,8 +330,7 @@ pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol)
/// Checks if the `def_id` belongs to a function that is part of a trait impl.
pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
if let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(def_id)
&& let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)
if let Node::Item(item) = cx.tcx.parent_hir_node(cx.tcx.local_def_id_to_hir_id(def_id))
&& let ItemKind::Impl(imp) = item.kind
{
imp.of_trait.is_some()
@ -574,12 +573,12 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb
let hir = tcx.hir();
let root_mod;
let item_kind = match tcx.opt_hir_node_by_def_id(local_id) {
Some(Node::Crate(r#mod)) => {
let item_kind = match tcx.hir_node_by_def_id(local_id) {
Node::Crate(r#mod) => {
root_mod = ItemKind::Mod(r#mod);
&root_mod
},
Some(Node::Item(item)) => &item.kind,
Node::Item(item) => &item.kind,
_ => return Vec::new(),
};
@ -1254,12 +1253,10 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
/// Gets the name of the item the expression is in, if available.
pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id;
match cx.tcx.opt_hir_node_by_def_id(parent_id) {
Some(
Node::Item(Item { ident, .. })
| Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. }),
) => Some(ident.name),
match cx.tcx.hir_node_by_def_id(parent_id) {
Node::Item(Item { ident, .. })
| Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
_ => None,
}
}
@ -2667,11 +2664,10 @@ impl<'tcx> ExprUseNode<'tcx> {
.and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())),
)),
Self::Return(id) => {
let hir_id = cx.tcx.local_def_id_to_hir_id(id.def_id);
if let Node::Expr(Expr {
kind: ExprKind::Closure(c),
..
}) = cx.tcx.hir_node(hir_id)
}) = cx.tcx.hir_node_by_def_id(id.def_id)
{
match c.fn_decl.output {
FnRetTy::DefaultReturn(_) => None,

View file

@ -147,6 +147,8 @@ Options:
--test-builder PATH
The rustc-like binary to use as the test builder
--test-builder-wrapper PATH
Wrapper program to pass test-builder and arguments
--check Run rustdoc checks
--generate-redirect-map
Generate JSON file at the top level instead of