From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_hir/Cargo.toml | 1 - compiler/rustc_hir/src/arena.rs | 1 - compiler/rustc_hir/src/def.rs | 66 ++- compiler/rustc_hir/src/definitions.rs | 22 +- compiler/rustc_hir/src/diagnostic_items.rs | 7 +- compiler/rustc_hir/src/hir.rs | 795 ++++++----------------------- compiler/rustc_hir/src/hir_id.rs | 8 +- compiler/rustc_hir/src/intravisit.rs | 8 +- compiler/rustc_hir/src/lang_items.rs | 7 +- compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir/src/pat_util.rs | 7 +- compiler/rustc_hir/src/target.rs | 36 ++ 12 files changed, 284 insertions(+), 675 deletions(-) (limited to 'compiler/rustc_hir') diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index a72c4d0f1..ac24c47d0 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -9,7 +9,6 @@ odht = { version = "0.3.1", features = ["nightly"] } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } -rustc_error_messages = { path = "../rustc_error_messages" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index e213623e0..f1f624269 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_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index ed1dc751f..81ec7ddb6 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -1,9 +1,10 @@ +use crate::definitions::DefPathData; use crate::hir; use rustc_ast as ast; use rustc_ast::NodeId; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::ToStableHashKey; +use rustc_data_structures::unord::UnordMap; use rustc_macros::HashStable_Generic; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::hygiene::MacroKind; @@ -13,8 +14,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 +23,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 +32,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 +46,8 @@ 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)] +/// `enum DefPathData` may need to be updated if a new variant is added here. +#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)] pub enum DefKind { // Type namespace Mod, @@ -118,7 +116,6 @@ pub enum DefKind { of_trait: bool, }, Closure, - Coroutine, } impl DefKind { @@ -161,7 +158,6 @@ impl DefKind { DefKind::Field => "field", DefKind::Impl { .. } => "implementation", DefKind::Closure => "closure", - DefKind::Coroutine => "coroutine", DefKind::ExternCrate => "extern crate", DefKind::GlobalAsm => "global assembly block", } @@ -220,7 +216,6 @@ impl DefKind { | DefKind::LifetimeParam | DefKind::ExternCrate | DefKind::Closure - | DefKind::Coroutine | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm @@ -228,9 +223,44 @@ impl DefKind { } } + pub fn def_path_data(self, name: Symbol) -> DefPathData { + match self { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::ExternCrate => DefPathData::TypeNs(name), + DefKind::Fn + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(..) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Field => DefPathData::ValueNs(name), + DefKind::Macro(..) => DefPathData::MacroNs(name), + DefKind::LifetimeParam => DefPathData::LifetimeNs(name), + DefKind::Ctor(..) => DefPathData::Ctor, + DefKind::Use => DefPathData::Use, + DefKind::ForeignMod => DefPathData::ForeignMod, + DefKind::AnonConst => DefPathData::AnonConst, + DefKind::InlineConst => DefPathData::AnonConst, + DefKind::OpaqueTy => DefPathData::OpaqueTy, + DefKind::GlobalAsm => DefPathData::GlobalAsm, + DefKind::Impl { .. } => DefPathData::Impl, + DefKind::Closure => DefPathData::Closure, + } + } + #[inline] pub fn is_fn_like(self) -> bool { - matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Coroutine) + matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) } /// Whether `query get_codegen_attrs` should be used with this definition. @@ -240,7 +270,6 @@ impl DefKind { | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure - | DefKind::Coroutine | DefKind::Static(_) => true, DefKind::Mod | DefKind::Struct @@ -299,8 +328,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. /// @@ -575,7 +603,7 @@ impl CtorKind { match *vdata { ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)), ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)), - ast::VariantData::Struct(..) => None, + ast::VariantData::Struct { .. } => None, } } } @@ -591,6 +619,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" } @@ -776,4 +806,4 @@ pub enum LifetimeRes { ElidedAnchor { start: NodeId, end: NodeId }, } -pub type DocLinkResMap = FxHashMap<(Symbol, Namespace), Option>>; +pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option>>; diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 168b336e3..2ab9a6ef3 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -8,8 +8,8 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::def_path_hash_map::DefPathHashMap; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; +use rustc_data_structures::unord::UnordMap; use rustc_index::IndexVec; use rustc_span::symbol::{kw, sym, Symbol}; @@ -95,7 +95,7 @@ impl DefPathTable { #[derive(Debug)] pub struct Definitions { table: DefPathTable, - next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>, + next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>, /// The [StableCrateId] of the local crate. stable_crate_id: StableCrateId, @@ -246,6 +246,7 @@ impl DefPath { } } +/// New variants should only be added in synchronization with `enum DefKind`. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] pub enum DefPathData { // Root: these should only be used for the root nodes, because @@ -271,7 +272,7 @@ pub enum DefPathData { /// Something in the lifetime namespace. LifetimeNs(Symbol), /// A closure expression. - ClosureExpr, + Closure, // Subportions of items: /// Implicit constructor for a unit or tuple-like struct or enum variant. @@ -280,9 +281,7 @@ pub enum DefPathData { AnonConst, /// An existential `impl Trait` type node. /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name. - ImplTrait, - /// `impl Trait` generated associated type node. - ImplTraitAssocTy, + OpaqueTy, } impl Definitions { @@ -403,16 +402,17 @@ impl DefPathData { pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { + TypeNs(name) if name == kw::Empty => None, TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - - Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait | ImplTraitAssocTy => None, + Impl | ForeignMod | CrateRoot | Use | GlobalAsm | Closure | Ctor | AnonConst + | OpaqueTy => None, } } pub fn name(&self) -> DefPathDataName { use self::DefPathData::*; match *self { + TypeNs(name) if name == kw::Empty => DefPathDataName::Anon { namespace: sym::opaque }, TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => { DefPathDataName::Named(name) } @@ -422,10 +422,10 @@ impl DefPathData { ForeignMod => DefPathDataName::Anon { namespace: kw::Extern }, Use => DefPathDataName::Anon { namespace: kw::Use }, GlobalAsm => DefPathDataName::Anon { namespace: sym::global_asm }, - ClosureExpr => DefPathDataName::Anon { namespace: sym::closure }, + Closure => DefPathDataName::Anon { namespace: sym::closure }, Ctor => DefPathDataName::Anon { namespace: sym::constructor }, AnonConst => DefPathDataName::Anon { namespace: sym::constant }, - ImplTrait | ImplTraitAssocTy => DefPathDataName::Anon { namespace: sym::opaque }, + OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque }, } } } diff --git a/compiler/rustc_hir/src/diagnostic_items.rs b/compiler/rustc_hir/src/diagnostic_items.rs index 243014b00..d4d09f9a4 100644 --- a/compiler/rustc_hir/src/diagnostic_items.rs +++ b/compiler/rustc_hir/src/diagnostic_items.rs @@ -1,12 +1,13 @@ use crate::def_id::DefId; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_span::def_id::DefIdMap; use rustc_span::Symbol; #[derive(Debug, Default)] pub struct DiagnosticItems { - pub id_to_name: FxHashMap, - pub name_to_id: FxHashMap, + pub id_to_name: DefIdMap, + pub name_to_id: FxIndexMap, } impl HashStable for DiagnosticItems { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c4e44a6a4..3179fd736 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,19 +1,17 @@ use crate::def::{CtorKind, DefKind, Res}; -use crate::def_id::DefId; -pub(crate) use crate::hir_id::{HirId, ItemLocalId, OwnerId}; +use crate::def_id::{DefId, LocalDefIdMap}; +pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId}; use crate::intravisit::FnKind; use crate::LangItem; use rustc_ast as ast; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy}; -pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto}; -pub use rustc_ast::{CaptureBy, Movability, Mutability}; +pub use rustc_ast::{BinOp, BinOpKind, BindingAnnotation, BorrowKind, ByRef, CaptureBy}; +pub use rustc_ast::{ImplPolarity, IsAuto, Movability, Mutability, UnOp}; 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 +74,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 +107,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 +280,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 +355,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 +365,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() @@ -457,8 +434,6 @@ pub enum TraitBoundModifier { #[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), - // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` - LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), Outlives(&'hir Lifetime), } @@ -473,7 +448,6 @@ impl GenericBound<'_> { pub fn span(&self) -> Span { match self { GenericBound::Trait(t, ..) => t.span, - GenericBound::LangItemTrait(_, span, ..) => *span, GenericBound::Outlives(l) => l.ident.span, } } @@ -509,6 +483,7 @@ pub enum GenericParamKind<'hir> { ty: &'hir Ty<'hir>, /// Optional default value for the const generic param default: Option, + is_host_effect: bool, }, } @@ -589,14 +564,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 +646,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 +779,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 +836,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. @@ -906,12 +873,12 @@ pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, /// Map from each nested owner to its parent's local id. - pub parenting: FxHashMap, + pub parenting: LocalDefIdMap, /// Collected attributes of the HIR nodes. pub attrs: AttributeMap<'hir>, /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. - pub trait_map: FxHashMap>, + pub trait_map: ItemLocalMap>, } impl<'tcx> OwnerInfo<'tcx> { @@ -1032,7 +999,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { - Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true, + Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true, Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it), Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)), TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)), @@ -1059,7 +1026,7 @@ impl<'hir> Pat<'hir> { use PatKind::*; match self.kind { - Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {} + Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {} Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it), Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)), TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)), @@ -1085,6 +1052,23 @@ impl<'hir> Pat<'hir> { true }) } + + /// Whether this a never pattern. + pub fn is_never_pattern(&self) -> bool { + let mut is_never_pattern = false; + self.walk(|pat| match &pat.kind { + PatKind::Never => { + is_never_pattern = true; + false + } + PatKind::Or(s) => { + is_never_pattern = s.iter().all(|p| p.is_never_pattern()); + false + } + _ => true, + }); + is_never_pattern + } } /// A single field in a struct pattern. @@ -1172,6 +1156,9 @@ pub enum PatKind<'hir> { /// Invariant: `pats.len() >= 2`. Or(&'hir [Pat<'hir>]), + /// A never pattern `!`. + Never, + /// A path pattern for a unit struct/variant or a (maybe-associated) constant. Path(QPath<'hir>), @@ -1204,159 +1191,6 @@ pub enum PatKind<'hir> { Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]), } -#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)] -pub enum BinOpKind { - /// The `+` operator (addition). - Add, - /// The `-` operator (subtraction). - Sub, - /// The `*` operator (multiplication). - Mul, - /// The `/` operator (division). - Div, - /// The `%` operator (modulus). - Rem, - /// The `&&` operator (logical and). - And, - /// The `||` operator (logical or). - Or, - /// The `^` operator (bitwise xor). - BitXor, - /// The `&` operator (bitwise and). - BitAnd, - /// The `|` operator (bitwise or). - BitOr, - /// The `<<` operator (shift left). - Shl, - /// The `>>` operator (shift right). - Shr, - /// The `==` operator (equality). - Eq, - /// The `<` operator (less than). - Lt, - /// The `<=` operator (less than or equal to). - Le, - /// The `!=` operator (not equal to). - Ne, - /// The `>=` operator (greater than or equal to). - Ge, - /// The `>` operator (greater than). - Gt, -} - -impl BinOpKind { - pub fn as_str(self) -> &'static str { - match self { - BinOpKind::Add => "+", - BinOpKind::Sub => "-", - BinOpKind::Mul => "*", - BinOpKind::Div => "/", - BinOpKind::Rem => "%", - BinOpKind::And => "&&", - BinOpKind::Or => "||", - BinOpKind::BitXor => "^", - BinOpKind::BitAnd => "&", - BinOpKind::BitOr => "|", - BinOpKind::Shl => "<<", - BinOpKind::Shr => ">>", - BinOpKind::Eq => "==", - BinOpKind::Lt => "<", - BinOpKind::Le => "<=", - BinOpKind::Ne => "!=", - BinOpKind::Ge => ">=", - BinOpKind::Gt => ">", - } - } - - pub fn is_lazy(self) -> bool { - 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 - | BinOpKind::Lt - | BinOpKind::Le - | BinOpKind::Ne - | BinOpKind::Gt - | BinOpKind::Ge => true, - BinOpKind::And - | BinOpKind::Or - | BinOpKind::Add - | BinOpKind::Sub - | BinOpKind::Mul - | BinOpKind::Div - | BinOpKind::Rem - | BinOpKind::BitXor - | BinOpKind::BitAnd - | BinOpKind::BitOr - | BinOpKind::Shl - | BinOpKind::Shr => false, - } - } - - /// Returns `true` if the binary operator takes its arguments by value. - pub fn is_by_value(self) -> bool { - !self.is_comparison() - } -} - -impl Into for BinOpKind { - fn into(self) -> ast::BinOpKind { - match self { - BinOpKind::Add => ast::BinOpKind::Add, - BinOpKind::Sub => ast::BinOpKind::Sub, - BinOpKind::Mul => ast::BinOpKind::Mul, - BinOpKind::Div => ast::BinOpKind::Div, - BinOpKind::Rem => ast::BinOpKind::Rem, - BinOpKind::And => ast::BinOpKind::And, - BinOpKind::Or => ast::BinOpKind::Or, - BinOpKind::BitXor => ast::BinOpKind::BitXor, - BinOpKind::BitAnd => ast::BinOpKind::BitAnd, - BinOpKind::BitOr => ast::BinOpKind::BitOr, - BinOpKind::Shl => ast::BinOpKind::Shl, - BinOpKind::Shr => ast::BinOpKind::Shr, - BinOpKind::Eq => ast::BinOpKind::Eq, - BinOpKind::Lt => ast::BinOpKind::Lt, - BinOpKind::Le => ast::BinOpKind::Le, - BinOpKind::Ne => ast::BinOpKind::Ne, - BinOpKind::Ge => ast::BinOpKind::Ge, - BinOpKind::Gt => ast::BinOpKind::Gt, - } - } -} - -pub type BinOp = Spanned; - -#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)] -pub enum UnOp { - /// The `*` operator (dereferencing). - Deref, - /// The `!` operator (logical negation). - Not, - /// The `-` operator (negation). - Neg, -} - -impl UnOp { - pub fn as_str(self) -> &'static str { - match self { - Self::Deref => "*", - Self::Not => "!", - Self::Neg => "-", - } - } - - /// Returns `true` if the unary operator takes its argument by value. - pub fn is_by_value(self) -> bool { - matches!(self, Self::Neg | Self::Not) - } -} - /// A statement. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Stmt<'hir> { @@ -1516,15 +1350,18 @@ 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. + /// An explicit `async` block or the body of an `async` function. Async(CoroutineSource), /// An explicit `gen` block or the body of a `gen` function. Gen(CoroutineSource), + /// An explicit `async gen` block or the body of an `async gen` function, + /// which is able to both `yield` and `.await`. + AsyncGen(CoroutineSource), + /// A coroutine literal created via a `yield` inside a closure. Coroutine, } @@ -1549,6 +1386,14 @@ impl fmt::Display for CoroutineKind { } k.fmt(f) } + CoroutineKind::AsyncGen(k) => { + if f.alternate() { + f.write_str("`async gen` ")?; + } else { + f.write_str("async gen ")? + } + k.fmt(f) + } } } } @@ -1558,8 +1403,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, @@ -1712,7 +1556,7 @@ impl Expr<'_> { ExprKind::Call(..) => ExprPrecedence::Call, ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, ExprKind::Tup(_) => ExprPrecedence::Tup, - ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()), + ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), ExprKind::Unary(..) => ExprPrecedence::Unary, ExprKind::Lit(_) => ExprPrecedence::Lit, ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, @@ -1852,11 +1696,9 @@ impl Expr<'_> { // them being used only for its side-effects. base.can_have_side_effects() } - ExprKind::Struct(_, fields, init) => fields - .iter() - .map(|field| field.expr) - .chain(init.into_iter()) - .any(|e| e.can_have_side_effects()), + ExprKind::Struct(_, fields, init) => { + fields.iter().map(|field| field.expr).chain(init).any(|e| e.can_have_side_effects()) + } ExprKind::Array(args) | ExprKind::Tup(args) @@ -2094,8 +1936,8 @@ pub enum QPath<'hir> { /// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`. TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>), - /// Reference to a `#[lang = "foo"]` item. `HirId` of the inner expr. - LangItem(LangItem, Span, Option), + /// Reference to a `#[lang = "foo"]` item. + LangItem(LangItem, Span), } impl<'hir> QPath<'hir> { @@ -2104,7 +1946,7 @@ impl<'hir> QPath<'hir> { match *self { QPath::Resolved(_, path) => path.span, QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span), - QPath::LangItem(_, span, _) => span, + QPath::LangItem(_, span) => span, } } @@ -2114,17 +1956,7 @@ impl<'hir> QPath<'hir> { match *self { QPath::Resolved(_, path) => path.span, QPath::TypeRelative(qself, _) => qself.span, - 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, + QPath::LangItem(_, span) => span, } } } @@ -2153,8 +1985,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, @@ -2256,17 +2087,6 @@ impl fmt::Display for YieldSource { } } -impl From for YieldSource { - fn from(kind: CoroutineKind) -> Self { - match kind { - // Guess based on the kind of the current coroutine. - CoroutineKind::Coroutine => Self::Yield, - CoroutineKind::Async(_) => Self::Await { expr: None }, - CoroutineKind::Gen(_) => Self::Yield, - } - } -} - // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. #[derive(Debug, Clone, Copy, HashStable_Generic)] @@ -2314,6 +2134,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 { @@ -2325,30 +2174,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 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_methods_self_kind! { + expect_const, (&'hir Ty<'hir>, Option), + TraitItemKind::Const(ty, body), (ty, *body); - /// 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); } } @@ -2413,30 +2247,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; } } @@ -2452,9 +2266,6 @@ pub enum ImplItemKind<'hir> { Type(&'hir Ty<'hir>), } -/// The name of the associated type for `Fn` return types. -pub const FN_OUTPUT_NAME: Symbol = sym::Output; - /// Bind a type to an associated type (i.e., `A = Foo`). /// /// Bindings like `A: Debug` are represented as a special type `A = @@ -2579,8 +2390,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 +2670,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, @@ -3000,7 +2809,7 @@ impl TraitRef<'_> { match self.path.res { Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did), Res::Err => None, - _ => unreachable!(), + res => panic!("{res:?} did not resolve to a trait or trait alias"), } } } @@ -3039,7 +2848,11 @@ pub enum VariantData<'hir> { /// A struct variant. /// /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. - Struct(&'hir [FieldDef<'hir>], /* recovered */ bool), + Struct { + fields: &'hir [FieldDef<'hir>], + // FIXME: investigate making this a `Option` + recovered: bool, + }, /// A tuple variant. /// /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. @@ -3054,7 +2867,7 @@ impl<'hir> VariantData<'hir> { /// Return the fields of this variant. pub fn fields(&self) -> &'hir [FieldDef<'hir>] { match *self { - VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => fields, + VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields, _ => &[], } } @@ -3063,7 +2876,7 @@ impl<'hir> VariantData<'hir> { match *self { VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)), VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)), - VariantData::Struct(..) => None, + VariantData::Struct { .. } => None, } } @@ -3124,134 +2937,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); + + expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>), + ItemKind::TraitAlias(gen, bounds), (gen, bounds); - #[track_caller] - fn expect_failed(&self, expected: &'static str) -> ! { - panic!("expected {expected} item, found {self:?}") + expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp; } } @@ -3280,8 +3010,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, @@ -3624,32 +3353,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; } } @@ -3902,196 +3610,33 @@ 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> { - 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; } } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 34c615779..d339075c1 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, @@ -156,6 +154,8 @@ rustc_index::newtype_index! { /// an "item-like" to something else can be implemented by a `Vec` instead of a /// tree or hash map. #[derive(HashStable_Generic)] + #[encodable] + #[orderable] pub struct ItemLocalId {} } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 8a6728559..67e058a32 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -660,7 +660,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) { walk_list!(visitor, visit_expr, lower_bound); walk_list!(visitor, visit_expr, upper_bound); } - PatKind::Wild => (), + PatKind::Never | PatKind::Wild => (), PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => { walk_list!(visitor, visit_pat, prepatterns); walk_list!(visitor, visit_pat, slice_pattern); @@ -874,7 +874,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default), - GenericParamKind::Const { ref ty, ref default } => { + GenericParamKind::Const { ref ty, ref default, is_host_effect: _ } => { visitor.visit_ty(ty); if let Some(ref default) = default { visitor.visit_const_param_default(param.hir_id, default); @@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB GenericBound::Trait(ref typ, _modifier) => { visitor.visit_poly_trait_ref(typ); } - GenericBound::LangItemTrait(_, _span, hir_id, args) => { - visitor.visit_id(hir_id); - visitor.visit_generic_args(args); - } GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), } } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 1d1a1ee88..b0b53bb74 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -212,6 +212,7 @@ language_item_table! { Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0); Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); + AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0); CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None; Coroutine, sym::coroutine, coroutine_trait, Target::Trait, GenericRequirement::Minimum(1); Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; @@ -233,7 +234,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; @@ -294,6 +295,10 @@ language_item_table! { PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None; PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None; + AsyncGenReady, sym::AsyncGenReady, async_gen_ready, Target::Method(MethodKind::Inherent), GenericRequirement::Exact(1); + AsyncGenPending, sym::AsyncGenPending, async_gen_pending, Target::AssocConst, GenericRequirement::Exact(1); + AsyncGenFinished, sym::AsyncGenFinished, async_gen_finished, Target::AssocConst, GenericRequirement::Exact(1); + // FIXME(swatinem): the following lang items are used for async lowering and // should become obsolete eventually. ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 094d5b1e7..87de3c087 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)] diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index 838c123f8..e60503271 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -1,7 +1,6 @@ use crate::def::{CtorOf, DefKind, Res}; -use crate::def_id::DefId; +use crate::def_id::{DefId, DefIdSet}; use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind}; -use rustc_data_structures::fx::FxHashSet; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -114,9 +113,9 @@ impl hir::Pat<'_> { } _ => true, }); - // We remove duplicates by inserting into a `FxHashSet` to avoid re-ordering + // We remove duplicates by inserting into a hash set to avoid re-ordering // the bounds - let mut duplicates = FxHashSet::default(); + let mut duplicates = DefIdSet::default(); variants.retain(|def_id| duplicates.insert(*def_id)); variants } diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 0d65ddb56..8948a03e4 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -67,6 +67,42 @@ impl Display for Target { } impl Target { + pub fn is_associated_item(self) -> bool { + match self { + Target::AssocConst | Target::AssocTy | Target::Method(_) => true, + Target::ExternCrate + | Target::Use + | Target::Static + | Target::Const + | Target::Fn + | Target::Closure + | Target::Mod + | Target::ForeignMod + | Target::GlobalAsm + | Target::TyAlias + | Target::OpaqueTy + | Target::Enum + | Target::Variant + | Target::Struct + | Target::Field + | Target::Union + | Target::Trait + | Target::TraitAlias + | Target::Impl + | Target::Expression + | Target::Statement + | Target::Arm + | Target::ForeignFn + | Target::ForeignStatic + | Target::ForeignTy + | Target::GenericParam(_) + | Target::MacroDef + | Target::Param + | Target::PatField + | Target::ExprField => false, + } + } + pub fn from_item(item: &Item<'_>) -> Target { match item.kind { ItemKind::ExternCrate(..) => Target::ExternCrate, -- cgit v1.2.3