From 55e3dc487fdf8025fb99301883e24af15323912a Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Fri, 10 Nov 2023 07:42:27 -0800 Subject: [PATCH 01/17] CFI: Add missing use core::ffi::c_int Adds missing use core::ffi::c_int for when sanitizer_cfi_normalize_integers is defined. --- library/std/src/sys/unix/thread_local_dtor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index 06399e8a27427..667fd51696249 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -23,6 +23,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { /// This is necessary because the __cxa_thread_atexit_impl implementation /// std links to by default may be a C or C++ implementation that was not /// compiled using the Clang integer normalization option. + #[cfg(sanitizer_cfi_normalize_integers)] + use core::ffi::c_int; #[cfg(not(sanitizer_cfi_normalize_integers))] #[cfi_encoding = "i"] #[repr(transparent)] From 251e75ced6d2f5464d1ec87a52cf01e69dc93b3a Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:05:49 +0100 Subject: [PATCH 02/17] Explicitly unset $CARGO for compiletest Some UI tests trigger behavior in rustc where it reads $CARGO and changes behavior if it exists. To make the tests work that rely on it not being set, make sure it is not set. By default, this is not set, but people may do weird hacks that cause it to be set. --- src/bootstrap/src/core/build_steps/test.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 254fbc72a8c7e..8d4c58345f7b6 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1932,6 +1932,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } } } + + // Some UI tests trigger behavior in rustc where it reads $CARGO and changes behavior if it exists. + // To make the tests work that rely on it not being set, make sure it is not set. + cmd.env_remove("CARGO"); + cmd.env("RUSTC_BOOTSTRAP", "1"); // Override the rustc version used in symbol hashes to reduce the amount of normalization // needed when diffing test output. From e2664eba508bc8c089d81cde5932adbc51f5ca89 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Nov 2023 17:08:27 +1100 Subject: [PATCH 03/17] Reduce exposure of some items. --- compiler/rustc_ty_utils/src/abi.rs | 2 +- compiler/rustc_ty_utils/src/assoc.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 6 +++--- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- compiler/rustc_ty_utils/src/layout.rs | 2 +- compiler/rustc_ty_utils/src/lib.rs | 6 +++--- compiler/rustc_ty_utils/src/representability.rs | 2 +- compiler/rustc_ty_utils/src/sig_types.rs | 4 ++-- compiler/rustc_ty_utils/src/structural_match.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 38f2d616f9a5d..4a3c02bc19c43 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -16,7 +16,7 @@ use rustc_target::spec::abi::Abi as SpecAbi; use std::iter; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index ffeeae668587e..0a34aef16ae0f 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -8,7 +8,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, GenericArgs, ImplTraitInTraitData, Ty, TyCtxt}; use rustc_span::symbol::kw; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { associated_item, associated_item_def_ids, diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 35487d3b6982b..9ced50c8e138c 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -17,7 +17,7 @@ use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub}; /// Destructures array, ADT or tuple constants into the constants /// of their fields. -pub(crate) fn destructure_const<'tcx>( +fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, const_: ty::Const<'tcx>, ) -> ty::DestructuredConst<'tcx> { @@ -396,7 +396,7 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { } /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. -pub fn thir_abstract_const( +fn thir_abstract_const( tcx: TyCtxt<'_>, def: LocalDefId, ) -> Result>>, ErrorGuaranteed> { @@ -428,6 +428,6 @@ pub fn thir_abstract_const( Ok(Some(ty::EarlyBinder::bind(recurse_build(tcx, body, body_id, root_span)?))) } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { destructure_const, thir_abstract_const, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 24afd7dc35782..6cf5aa6f2fb36 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use std::iter; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { assumed_wf_types, assumed_wf_types_for_rpitit: |tcx, def_id| { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 1487f40fd9941..ba5fbcad639d7 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -328,6 +328,6 @@ fn resolve_associated_item<'tcx>( }) } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { resolve_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 52f723eba80ef..6cad8cfe630b3 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -24,7 +24,7 @@ use crate::errors::{ }; use crate::layout_sanity_check::sanity_check_layout; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { layout_of, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8de058f02c9e7..871e431ea6472 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -34,13 +34,13 @@ mod common_traits; mod consts; mod errors; mod implied_bounds; -pub mod instance; +mod instance; mod layout; mod layout_sanity_check; mod needs_drop; mod opaque_types; -pub mod representability; -pub mod sig_types; +mod representability; +mod sig_types; mod structural_match; mod ty; diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index f34e0df2c75ef..3aaa2e73bb805 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -6,7 +6,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { representability, representability_adt_ty, params_in_repr, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index ccdc6120196ac..268639a7f4441 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; -pub trait SpannedTypeVisitor<'tcx> { +pub(crate) trait SpannedTypeVisitor<'tcx> { type BreakTy = !; fn visit( &mut self, @@ -17,7 +17,7 @@ pub trait SpannedTypeVisitor<'tcx> { ) -> ControlFlow; } -pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( +pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( tcx: TyCtxt<'tcx>, item: LocalDefId, visitor: &mut V, diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 215acbe2c8f85..6e7a9887774f8 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -39,6 +39,6 @@ fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { ocx.select_all_or_error().is_empty() } -pub fn provide(providers: &mut Providers) { +pub(crate) fn provide(providers: &mut Providers) { providers.has_structural_eq_impls = has_structural_eq_impls; } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 485bde735d8f6..b7c75da7301f4 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -351,7 +351,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet Date: Thu, 16 Nov 2023 17:22:30 +1100 Subject: [PATCH 04/17] Inline and remove `record_layout_for_printing`. It has a single call site. --- compiler/rustc_ty_utils/src/layout.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 6cad8cfe630b3..b09566e166829 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -65,7 +65,11 @@ fn layout_of<'tcx>( let layout = layout_of_uncached(&cx, ty)?; let layout = TyAndLayout { ty, layout }; - record_layout_for_printing(&cx, layout); + // If we are running with `-Zprint-type-sizes`, maybe record layouts + // for dumping later. + if cx.tcx.sess.opts.unstable_opts.print_type_sizes { + record_layout_for_printing(&cx, layout); + } sanity_check_layout(&cx, &layout); @@ -911,21 +915,7 @@ fn coroutine_layout<'tcx>( Ok(layout) } -/// This is invoked by the `layout_of` query to record the final -/// layout of each type. -#[inline(always)] fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: TyAndLayout<'tcx>) { - // If we are running with `-Zprint-type-sizes`, maybe record layouts - // for dumping later. - if cx.tcx.sess.opts.unstable_opts.print_type_sizes { - record_layout_for_printing_outlined(cx, layout) - } -} - -fn record_layout_for_printing_outlined<'tcx>( - cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, - layout: TyAndLayout<'tcx>, -) { // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. From 9e6ee728a268ad700336d9b2933e152849c22a99 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Nov 2023 18:33:36 +1100 Subject: [PATCH 05/17] Alphabetize features. --- compiler/rustc_ty_utils/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 871e431ea6472..8321732b76630 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -10,11 +10,11 @@ #![allow(internal_features)] #![feature(assert_matches)] #![feature(associated_type_defaults)] +#![feature(box_patterns)] +#![feature(if_let_guard)] #![feature(iterator_try_collect)] #![feature(let_chains)] -#![feature(if_let_guard)] #![feature(never_type)] -#![feature(box_patterns)] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] From 6ba4c2f017434e4f26bdde5b05ef267f9467f7f8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 Nov 2023 14:35:34 +1100 Subject: [PATCH 06/17] Remove unused arena kinds in `rustc_hir` and `rustc_middle`. --- compiler/rustc_hir/src/arena.rs | 1 - compiler/rustc_middle/src/arena.rs | 17 +---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index e213623e06d91..f1f624269aee9 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -5,7 +5,6 @@ macro_rules! arena_types { ($macro:path) => ( $macro!([ // HIR types - [] hir_krate: rustc_hir::Crate<'tcx>, [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, [] owner_info: rustc_hir::OwnerInfo<'tcx>, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index dd761b4e31203..5735c5568f79f 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -27,19 +27,12 @@ macro_rules! arena_types { rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> >, - [decode] closure_debuginfo: - rustc_index::IndexVec< - rustc_target::abi::FieldIdx, - rustc_span::symbol::Symbol, - >, [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>, - [decode] borrowck_result: - rustc_middle::mir::BorrowCheckResult<'tcx>, + [decode] borrowck_result: rustc_middle::mir::BorrowCheckResult<'tcx>, [] resolver: rustc_data_structures::steal::Steal<( rustc_middle::ty::ResolverAstLowering, rustc_data_structures::sync::Lrc, )>, - [] output_filenames: std::sync::Arc, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, @@ -91,21 +84,16 @@ macro_rules! arena_types { rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> >, - [] all_traits: Vec, [] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities, - [] foreign_module: rustc_session::cstore::ForeignModule, - [] foreign_modules: Vec, [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap, [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<'tcx>, [decode] attribute: rustc_ast::Attribute, [] name_set: rustc_data_structures::unord::UnordSet, [] ordered_name_set: rustc_data_structures::fx::FxIndexSet, - [] hir_id_set: rustc_hir::HirIdSet, // Interned types [] tys: rustc_type_ir::WithCachedTypeInfo>, - [] predicates: rustc_type_ir::WithCachedTypeInfo>, [] consts: rustc_middle::ty::ConstData<'tcx>, // Note that this deliberately duplicates items in the `rustc_hir::arena`, @@ -113,7 +101,6 @@ macro_rules! arena_types { // (during lowering) and the `librustc_middle` arena (for decoding MIR) [decode] asm_template: rustc_ast::InlineAsmTemplatePiece, [decode] used_trait_imports: rustc_data_structures::unord::UnordSet, - [decode] registered_tools: rustc_middle::ty::RegisteredTools, [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, @@ -124,11 +111,9 @@ macro_rules! arena_types { rustc_hir::def_id::DefId, rustc_middle::ty::EarlyBinder> >, - [] bit_set_u32: rustc_index::bit_set::BitSet, [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>, [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>, [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, - [] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>), [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem, [] mod_child: rustc_middle::metadata::ModChild, [] features: rustc_feature::Features, From b142ed296c2b1c4508cc62224e9ff154c03be08f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 Nov 2023 16:11:06 +1100 Subject: [PATCH 07/17] Add a comment. --- compiler/rustc_hir/src/def.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index ed1dc751fbab7..1c04626978135 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -591,6 +591,8 @@ impl NonMacroAttrKind { } } + // Currently trivial, but exists in case a new kind is added in the future whose name starts + // with a vowel. pub fn article(self) -> &'static str { "a" } From 5bec5ae5452c0e5984941610362b4aa83ff7b71c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 Nov 2023 16:17:02 +1100 Subject: [PATCH 08/17] Put derives on a single line where possible. --- compiler/rustc_hir/src/def.rs | 15 +++++---------- compiler/rustc_hir/src/hir.rs | 18 ++++++------------ compiler/rustc_hir/src/hir_id.rs | 6 ++---- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 1c04626978135..e901eba35b783 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -13,8 +13,7 @@ use std::array::IntoIter; use std::fmt::Debug; /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct. -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum CtorOf { /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct. Struct, @@ -23,8 +22,7 @@ pub enum CtorOf { } /// What kind of constructor something is. -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum CtorKind { /// Constructor function automatically created by a tuple struct/variant. Fn, @@ -33,8 +31,7 @@ pub enum CtorKind { } /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`. -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum NonMacroAttrKind { /// Single-segment attribute defined by the language (`#[inline]`) Builtin(Symbol), @@ -48,8 +45,7 @@ pub enum NonMacroAttrKind { } /// What kind of definition something is; e.g., `mod` vs `struct`. -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum DefKind { // Type namespace Mod, @@ -299,8 +295,7 @@ impl DefKind { /// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`] /// pointing to the definition of `str_to_string` in the current crate. // -#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum Res { /// Definition having a unique ID (`DefId`), corresponds to something defined in user code. /// diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c4e44a6a4e388..00111767897ad 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1516,8 +1516,7 @@ impl<'hir> Body<'hir> { } /// The type of source expression that caused this coroutine to be created. -#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)] pub enum CoroutineKind { /// An explicit `async` block or the body of an async function. Async(CoroutineSource), @@ -1558,8 +1557,7 @@ impl fmt::Display for CoroutineKind { /// /// This helps error messages but is also used to drive coercions in /// type-checking (see #60424). -#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)] pub enum CoroutineSource { /// An explicit `async`/`gen` block written by the user. Block, @@ -2153,8 +2151,7 @@ pub enum LocalSource { } /// Hints at the original code for a `match _ { .. }`. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)] pub enum MatchSource { /// A `match _ { .. }`. Normal, @@ -2579,8 +2576,7 @@ impl<'hir> Ty<'hir> { } /// Not represented directly in the AST; referred to by name through a `ty_path`. -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)] -#[derive(HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum PrimTy { Int(IntTy), Uint(UintTy), @@ -2860,8 +2856,7 @@ impl ImplicitSelfKind { } } -#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)] -#[derive(HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum IsAsync { Async(Span), NotAsync, @@ -3280,8 +3275,7 @@ impl fmt::Display for Unsafety { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)] pub enum Constness { Const, NotConst, diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 34c6157793663..7b741e8882dea 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -3,8 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, use rustc_span::{def_id::DefPathHash, HashStableContext}; use std::fmt::{self, Debug}; -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[derive(Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] pub struct OwnerId { pub def_id: LocalDefId, } @@ -73,8 +72,7 @@ impl ToStableHashKey for OwnerId { /// the `local_id` part of the `HirId` changing, which is a very useful property in /// incremental compilation where we have to persist things through changes to /// the code base. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] #[rustc_pass_by_value] pub struct HirId { pub owner: OwnerId, From f79911def6957c873805e98837779cb75bdb1435 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 Nov 2023 16:20:45 +1100 Subject: [PATCH 09/17] Remove unused feature. --- compiler/rustc_hir/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 094d5b1e77cf7..87de3c0870bc9 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -4,7 +4,6 @@ #![feature(associated_type_defaults)] #![feature(closure_track_caller)] -#![feature(const_btree_len)] #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] From 2fd9442afca446af8084c8b15feba2daa2fb4bb6 Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 16:47:32 +0300 Subject: [PATCH 10/17] feat: specialize `SpecFromElem` for `()` While a better approach would be to implement it for all ZSTs which are `Copy` and have trivial `Clone`, the last property cannot be detected for now. Signed-off-by: Petr Portnov --- library/alloc/src/vec/spec_from_elem.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index da43d17bf3624..4e4150d94358d 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -36,12 +36,12 @@ impl SpecFromElem for i8 { if elem == 0 { return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } + let mut v = Vec::with_capacity_in(n, alloc); unsafe { - let mut v = Vec::with_capacity_in(n, alloc); ptr::write_bytes(v.as_mut_ptr(), elem as u8, n); v.set_len(n); - v } + v } } @@ -51,11 +51,26 @@ impl SpecFromElem for u8 { if elem == 0 { return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } + let mut v = Vec::with_capacity_in(n, alloc); unsafe { - let mut v = Vec::with_capacity_in(n, alloc); ptr::write_bytes(v.as_mut_ptr(), elem, n); v.set_len(n); - v } + v + } +} + +// A better way would be to implement this for all ZSTs which are `Copy` and have trivial `Clone` +// but this cannot be implemented currently +impl SpecFromElem for () { + #[inline] + fn from_elem(elem: (), n: usize, alloc: A) -> Vec<(), A> { + let mut v = Vec::with_capacity_in(n, alloc); + // SAFETY: the capacity has just been set to `n` and `()` + // is a ZST with trivial `Clone` implementation + unsafe { + v.set_len(n); + } + v } } From 91fcdde51b477e8def5e8cca2807a2dc12c8f06d Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 18:33:55 +0300 Subject: [PATCH 11/17] chore(GH-118094): explicitly mark `_elem` as unused Signed-off-by: Petr Portnov --- library/alloc/src/vec/spec_from_elem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index 4e4150d94358d..63225b41cbd22 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -64,7 +64,7 @@ impl SpecFromElem for u8 { // but this cannot be implemented currently impl SpecFromElem for () { #[inline] - fn from_elem(elem: (), n: usize, alloc: A) -> Vec<(), A> { + fn from_elem(_elem: (), n: usize, alloc: A) -> Vec<(), A> { let mut v = Vec::with_capacity_in(n, alloc); // SAFETY: the capacity has just been set to `n` and `()` // is a ZST with trivial `Clone` implementation From 72a8633ee8ab8986ab32fb29c2ebd9e2d98c723b Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 18:35:04 +0300 Subject: [PATCH 12/17] docs(GH-118094): make docs a bit more explicit Signed-off-by: Petr Portnov --- library/alloc/src/vec/spec_from_elem.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index 63225b41cbd22..01a6db14474bb 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -61,13 +61,13 @@ impl SpecFromElem for u8 { } // A better way would be to implement this for all ZSTs which are `Copy` and have trivial `Clone` -// but this cannot be implemented currently +// but the latter cannot be detected currently impl SpecFromElem for () { #[inline] fn from_elem(_elem: (), n: usize, alloc: A) -> Vec<(), A> { let mut v = Vec::with_capacity_in(n, alloc); - // SAFETY: the capacity has just been set to `n` and `()` - // is a ZST with trivial `Clone` implementation + // SAFETY: the capacity has just been set to `n` + // and `()` is a ZST with trivial `Clone` implementation unsafe { v.set_len(n); } From 3c999d8bf41564909c38775bb869fcd4a0da7954 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:01:11 -0500 Subject: [PATCH 13/17] Update books --- src/doc/book | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book b/src/doc/book index 5b6c1ceaa62ec..71352deb20727 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 5b6c1ceaa62ecbd6caef08df39b33b3938e99deb +Subproject commit 71352deb20727b4dda9ebfe8182709d5bf17dfea diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 311b84962016b..a6581246f9683 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 311b84962016b28c75525c86e7b3f49fd9101a39 +Subproject commit a6581246f96837113968c02187db24f742af3908 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 77dbe5782b248..ddb8b1309f9e9 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 77dbe5782b2488af3bb489ad702eaff438f465bf +Subproject commit ddb8b1309f9e905804cea1e248a4572fed6b464b From 8cf94c955f2aca6f5987d82b280616c60317803c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 20 Nov 2023 22:44:39 -0300 Subject: [PATCH 14/17] Fix occurrences of old fn names in comment and tracing --- compiler/rustc_trait_selection/src/traits/coherence.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index dcf5fd869290f..d5bc890764a10 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -998,7 +998,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> { let Goal { param_env, predicate } = goal.goal(); - // For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders` + // For bound predicates we simply call `infcx.instantiate_binder_with_placeholders` // and then prove the resulting predicate as a nested goal. let trait_ref = match predicate.kind().no_bound_vars() { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref, diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 1487f40fd9941..ba44d34e17d4f 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -61,7 +61,7 @@ fn resolve_instance<'tcx>( Ok(Some(Instance { def, args })) }; - debug!("inner_resolve_instance: result={:?}", result); + debug!("resolve_instance: result={:?}", result); result } From c965a7608da1f2cfb61b5d77c180e9b666f9fcb8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 20 Nov 2023 16:36:04 +1100 Subject: [PATCH 15/17] Wrap a long line. --- compiler/rustc_hir/src/lang_items.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 1d1a1ee886272..60f1449c177cb 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -233,7 +233,7 @@ language_item_table! { PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None; ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None; PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0); - PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0); + PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0); PanicInfo, sym::panic_info, panic_info, Target::Struct, GenericRequirement::None; PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None; PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; From ec10e3726c7b98466ad2523a9c5e4f112094beb1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 21 Nov 2023 12:40:34 +1100 Subject: [PATCH 16/17] Remove some unused functions. And remove `pub` from some local-only ones. --- compiler/rustc_hir/src/hir.rs | 58 +++-------------------------------- 1 file changed, 4 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 00111767897ad..18eb38ce8af08 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -13,7 +13,6 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_error_messages::MultiSpan; use rustc_index::IndexVec; use rustc_macros::HashStable_Generic; use rustc_span::hygiene::MacroKind; @@ -76,13 +75,6 @@ impl ParamName { ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime), } } - - pub fn normalize_to_macros_2_0(&self) -> ParamName { - match *self { - ParamName::Plain(ident) => ParamName::Plain(ident.normalize_to_macros_2_0()), - param_name => param_name, - } - } } #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)] @@ -116,7 +108,7 @@ pub enum LifetimeName { } impl LifetimeName { - pub fn is_elided(&self) -> bool { + fn is_elided(&self) -> bool { match self { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, @@ -289,10 +281,6 @@ impl GenericArg<'_> { } } - pub fn is_synthetic(&self) -> bool { - matches!(self, GenericArg::Lifetime(lifetime) if lifetime.ident == Ident::empty()) - } - pub fn descr(&self) -> &'static str { match self { GenericArg::Lifetime(_) => "lifetime", @@ -368,11 +356,6 @@ impl<'hir> GenericArgs<'hir> { panic!("GenericArgs::inputs: not a `Fn(T) -> U`"); } - #[inline] - pub fn has_type_params(&self) -> bool { - self.args.iter().any(|arg| matches!(arg, GenericArg::Type(_))) - } - pub fn has_err(&self) -> bool { self.args.iter().any(|arg| match arg { GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)), @@ -383,11 +366,6 @@ impl<'hir> GenericArgs<'hir> { }) } - #[inline] - pub fn num_type_params(&self) -> usize { - self.args.iter().filter(|arg| matches!(arg, GenericArg::Type(_))).count() - } - #[inline] pub fn num_lifetime_params(&self) -> usize { self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count() @@ -589,14 +567,6 @@ impl<'hir> Generics<'hir> { self.params.iter().find(|¶m| name == param.name.ident().name) } - pub fn spans(&self) -> MultiSpan { - if self.params.is_empty() { - self.span.into() - } else { - self.params.iter().map(|p| p.span).collect::>().into() - } - } - /// If there are generic parameters, return where to introduce a new one. pub fn span_for_lifetime_suggestion(&self) -> Option { if let Some(first) = self.params.first() @@ -679,7 +649,7 @@ impl<'hir> Generics<'hir> { ) } - pub fn span_for_predicate_removal(&self, pos: usize) -> Span { + fn span_for_predicate_removal(&self, pos: usize) -> Span { let predicate = &self.predicates[pos]; let span = predicate.span(); @@ -812,7 +782,7 @@ pub struct WhereRegionPredicate<'hir> { impl<'hir> WhereRegionPredicate<'hir> { /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate. - pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool { + fn is_param_bound(&self, param_def_id: LocalDefId) -> bool { self.lifetime.res == LifetimeName::Param(param_def_id) } } @@ -869,7 +839,7 @@ pub struct OwnerNodes<'tcx> { } impl<'tcx> OwnerNodes<'tcx> { - pub fn node(&self) -> OwnerNode<'tcx> { + fn node(&self) -> OwnerNode<'tcx> { use rustc_index::Idx; let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node; let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode. @@ -1272,10 +1242,6 @@ impl BinOpKind { matches!(self, BinOpKind::And | BinOpKind::Or) } - pub fn is_shift(self) -> bool { - matches!(self, BinOpKind::Shl | BinOpKind::Shr) - } - pub fn is_comparison(self) -> bool { match self { BinOpKind::Eq @@ -2115,16 +2081,6 @@ impl<'hir> QPath<'hir> { QPath::LangItem(_, span, _) => span, } } - - /// Returns the span of the last segment of this `QPath`. For example, `method` in - /// `<() as Trait>::method`. - pub fn last_segment_span(&self) -> Span { - match *self { - QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span, - QPath::TypeRelative(_, segment) => segment.ident.span, - QPath::LangItem(_, span, _) => span, - } - } } /// Hints at the original code for a let statement. @@ -3896,12 +3852,6 @@ impl<'hir> Node<'hir> { } } - /// Get the fields for the tuple-constructor, - /// if this node is a tuple constructor, otherwise None - pub fn tuple_fields(&self) -> Option<&'hir [FieldDef<'hir>]> { - if let Node::Ctor(&VariantData::Tuple(fields, _, _)) = self { Some(fields) } else { None } - } - /// Expect a [`Node::Param`] or panic. #[track_caller] pub fn expect_param(self) -> &'hir Param<'hir> { From 72653c1f50f49efd209f5864cfe560d2a883141d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 21 Nov 2023 14:55:58 +1100 Subject: [PATCH 17/17] Use macros to avoid `expect_*` boilerplate. The majority of these aren't actually used, but I kept them anyway. --- compiler/rustc_hir/src/hir.rs | 471 ++++++++-------------------------- 1 file changed, 102 insertions(+), 369 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 18eb38ce8af08..1d7e8dc5eaa37 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2267,6 +2267,35 @@ pub struct TraitItem<'hir> { pub defaultness: Defaultness, } +macro_rules! expect_methods_self_kind { + ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => { + $( + #[track_caller] + pub fn $name(&self) -> $ret_ty { + let $pat = &self.kind else { expect_failed(stringify!($ident), self) }; + $ret_val + } + )* + } +} + +macro_rules! expect_methods_self { + ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => { + $( + #[track_caller] + pub fn $name(&self) -> $ret_ty { + let $pat = self else { expect_failed(stringify!($ident), self) }; + $ret_val + } + )* + } +} + +#[track_caller] +fn expect_failed(ident: &'static str, found: T) -> ! { + panic!("{ident}: found {found:?}") +} + impl<'hir> TraitItem<'hir> { #[inline] pub fn hir_id(&self) -> HirId { @@ -2278,30 +2307,15 @@ impl<'hir> TraitItem<'hir> { TraitItemId { owner_id: self.owner_id } } - /// Expect an [`TraitItemKind::Const`] or panic. - #[track_caller] - pub fn expect_const(&self) -> (&'hir Ty<'hir>, Option) { - let TraitItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") }; - (ty, body) - } + expect_methods_self_kind! { + expect_const, (&'hir Ty<'hir>, Option), + TraitItemKind::Const(ty, body), (ty, *body); - /// Expect an [`TraitItemKind::Fn`] or panic. - #[track_caller] - pub fn expect_fn(&self) -> (&FnSig<'hir>, &TraitFn<'hir>) { - let TraitItemKind::Fn(ty, trfn) = &self.kind else { self.expect_failed("a function") }; - (ty, trfn) - } - - /// Expect an [`TraitItemKind::Type`] or panic. - #[track_caller] - pub fn expect_type(&self) -> (GenericBounds<'hir>, Option<&'hir Ty<'hir>>) { - let TraitItemKind::Type(bounds, ty) = self.kind else { self.expect_failed("a type") }; - (bounds, ty) - } + expect_fn, (&FnSig<'hir>, &TraitFn<'hir>), + TraitItemKind::Fn(ty, trfn), (ty, trfn); - #[track_caller] - fn expect_failed(&self, expected: &'static str) -> ! { - panic!("expected {expected} item, found {self:?}") + expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>), + TraitItemKind::Type(bounds, ty), (bounds, *ty); } } @@ -2366,30 +2380,10 @@ impl<'hir> ImplItem<'hir> { ImplItemId { owner_id: self.owner_id } } - /// Expect an [`ImplItemKind::Const`] or panic. - #[track_caller] - pub fn expect_const(&self) -> (&'hir Ty<'hir>, BodyId) { - let ImplItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") }; - (ty, body) - } - - /// Expect an [`ImplItemKind::Fn`] or panic. - #[track_caller] - pub fn expect_fn(&self) -> (&FnSig<'hir>, BodyId) { - let ImplItemKind::Fn(ty, body) = &self.kind else { self.expect_failed("a function") }; - (ty, *body) - } - - /// Expect an [`ImplItemKind::Type`] or panic. - #[track_caller] - pub fn expect_type(&self) -> &'hir Ty<'hir> { - let ImplItemKind::Type(ty) = self.kind else { self.expect_failed("a type") }; - ty - } - - #[track_caller] - fn expect_failed(&self, expected: &'static str) -> ! { - panic!("expected {expected} item, found {self:?}") + expect_methods_self_kind! { + expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body); + expect_fn, (&FnSig<'hir>, BodyId), ImplItemKind::Fn(ty, body), (ty, *body); + expect_type, &'hir Ty<'hir>, ImplItemKind::Type(ty), ty; } } @@ -3075,134 +3069,51 @@ impl<'hir> Item<'hir> { ItemId { owner_id: self.owner_id } } - /// Expect an [`ItemKind::ExternCrate`] or panic. - #[track_caller] - pub fn expect_extern_crate(&self) -> Option { - let ItemKind::ExternCrate(s) = self.kind else { self.expect_failed("an extern crate") }; - s - } + expect_methods_self_kind! { + expect_extern_crate, Option, ItemKind::ExternCrate(s), *s; - /// Expect an [`ItemKind::Use`] or panic. - #[track_caller] - pub fn expect_use(&self) -> (&'hir UsePath<'hir>, UseKind) { - let ItemKind::Use(p, uk) = self.kind else { self.expect_failed("a use") }; - (p, uk) - } + expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk); - /// Expect an [`ItemKind::Static`] or panic. - #[track_caller] - pub fn expect_static(&self) -> (&'hir Ty<'hir>, Mutability, BodyId) { - let ItemKind::Static(ty, mutbl, body) = self.kind else { self.expect_failed("a static") }; - (ty, mutbl, body) - } - /// Expect an [`ItemKind::Const`] or panic. - #[track_caller] - pub fn expect_const(&self) -> (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId) { - let ItemKind::Const(ty, gen, body) = self.kind else { self.expect_failed("a constant") }; - (ty, gen, body) - } - /// Expect an [`ItemKind::Fn`] or panic. - #[track_caller] - pub fn expect_fn(&self) -> (&FnSig<'hir>, &'hir Generics<'hir>, BodyId) { - let ItemKind::Fn(sig, gen, body) = &self.kind else { self.expect_failed("a function") }; - (sig, gen, *body) - } + expect_static, (&'hir Ty<'hir>, Mutability, BodyId), + ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body); - /// Expect an [`ItemKind::Macro`] or panic. - #[track_caller] - pub fn expect_macro(&self) -> (&ast::MacroDef, MacroKind) { - let ItemKind::Macro(def, mk) = &self.kind else { self.expect_failed("a macro") }; - (def, *mk) - } + expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), + ItemKind::Const(ty, gen, body), (ty, gen, *body); - /// Expect an [`ItemKind::Mod`] or panic. - #[track_caller] - pub fn expect_mod(&self) -> &'hir Mod<'hir> { - let ItemKind::Mod(m) = self.kind else { self.expect_failed("a module") }; - m - } + expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId), + ItemKind::Fn(sig, gen, body), (sig, gen, *body); - /// Expect an [`ItemKind::ForeignMod`] or panic. - #[track_caller] - pub fn expect_foreign_mod(&self) -> (Abi, &'hir [ForeignItemRef]) { - let ItemKind::ForeignMod { abi, items } = self.kind else { - self.expect_failed("a foreign module") - }; - (abi, items) - } + expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk); - /// Expect an [`ItemKind::GlobalAsm`] or panic. - #[track_caller] - pub fn expect_global_asm(&self) -> &'hir InlineAsm<'hir> { - let ItemKind::GlobalAsm(asm) = self.kind else { self.expect_failed("a global asm") }; - asm - } + expect_mod, &'hir Mod<'hir>, ItemKind::Mod(m), m; - /// Expect an [`ItemKind::TyAlias`] or panic. - #[track_caller] - pub fn expect_ty_alias(&self) -> (&'hir Ty<'hir>, &'hir Generics<'hir>) { - let ItemKind::TyAlias(ty, gen) = self.kind else { self.expect_failed("a type alias") }; - (ty, gen) - } + expect_foreign_mod, (Abi, &'hir [ForeignItemRef]), + ItemKind::ForeignMod { abi, items }, (*abi, items); - /// Expect an [`ItemKind::OpaqueTy`] or panic. - #[track_caller] - pub fn expect_opaque_ty(&self) -> &OpaqueTy<'hir> { - let ItemKind::OpaqueTy(ty) = &self.kind else { self.expect_failed("an opaque type") }; - ty - } + expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm; - /// Expect an [`ItemKind::Enum`] or panic. - #[track_caller] - pub fn expect_enum(&self) -> (&EnumDef<'hir>, &'hir Generics<'hir>) { - let ItemKind::Enum(def, gen) = &self.kind else { self.expect_failed("an enum") }; - (def, gen) - } + expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>), + ItemKind::TyAlias(ty, gen), (ty, gen); - /// Expect an [`ItemKind::Struct`] or panic. - #[track_caller] - pub fn expect_struct(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { - let ItemKind::Struct(data, gen) = &self.kind else { self.expect_failed("a struct") }; - (data, gen) - } + expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty; - /// Expect an [`ItemKind::Union`] or panic. - #[track_caller] - pub fn expect_union(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { - let ItemKind::Union(data, gen) = &self.kind else { self.expect_failed("a union") }; - (data, gen) - } + expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, gen), (def, gen); - /// Expect an [`ItemKind::Trait`] or panic. - #[track_caller] - pub fn expect_trait( - self, - ) -> (IsAuto, Unsafety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]) { - let ItemKind::Trait(is_auto, unsafety, gen, bounds, items) = self.kind else { - self.expect_failed("a trait") - }; - (is_auto, unsafety, gen, bounds, items) - } + expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>), + ItemKind::Struct(data, gen), (data, gen); - /// Expect an [`ItemKind::TraitAlias`] or panic. - #[track_caller] - pub fn expect_trait_alias(&self) -> (&'hir Generics<'hir>, GenericBounds<'hir>) { - let ItemKind::TraitAlias(gen, bounds) = self.kind else { - self.expect_failed("a trait alias") - }; - (gen, bounds) - } + expect_union, (&VariantData<'hir>, &'hir Generics<'hir>), + ItemKind::Union(data, gen), (data, gen); - /// Expect an [`ItemKind::Impl`] or panic. - #[track_caller] - pub fn expect_impl(&self) -> &'hir Impl<'hir> { - let ItemKind::Impl(imp) = self.kind else { self.expect_failed("an impl") }; - imp - } + expect_trait, + (IsAuto, Unsafety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), + ItemKind::Trait(is_auto, unsafety, gen, bounds, items), + (*is_auto, *unsafety, gen, bounds, items); - #[track_caller] - fn expect_failed(&self, expected: &'static str) -> ! { - panic!("expected {expected} item, found {self:?}") + expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>), + ItemKind::TraitAlias(gen, bounds), (gen, bounds); + + expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp; } } @@ -3574,32 +3485,11 @@ impl<'hir> OwnerNode<'hir> { } } - pub fn expect_item(self) -> &'hir Item<'hir> { - match self { - OwnerNode::Item(n) => n, - _ => panic!(), - } - } - - pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> { - match self { - OwnerNode::ForeignItem(n) => n, - _ => panic!(), - } - } - - pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> { - match self { - OwnerNode::ImplItem(n) => n, - _ => panic!(), - } - } - - pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> { - match self { - OwnerNode::TraitItem(n) => n, - _ => panic!(), - } + expect_methods_self! { + expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n; + expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n; + expect_impl_item, &'hir ImplItem<'hir>, OwnerNode::ImplItem(n), n; + expect_trait_item, &'hir TraitItem<'hir>, OwnerNode::TraitItem(n), n; } } @@ -3852,190 +3742,33 @@ impl<'hir> Node<'hir> { } } - /// Expect a [`Node::Param`] or panic. - #[track_caller] - pub fn expect_param(self) -> &'hir Param<'hir> { - let Node::Param(this) = self else { self.expect_failed("a parameter") }; - this - } - - /// Expect a [`Node::Item`] or panic. - #[track_caller] - pub fn expect_item(self) -> &'hir Item<'hir> { - let Node::Item(this) = self else { self.expect_failed("a item") }; - this - } - - /// Expect a [`Node::ForeignItem`] or panic. - #[track_caller] - pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> { - let Node::ForeignItem(this) = self else { self.expect_failed("a foreign item") }; - this - } - - /// Expect a [`Node::TraitItem`] or panic. - #[track_caller] - pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> { - let Node::TraitItem(this) = self else { self.expect_failed("a trait item") }; - this - } - - /// Expect a [`Node::ImplItem`] or panic. - #[track_caller] - pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> { - let Node::ImplItem(this) = self else { self.expect_failed("an implementation item") }; - this - } - - /// Expect a [`Node::Variant`] or panic. - #[track_caller] - pub fn expect_variant(self) -> &'hir Variant<'hir> { - let Node::Variant(this) = self else { self.expect_failed("a variant") }; - this - } - - /// Expect a [`Node::Field`] or panic. - #[track_caller] - pub fn expect_field(self) -> &'hir FieldDef<'hir> { - let Node::Field(this) = self else { self.expect_failed("a field definition") }; - this - } - - /// Expect a [`Node::AnonConst`] or panic. - #[track_caller] - pub fn expect_anon_const(self) -> &'hir AnonConst { - let Node::AnonConst(this) = self else { self.expect_failed("an anonymous constant") }; - this - } - - /// Expect a [`Node::ConstBlock`] or panic. - #[track_caller] - pub fn expect_inline_const(self) -> &'hir ConstBlock { - let Node::ConstBlock(this) = self else { self.expect_failed("an inline constant") }; - this - } - - /// Expect a [`Node::Expr`] or panic. - #[track_caller] - pub fn expect_expr(self) -> &'hir Expr<'hir> { - let Node::Expr(this) = self else { self.expect_failed("an expression") }; - this - } - /// Expect a [`Node::ExprField`] or panic. - #[track_caller] - pub fn expect_expr_field(self) -> &'hir ExprField<'hir> { - let Node::ExprField(this) = self else { self.expect_failed("an expression field") }; - this - } - - /// Expect a [`Node::Stmt`] or panic. - #[track_caller] - pub fn expect_stmt(self) -> &'hir Stmt<'hir> { - let Node::Stmt(this) = self else { self.expect_failed("a statement") }; - this - } - - /// Expect a [`Node::PathSegment`] or panic. - #[track_caller] - pub fn expect_path_segment(self) -> &'hir PathSegment<'hir> { - let Node::PathSegment(this) = self else { self.expect_failed("a path segment") }; - this - } - - /// Expect a [`Node::Ty`] or panic. - #[track_caller] - pub fn expect_ty(self) -> &'hir Ty<'hir> { - let Node::Ty(this) = self else { self.expect_failed("a type") }; - this - } - - /// Expect a [`Node::TypeBinding`] or panic. - #[track_caller] - pub fn expect_type_binding(self) -> &'hir TypeBinding<'hir> { - let Node::TypeBinding(this) = self else { self.expect_failed("a type binding") }; - this - } - - /// Expect a [`Node::TraitRef`] or panic. - #[track_caller] - pub fn expect_trait_ref(self) -> &'hir TraitRef<'hir> { - let Node::TraitRef(this) = self else { self.expect_failed("a trait reference") }; - this - } - - /// Expect a [`Node::Pat`] or panic. - #[track_caller] - pub fn expect_pat(self) -> &'hir Pat<'hir> { - let Node::Pat(this) = self else { self.expect_failed("a pattern") }; - this - } - - /// Expect a [`Node::PatField`] or panic. - #[track_caller] - pub fn expect_pat_field(self) -> &'hir PatField<'hir> { - let Node::PatField(this) = self else { self.expect_failed("a pattern field") }; - this - } - - /// Expect a [`Node::Arm`] or panic. - #[track_caller] - pub fn expect_arm(self) -> &'hir Arm<'hir> { - let Node::Arm(this) = self else { self.expect_failed("an arm") }; - this - } - - /// Expect a [`Node::Block`] or panic. - #[track_caller] - pub fn expect_block(self) -> &'hir Block<'hir> { - let Node::Block(this) = self else { self.expect_failed("a block") }; - this - } - - /// Expect a [`Node::Local`] or panic. - #[track_caller] - pub fn expect_local(self) -> &'hir Local<'hir> { - let Node::Local(this) = self else { self.expect_failed("a local") }; - this - } - - /// Expect a [`Node::Ctor`] or panic. - #[track_caller] - pub fn expect_ctor(self) -> &'hir VariantData<'hir> { - let Node::Ctor(this) = self else { self.expect_failed("a constructor") }; - this - } - - /// Expect a [`Node::Lifetime`] or panic. - #[track_caller] - pub fn expect_lifetime(self) -> &'hir Lifetime { - let Node::Lifetime(this) = self else { self.expect_failed("a lifetime") }; - this - } - - /// Expect a [`Node::GenericParam`] or panic. - #[track_caller] - pub fn expect_generic_param(self) -> &'hir GenericParam<'hir> { - let Node::GenericParam(this) = self else { self.expect_failed("a generic parameter") }; - this - } - - /// Expect a [`Node::Crate`] or panic. - #[track_caller] - pub fn expect_crate(self) -> &'hir Mod<'hir> { - let Node::Crate(this) = self else { self.expect_failed("a crate") }; - this - } - - /// Expect a [`Node::Infer`] or panic. - #[track_caller] - pub fn expect_infer(self) -> &'hir InferArg { - let Node::Infer(this) = self else { self.expect_failed("an infer") }; - this - } - - #[track_caller] - fn expect_failed(&self, expected: &'static str) -> ! { - panic!("expected {expected} node, found {self:?}") + expect_methods_self! { + expect_param, &'hir Param<'hir>, Node::Param(n), n; + expect_item, &'hir Item<'hir>, Node::Item(n), n; + expect_foreign_item, &'hir ForeignItem<'hir>, Node::ForeignItem(n), n; + expect_trait_item, &'hir TraitItem<'hir>, Node::TraitItem(n), n; + expect_impl_item, &'hir ImplItem<'hir>, Node::ImplItem(n), n; + expect_variant, &'hir Variant<'hir>, Node::Variant(n), n; + expect_field, &'hir FieldDef<'hir>, Node::Field(n), n; + expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n; + expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n; + expect_expr, &'hir Expr<'hir>, Node::Expr(n), n; + expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n; + expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n; + expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n; + expect_ty, &'hir Ty<'hir>, Node::Ty(n), n; + expect_type_binding, &'hir TypeBinding<'hir>, Node::TypeBinding(n), n; + expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n; + expect_pat, &'hir Pat<'hir>, Node::Pat(n), n; + expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n; + expect_arm, &'hir Arm<'hir>, Node::Arm(n), n; + expect_block, &'hir Block<'hir>, Node::Block(n), n; + expect_local, &'hir Local<'hir>, Node::Local(n), n; + expect_ctor, &'hir VariantData<'hir>, Node::Ctor(n), n; + expect_lifetime, &'hir Lifetime, Node::Lifetime(n), n; + expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n; + expect_crate, &'hir Mod<'hir>, Node::Crate(n), n; + expect_infer, &'hir InferArg, Node::Infer(n), n; } }