From a5cb61d39ba92beb8b48d9b4dfe72ac06fa4503c Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Mar 2024 12:34:29 -0700 Subject: [PATCH 01/10] cleanup prefixes iterator --- .../src/diagnostics/conflict_errors.rs | 27 ++---- compiler/rustc_borrowck/src/prefixes.rs | 89 +++++-------------- 2 files changed, 28 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 0776f455efd9c..cec79a4a3f537 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -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 @@ -1995,21 +1995,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { kind: Option, ) { 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 root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection); + let proper_span = self.body.local_decls[borrowed_local].source_info.span; - 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 +2010,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 +2533,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(), diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 8bb3dc88b3467..8a3a089d0eeba 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -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>, } @@ -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 { 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."), - } } } } From 07e0182fd3276bb09081a67dbd6cb69910f14413 Mon Sep 17 00:00:00 2001 From: baitcode Date: Thu, 14 Mar 2024 18:58:23 +0000 Subject: [PATCH 02/10] Fix minor documentation issue. Code outside the test would fail. Seek documentation clearly states that negative indexes will cause error. Just making the code in the example to return Result::Ok, instead of Result::Error. --- library/std/src/io/cursor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 25c64240e7480..4ef1f1b695e60 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -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(()) From 89b536dbc85e23275f08feaf73a7abce691bf72c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 14 Mar 2024 21:05:06 +0300 Subject: [PATCH 03/10] hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id` Also replace a few `hir_node()` calls with `hir_node_by_def_id()` --- .../src/diagnostics/conflict_errors.rs | 3 +- .../src/diagnostics/mutability_errors.rs | 11 +-- .../rustc_hir_analysis/src/check/entry.rs | 9 +-- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- .../src/collect/predicates_of.rs | 6 +- .../src/collect/type_of/opaque.rs | 5 +- compiler/rustc_hir_typeck/src/_match.rs | 7 +- compiler/rustc_hir_typeck/src/expr.rs | 16 ++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 15 ++-- .../src/infer/error_reporting/mod.rs | 23 +++--- .../nice_region_error/static_impl_trait.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 15 ++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +- compiler/rustc_middle/src/hir/map/mod.rs | 11 +-- compiler/rustc_middle/src/ty/context.rs | 12 +--- compiler/rustc_passes/src/dead.rs | 70 +++++++++---------- compiler/rustc_passes/src/entry.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 15 ++-- .../error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 19 +++-- .../error_reporting/type_err_ctxt_ext.rs | 4 +- compiler/rustc_ty_utils/src/assoc.rs | 6 +- src/librustdoc/clean/mod.rs | 6 +- src/librustdoc/clean/utils.rs | 7 +- .../passes/check_doc_test_visibility.rs | 3 +- src/tools/clippy/clippy_lints/src/escape.rs | 3 +- src/tools/clippy/clippy_lints/src/exit.rs | 2 +- .../clippy_lints/src/functions/result.rs | 2 +- src/tools/clippy/clippy_lints/src/misc.rs | 3 +- .../src/missing_fields_in_debug.rs | 2 +- .../src/needless_pass_by_ref_mut.rs | 5 +- .../src/self_named_constructors.rs | 3 +- .../clippy/clippy_lints/src/single_call_fn.rs | 2 +- .../clippy/clippy_lints/src/types/mod.rs | 6 +- .../clippy_lints/src/zero_sized_map_values.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 22 +++--- 37 files changed, 135 insertions(+), 199 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 0776f455efd9c..27159af81e16e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -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) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index ebc9f1d109ee7..68d492bbf3a81 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -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)); diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 3d803258c8e5e..d5908cf285118 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -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()) } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index f5bfc6b1b869d..22afddad6336d 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -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); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ae15efc0764b7..f525004534408 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -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 diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 2675eacc06e19..6aae4aa21b878 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -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 { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index dcb01a117b047..b5765913cb857 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -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), diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index c7343387dafc4..4b3359858f15d 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -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; }; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7e19e577d7d0c..1a142f27809e1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 2747700f3c136..7a25bf44340ce 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -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(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index edd7f733ec96b..71df1ffc6ddfa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -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::>(); - 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)) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index afcb4a182fa4b..503645191aacf 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -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 diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index d14cabfc429b5..24eaff08220d6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -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(); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 26226386ef721..d8cfceab460a0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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)); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index a64fa74762c04..d0002694fd0df 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -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> { - 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> { - 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 { - 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) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5362b6d8b24ca..17ba97c5fd3a7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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 { - 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) } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 0371bab83c044..350f7e166bf9c 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -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); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 0bab13037e4ae..2af5a54a0cac7 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -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; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 2a78f47c34f67..9fbae8f84b4aa 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -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); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 126bc0c9ec0fc..745ddfc08af47 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -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") diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 1241227a5af39..cca004312bf5e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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, @@ -1685,8 +1686,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() @@ -1720,8 +1721,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option { - 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; }; @@ -1813,10 +1814,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(); @@ -4450,7 +4449,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; }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index d18acb8c864ba..1cbc94800c59b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -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) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 3f628092190b5..32ba1e1948130 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -319,11 +319,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, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b32d3ad562d03..b28e57a93591c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 57916ff0ff781..aed1d9c5a8337 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -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; diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 0603aae553609..e85b998bfbe1b 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -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(_), .. }), .. diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 8857cb8e3827f..ad589dad350b3 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index 6603512c73cdf..106844dd43489 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -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()) diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index 7f36f33fe708c..37fbf2c7d5960 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs index b9784a58596c1..ac9df8bfca3eb 100644 --- a/src/tools/clippy/clippy_lints/src/misc.rs +++ b/src/tools/clippy/clippy_lints/src/misc.rs @@ -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; } diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 88b331ddefdb7..3bf9f75e22619 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -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) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index a5b58f9910ad5..a450dee305005 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -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); diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index fc5a45dd56d6b..85a2b1a673525 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -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) diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index 223cbb3fae106..2ce7e714c6424 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -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(_) ) } diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 7882bfdd09fad..bdef82e9c5eed 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -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 { diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 81d4a26e9da43..4aaf3b0a0b674 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -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; } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 708037a465558..1cf896d743453 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -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 { 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, From 7ea4f3576675617c68e70014c955a49127c78fe0 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 15 Mar 2024 10:54:40 +0300 Subject: [PATCH 04/10] less symbols interner locks --- compiler/rustc_resolve/src/rustdoc.rs | 7 ++++--- src/librustdoc/html/render/mod.rs | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 4ff4ccf5e9845..0ebcad3cdb809 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -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); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fe83095f944ab..bfd67ccbd3f9a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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, "
"); From 58dee7d7817f8edcd32d7eb259e22d49a4e1abbe Mon Sep 17 00:00:00 2001 From: Travis Finkenauer Date: Sat, 19 Aug 2023 15:40:24 -0700 Subject: [PATCH 05/10] rustdoc: add `--test-builder-wrapper` argument Instead of executing the test builder directly, the test builder wrapper will be called with test builder as the first argument and subsequent arguments. This is similar to cargo's RUSTC_WRAPPER argument. The `--test-builder-wrapper` argument can be passed multiple times to allow "nesting" of wrappers. --- src/librustdoc/config.rs | 7 +++++++ src/librustdoc/doctest.rs | 14 ++++++++++++-- src/librustdoc/lib.rs | 8 ++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 4b1a417b21127..be7e319bc79f4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -130,6 +130,9 @@ pub(crate) struct Options { /// default to loading from `$sysroot/bin/rustc`. pub(crate) test_builder: Option, + /// Run these wrapper instead of rustc directly + pub(crate) test_builder_wrappers: Vec, + // 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, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d446b781bf139..96ad83e786763 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -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,16 @@ fn add_exe_suffix(input: String, target: &TargetTriple) -> String { input + &exe_suffix } +fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command { + let args: Vec<&Path> = + rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary].into_iter()).collect(); + let (exe, args) = args.split_first().expect("unable to create rustc command"); + + let mut command = Command::new(exe); + command.args(args); + command +} + fn run_test( test: &str, crate_name: &str, @@ -334,7 +344,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); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 39d27b104cdde..9618690575a21 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -530,6 +530,14 @@ fn opts() -> Vec { 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", + "The wrapper program for running rustc", + "WRAPPER", + ) + }), unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")), unstable("generate-redirect-map", |o| { o.optflagmulti( From 3d53242e53bcf4f43f7d361cb7e2a4a28f30db9c Mon Sep 17 00:00:00 2001 From: Travis Finkenauer Date: Sun, 20 Aug 2023 01:02:13 -0700 Subject: [PATCH 06/10] rustdoc: fix test's saved stdout Also reword "test-builder-wrapper" argument help. --- src/librustdoc/lib.rs | 4 ++-- .../run-make/issue-88756-default-output/output-default.stdout | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 9618690575a21..18651875130fc 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -534,8 +534,8 @@ fn opts() -> Vec { o.optmulti( "", "test-builder-wrapper", - "The wrapper program for running rustc", - "WRAPPER", + "Wrapper program to pass test-builder and arguments", + "PATH", ) }), unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")), diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout index 38a3965f0c53d..12c1b389fb340 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -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 From 713043ef226332216ed75c1bd5ec1f6068a8439c Mon Sep 17 00:00:00 2001 From: Travis Finkenauer Date: Sun, 20 Aug 2023 20:25:30 -0700 Subject: [PATCH 07/10] rustdoc: create rustc command with an iterator This avoids unnecessary allocation with a temporary Vec. --- src/librustdoc/doctest.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 96ad83e786763..c6eb7be08cd81 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -307,12 +307,14 @@ fn add_exe_suffix(input: String, target: &TargetTriple) -> String { } fn wrapped_rustc_command(rustc_wrappers: &[PathBuf], rustc_binary: &Path) -> Command { - let args: Vec<&Path> = - rustc_wrappers.iter().map(PathBuf::as_path).chain([rustc_binary].into_iter()).collect(); - let (exe, args) = args.split_first().expect("unable to create rustc 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); - command.args(args); + for arg in args { + command.arg(arg); + } + command } From d02e66ddf0f1b0d436b3a8374479ec8efbe4b1db Mon Sep 17 00:00:00 2001 From: Travis Finkenauer Date: Fri, 15 Mar 2024 03:19:29 -0700 Subject: [PATCH 08/10] doc: add --test-builder/--test-builder-wrapper --- src/doc/rustdoc/src/command-line-arguments.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index b46d80eb362e2..fe5cb529c2638 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -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. From e126ceb46d5f24015f0644df5d360fa9209d48be Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 14 Mar 2024 15:26:49 +0100 Subject: [PATCH 09/10] Greatly reduce GCC build logs --- .../host-x86_64/dist-x86_64-linux/build-gccjit.sh | 12 ++++++++---- .../docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile | 3 ++- .../docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile | 3 ++- .../docker/host-x86_64/x86_64-gnu-tools/Dockerfile | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh old mode 100644 new mode 100755 index 324dd5fac161e..2c65522cc1e94 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh @@ -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 @@ -20,9 +22,11 @@ cd ../gcc-build --enable-checking=release \ --disable-bootstrap \ --disable-multilib \ - --prefix=$(pwd)/../gcc-install -make -make install + --prefix=$(pwd)/../gcc-install \ + --quiet + +hide_output make +hide_output make install rm -rf ../gcc-src ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile index 6540a500d3a58..4fc2b2e507e0d 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile @@ -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 diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile index ed4e1978c5d40..7c2ecd198e234 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile @@ -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 diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index a03577b45112b..6f72056989818 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -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 \ From c4ece1f4c8862724fe195bf5bf0d4dcaa76b7686 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 15 Mar 2024 11:33:14 +0100 Subject: [PATCH 10/10] Build GCC with as many threads as available --- src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh index 2c65522cc1e94..b22d60f2b1d10 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh @@ -16,16 +16,16 @@ 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 \ - --quiet -hide_output make +hide_output make -j$(nproc) hide_output make install rm -rf ../gcc-src