From 4547b622d8d29df964fa2914213088b148c498fc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:32 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_hir/src/arena.rs | 1 + compiler/rustc_hir/src/def.rs | 22 +- compiler/rustc_hir/src/definitions.rs | 8 +- compiler/rustc_hir/src/hir.rs | 223 +++++---- compiler/rustc_hir/src/hir_id.rs | 22 +- compiler/rustc_hir/src/intravisit.rs | 790 +++++++++++++++--------------- compiler/rustc_hir/src/lang_items.rs | 230 +++++---- compiler/rustc_hir/src/lib.rs | 3 +- compiler/rustc_hir/src/pat_util.rs | 5 +- compiler/rustc_hir/src/tests.rs | 38 +- compiler/rustc_hir/src/weak_lang_items.rs | 59 +-- 11 files changed, 730 insertions(+), 671 deletions(-) (limited to 'compiler/rustc_hir') diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 44335b7f4..c89e7eb75 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -39,6 +39,7 @@ macro_rules! arena_types { [] param: rustc_hir::Param<'tcx>, [] pat: rustc_hir::Pat<'tcx>, [] path: rustc_hir::Path<'tcx>, + [] use_path: rustc_hir::UsePath<'tcx>, [] path_segment: rustc_hir::PathSegment<'tcx>, [] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>, [] qpath: rustc_hir::QPath<'tcx>, diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 4ef4aad90..149cf4ece 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -28,8 +28,6 @@ pub enum CtorKind { Fn, /// Constructor constant automatically created by a unit struct/variant. Const, - /// Unusable name in value namespace created by a struct variant. - Fictive, } /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`. @@ -132,13 +130,9 @@ impl DefKind { DefKind::Variant => "variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant", - DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant", DefKind::Struct => "struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", - DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => { - panic!("impossible struct constructor") - } DefKind::OpaqueTy => "opaque type", DefKind::ImplTraitPlaceholder => "opaque type in trait", DefKind::TyAlias => "type alias", @@ -562,19 +556,11 @@ impl PerNS> { } impl CtorKind { - pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { - match *vdata { - ast::VariantData::Tuple(..) => CtorKind::Fn, - ast::VariantData::Unit(..) => CtorKind::Const, - ast::VariantData::Struct(..) => CtorKind::Fictive, - } - } - - pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind { + pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> { match *vdata { - hir::VariantData::Tuple(..) => CtorKind::Fn, - hir::VariantData::Unit(..) => CtorKind::Const, - hir::VariantData::Struct(..) => CtorKind::Fictive, + ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)), + ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)), + ast::VariantData::Struct(..) => None, } } } diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index d85ac960f..dd37efb69 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -368,10 +368,6 @@ impl Definitions { LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) } } - pub fn iter_local_def_id(&self) -> impl Iterator + '_ { - self.table.def_path_hashes.indices().map(|local_def_index| LocalDefId { local_def_index }) - } - #[inline(always)] pub fn local_def_path_hash_to_def_id( &self, @@ -389,6 +385,10 @@ impl Definitions { pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap { &self.table.def_path_hash_to_index } + + pub fn num_definitions(&self) -> usize { + self.table.def_path_hashes.len() + } } #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ef00c1ffc..8bc022e1e 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -29,15 +29,16 @@ use std::fmt; #[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)] pub struct Lifetime { pub hir_id: HirId, - pub span: Span, /// Either "`'a`", referring to a named lifetime definition, - /// or "``" (i.e., `kw::Empty`), for elision placeholders. + /// `'_` referring to an anonymous lifetime (either explicitly `'_` or `&type`), + /// or "``" (i.e., `kw::Empty`) when appearing in path. /// - /// HIR lowering inserts these placeholders in type paths that - /// refer to type definitions needing lifetime parameters, - /// `&T` and `&mut T`, and trait objects without `... + 'a`. - pub name: LifetimeName, + /// See `Lifetime::suggestion_position` for practical use. + pub ident: Ident, + + /// Semantics of this lifetime. + pub res: LifetimeName, } #[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)] @@ -88,7 +89,7 @@ impl ParamName { #[derive(HashStable_Generic)] pub enum LifetimeName { /// User-given names or fresh (synthetic) names. - Param(LocalDefId, ParamName), + Param(LocalDefId), /// Implicit lifetime in a context like `dyn Foo`. This is /// distinguished from implicit lifetimes elsewhere because the @@ -116,25 +117,6 @@ pub enum LifetimeName { } impl LifetimeName { - pub fn ident(&self) -> Ident { - match *self { - LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(), - LifetimeName::Infer => Ident::with_dummy_span(kw::UnderscoreLifetime), - LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), - LifetimeName::Param(_, param_name) => param_name.ident(), - } - } - - pub fn is_anonymous(&self) -> bool { - match *self { - LifetimeName::ImplicitObjectLifetimeDefault - | LifetimeName::Infer - | LifetimeName::Param(_, ParamName::Fresh) - | LifetimeName::Error => true, - LifetimeName::Static | LifetimeName::Param(..) => false, - } - } - pub fn is_elided(&self) -> bool { match self { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, @@ -146,34 +128,54 @@ impl LifetimeName { LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, } } - - fn is_static(&self) -> bool { - self == &LifetimeName::Static - } - - pub fn normalize_to_macros_2_0(&self) -> LifetimeName { - match *self { - LifetimeName::Param(def_id, param_name) => { - LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0()) - } - lifetime_name => lifetime_name, - } - } } impl fmt::Display for Lifetime { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.name.ident().fmt(f) + if self.ident.name != kw::Empty { self.ident.name.fmt(f) } else { "'_".fmt(f) } } } +pub enum LifetimeSuggestionPosition { + /// The user wrote `'a` or `'_`. + Normal, + /// The user wrote `&type` or `&mut type`. + Ampersand, + /// The user wrote `Path` and omitted the `<'_>`. + ElidedPath, + /// The user wrote `Path`, and omitted the `'_,`. + ElidedPathArgument, + /// The user wrote `dyn Trait` and omitted the `+ '_`. + ObjectDefault, +} + impl Lifetime { pub fn is_elided(&self) -> bool { - self.name.is_elided() + self.res.is_elided() + } + + pub fn is_anonymous(&self) -> bool { + self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime + } + + pub fn suggestion_position(&self) -> (LifetimeSuggestionPosition, Span) { + if self.ident.name == kw::Empty { + if self.ident.span.is_empty() { + (LifetimeSuggestionPosition::ElidedPathArgument, self.ident.span) + } else { + (LifetimeSuggestionPosition::ElidedPath, self.ident.span.shrink_to_hi()) + } + } else if self.res == LifetimeName::ImplicitObjectLifetimeDefault { + (LifetimeSuggestionPosition::ObjectDefault, self.ident.span) + } else if self.ident.span.is_empty() { + (LifetimeSuggestionPosition::Ampersand, self.ident.span) + } else { + (LifetimeSuggestionPosition::Normal, self.ident.span) + } } pub fn is_static(&self) -> bool { - self.name.is_static() + self.res == LifetimeName::Static } } @@ -181,14 +183,17 @@ impl Lifetime { /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. #[derive(Debug, HashStable_Generic)] -pub struct Path<'hir> { +pub struct Path<'hir, R = Res> { pub span: Span, /// The resolution for the path. - pub res: Res, + pub res: R, /// The segments in the path: the things separated by `::`. pub segments: &'hir [PathSegment<'hir>], } +/// Up to three resolutions for type, value and macro namespaces. +pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>; + impl Path<'_> { pub fn is_global(&self) -> bool { !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot @@ -267,7 +272,7 @@ pub enum GenericArg<'hir> { impl GenericArg<'_> { pub fn span(&self) -> Span { match self { - GenericArg::Lifetime(l) => l.span, + GenericArg::Lifetime(l) => l.ident.span, GenericArg::Type(t) => t.span, GenericArg::Const(c) => c.span, GenericArg::Infer(i) => i.span, @@ -284,7 +289,7 @@ impl GenericArg<'_> { } pub fn is_synthetic(&self) -> bool { - matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::empty()) + matches!(self, GenericArg::Lifetime(lifetime) if lifetime.ident == Ident::empty()) } pub fn descr(&self) -> &'static str { @@ -388,6 +393,8 @@ impl<'hir> GenericArgs<'hir> { } #[inline] + /// This function returns the number of type and const generic params. + /// It should only be used for diagnostics. pub fn num_generic_params(&self) -> usize { self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count() } @@ -444,7 +451,7 @@ impl GenericBound<'_> { match self { GenericBound::Trait(t, ..) => t.span, GenericBound::LangItemTrait(_, span, ..) => *span, - GenericBound::Outlives(l) => l.span, + GenericBound::Outlives(l) => l.ident.span, } } } @@ -485,6 +492,7 @@ pub enum GenericParamKind<'hir> { #[derive(Debug, HashStable_Generic)] pub struct GenericParam<'hir> { pub hir_id: HirId, + pub def_id: LocalDefId, pub name: ParamName, pub span: Span, pub pure_wrt_drop: bool, @@ -556,6 +564,19 @@ impl<'hir> Generics<'hir> { } } + /// 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() + && self.span.contains(first.span) + { + // `fn foo(t: impl Trait)` + // ^ suggest `'a, ` here + Some(first.span.shrink_to_lo()) + } else { + None + } + } + /// If there are generic parameters, return where to introduce a new one. pub fn span_for_param_suggestion(&self) -> Option { if self.params.iter().any(|p| self.span.contains(p.span)) { @@ -762,10 +783,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 { - match self.lifetime.name { - LifetimeName::Param(id, _) => id == param_def_id, - _ => false, - } + self.lifetime.res == LifetimeName::Param(param_def_id) } } @@ -809,7 +827,7 @@ impl<'tcx> AttributeMap<'tcx> { pub struct OwnerNodes<'tcx> { /// Pre-computed hash of the full HIR. pub hash_including_bodies: Fingerprint, - /// Pre-computed hash of the item signature, sithout recursing into the body. + /// Pre-computed hash of the item signature, without recursing into the body. pub hash_without_bodies: Fingerprint, /// Full HIR for the current owner. // The zeroth node's parent should never be accessed: the owner's parent is computed by the @@ -919,12 +937,16 @@ pub struct Crate<'hir> { #[derive(Debug, HashStable_Generic)] pub struct Closure<'hir> { + pub def_id: LocalDefId, pub binder: ClosureBinder, pub capture_clause: CaptureBy, pub bound_generic_params: &'hir [GenericParam<'hir>], pub fn_decl: &'hir FnDecl<'hir>, pub body: BodyId, + /// The span of the declaration block: 'move |...| -> ...' pub fn_decl_span: Span, + /// The span of the argument block `|...|` + pub fn_arg_span: Option, pub movability: Option, } @@ -965,8 +987,8 @@ pub struct Pat<'hir> { pub hir_id: HirId, pub kind: PatKind<'hir>, pub span: Span, - // Whether to use default binding modes. - // At present, this is false only for destructuring assignment. + /// Whether to use default binding modes. + /// At present, this is false only for destructuring assignment. pub default_binding_modes: bool, } @@ -1074,7 +1096,7 @@ impl fmt::Display for RangeEnd { pub struct DotDotPos(u32); impl DotDotPos { - // Panics if n >= u32::MAX. + /// Panics if n >= u32::MAX. pub fn new(n: Option) -> Self { match n { Some(n) => { @@ -1510,9 +1532,9 @@ pub enum AsyncGeneratorKind { impl fmt::Display for AsyncGeneratorKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { - AsyncGeneratorKind::Block => "`async` block", - AsyncGeneratorKind::Closure => "`async` closure body", - AsyncGeneratorKind::Fn => "`async fn` body", + AsyncGeneratorKind::Block => "async block", + AsyncGeneratorKind::Closure => "async closure body", + AsyncGeneratorKind::Fn => "async fn body", }) } } @@ -1613,7 +1635,7 @@ pub enum ArrayLen { impl ArrayLen { pub fn hir_id(&self) -> HirId { match self { - &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, body: _ }) => hir_id, + &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, .. }) => hir_id, } } } @@ -1625,10 +1647,11 @@ impl ArrayLen { /// explicit discriminant values for enum variants. /// /// You can check if this anon const is a default in a const param -/// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_hir_id(..)` +/// `const N: usize = { ... }` with `tcx.hir().opt_const_param_default_param_def_id(..)` #[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)] pub struct AnonConst { pub hir_id: HirId, + pub def_id: LocalDefId, pub body: BodyId, } @@ -1677,10 +1700,10 @@ impl Expr<'_> { } } - // Whether this looks like a place expr, without checking for deref - // adjustments. - // This will return `true` in some potentially surprising cases such as - // `CONSTANT.field`. + /// Whether this looks like a place expr, without checking for deref + /// adjustments. + /// This will return `true` in some potentially surprising cases such as + /// `CONSTANT.field`. pub fn is_syntactic_place_expr(&self) -> bool { self.is_place_expr(|_| true) } @@ -1821,7 +1844,7 @@ impl Expr<'_> { } } - // To a first-order approximation, is this a pattern + /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { match &self.kind { ExprKind::Box(_) @@ -2143,11 +2166,11 @@ impl fmt::Display for LoopIdError { #[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)] pub struct Destination { - // This is `Some(_)` iff there is an explicit user-specified `label + /// This is `Some(_)` iff there is an explicit user-specified 'label pub label: Option