diff options
Diffstat (limited to 'compiler/rustc_hir/src/hir.rs')
-rw-r--r-- | compiler/rustc_hir/src/hir.rs | 219 |
1 files changed, 131 insertions, 88 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 617433a98..a8436ea64 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -7,7 +7,7 @@ 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::{BorrowKind, ImplPolarity, IsAuto}; +pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto}; pub use rustc_ast::{CaptureBy, Movability, Mutability}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_data_structures::fingerprint::Fingerprint; @@ -139,11 +139,10 @@ impl LifetimeName { match self { LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, - // It might seem surprising that `Fresh` counts as - // *not* elided -- but this is because, as far as the code - // in the compiler is concerned -- `Fresh` variants act - // equivalently to "some fresh name". They correspond to - // early-bound regions on an impl, in other words. + // It might seem surprising that `Fresh` counts as not *elided* + // -- but this is because, as far as the code in the compiler is + // concerned -- `Fresh` variants act equivalently to "some fresh name". + // They correspond to early-bound regions on an impl, in other words. LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, } } @@ -202,13 +201,8 @@ impl Path<'_> { pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, - // `id` and `res` are optional. We currently only use these in save-analysis, - // any path segments without these will not have save-analysis info and - // therefore will not have 'jump to def' in IDEs, but otherwise will not be - // affected. (In general, we don't bother to get the defs for synthesized - // segments, only for segments which have come from the AST). - pub hir_id: Option<HirId>, - pub res: Option<Res>, + pub hir_id: HirId, + pub res: Res, /// Type/lifetime parameters attached to this path. They come in /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that @@ -226,12 +220,12 @@ pub struct PathSegment<'hir> { impl<'hir> PathSegment<'hir> { /// Converts an identifier to the corresponding segment. - pub fn from_ident(ident: Ident) -> PathSegment<'hir> { - PathSegment { ident, hir_id: None, res: None, infer_args: true, args: None } + pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> { + PathSegment { ident, hir_id, res, infer_args: true, args: None } } pub fn invalid() -> Self { - Self::from_ident(Ident::empty()) + Self::new(Ident::empty(), HirId::INVALID, Res::Err) } pub fn args(&self) -> &GenericArgs<'hir> { @@ -264,8 +258,8 @@ impl InferArg { #[derive(Debug, HashStable_Generic)] pub enum GenericArg<'hir> { - Lifetime(Lifetime), - Type(Ty<'hir>), + Lifetime(&'hir Lifetime), + Type(&'hir Ty<'hir>), Const(ConstArg), Infer(InferArg), } @@ -280,7 +274,7 @@ impl GenericArg<'_> { } } - pub fn id(&self) -> HirId { + pub fn hir_id(&self) -> HirId { match self { GenericArg::Lifetime(l) => l.hir_id, GenericArg::Type(t) => t.hir_id, @@ -305,9 +299,9 @@ impl GenericArg<'_> { pub fn to_ord(&self) -> ast::ParamKindOrd { match self { GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime, - GenericArg::Type(_) => ast::ParamKindOrd::Type, - GenericArg::Const(_) => ast::ParamKindOrd::Const, - GenericArg::Infer(_) => ast::ParamKindOrd::Infer, + GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => { + ast::ParamKindOrd::TypeOrConst + } } } @@ -435,7 +429,7 @@ pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), - Outlives(Lifetime), + Outlives(&'hir Lifetime), } impl GenericBound<'_> { @@ -581,8 +575,7 @@ impl<'hir> Generics<'hir> { if self.has_where_clause_predicates { self.predicates .iter() - .filter(|p| p.in_where_clause()) - .last() + .rfind(|&p| p.in_where_clause()) .map_or(end, |p| p.span()) .shrink_to_hi() .to(end) @@ -761,7 +754,7 @@ impl<'hir> WhereBoundPredicate<'hir> { pub struct WhereRegionPredicate<'hir> { pub span: Span, pub in_where_clause: bool, - pub lifetime: Lifetime, + pub lifetime: &'hir Lifetime, pub bounds: GenericBounds<'hir>, } @@ -778,7 +771,6 @@ impl<'hir> WhereRegionPredicate<'hir> { /// An equality predicate (e.g., `T = int`); currently unsupported. #[derive(Debug, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { - pub hir_id: HirId, pub span: Span, pub lhs_ty: &'hir Ty<'hir>, pub rhs_ty: &'hir Ty<'hir>, @@ -841,7 +833,16 @@ impl<'tcx> OwnerNodes<'tcx> { impl fmt::Debug for OwnerNodes<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnerNodes") + // Do not print all the pointers to all the nodes, as it would be unreadable. .field("node", &self.nodes[ItemLocalId::from_u32(0)]) + .field( + "parents", + &self + .nodes + .iter_enumerated() + .map(|(id, parented_node)| (id, parented_node.as_ref().map(|node| node.parent))) + .collect::<Vec<_>>(), + ) .field("bodies", &self.bodies) .field("local_id_to_def_id", &self.local_id_to_def_id) .field("hash_without_bodies", &self.hash_without_bodies) @@ -1050,30 +1051,6 @@ pub struct PatField<'hir> { pub span: Span, } -/// Explicit binding annotations given in the HIR for a binding. Note -/// that this is not the final binding *mode* that we infer after type -/// inference. -#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] -pub enum BindingAnnotation { - /// No binding annotation given: this means that the final binding mode - /// will depend on whether we have skipped through a `&` reference - /// when matching. For example, the `x` in `Some(x)` will have binding - /// mode `None`; if you do `let Some(x) = &Some(22)`, it will - /// ultimately be inferred to be by-reference. - /// - /// Note that implicit reference skipping is not implemented yet (#42640). - Unannotated, - - /// Annotated with `mut x` -- could be either ref or not, similar to `None`. - Mutable, - - /// Annotated as `ref`, like `ref x` - Ref, - - /// Annotated as `ref mut x`. - RefMut, -} - #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] pub enum RangeEnd { Included, @@ -1089,6 +1066,35 @@ impl fmt::Display for RangeEnd { } } +// Equivalent to `Option<usize>`. That type takes up 16 bytes on 64-bit, but +// this type only takes up 4 bytes, at the cost of being restricted to a +// maximum value of `u32::MAX - 1`. In practice, this is more than enough. +#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)] +pub struct DotDotPos(u32); + +impl DotDotPos { + // Panics if n >= u32::MAX. + pub fn new(n: Option<usize>) -> Self { + match n { + Some(n) => { + assert!(n < u32::MAX as usize); + Self(n as u32) + } + None => Self(u32::MAX), + } + } + + pub fn as_opt_usize(&self) -> Option<usize> { + if self.0 == u32::MAX { None } else { Some(self.0 as usize) } + } +} + +impl fmt::Debug for DotDotPos { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.as_opt_usize().fmt(f) + } +} + #[derive(Debug, HashStable_Generic)] pub enum PatKind<'hir> { /// Represents a wildcard pattern (i.e., `_`). @@ -1105,9 +1111,9 @@ pub enum PatKind<'hir> { Struct(QPath<'hir>, &'hir [PatField<'hir>], bool), /// A tuple struct/variant pattern `Variant(x, y, .., z)`. - /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. + /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position. /// `0 <= position <= subpats.len()` - TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], Option<usize>), + TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. @@ -1119,7 +1125,7 @@ pub enum PatKind<'hir> { /// A tuple pattern (e.g., `(a, b)`). /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. /// `0 <= position <= subpats.len()` - Tuple(&'hir [Pat<'hir>], Option<usize>), + Tuple(&'hir [Pat<'hir>], DotDotPos), /// A `box` pattern. Box(&'hir Pat<'hir>), @@ -1322,7 +1328,7 @@ pub enum StmtKind<'hir> { Semi(&'hir Expr<'hir>), } -/// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`). +/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`). #[derive(Debug, HashStable_Generic)] pub struct Local<'hir> { pub pat: &'hir Pat<'hir>, @@ -1439,7 +1445,7 @@ pub struct BodyId { #[derive(Debug, HashStable_Generic)] pub struct Body<'hir> { pub params: &'hir [Param<'hir>], - pub value: Expr<'hir>, + pub value: &'hir Expr<'hir>, pub generator_kind: Option<GeneratorKind>, } @@ -1626,7 +1632,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug)] +#[derive(Debug, HashStable_Generic)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1882,11 +1888,11 @@ pub enum ExprKind<'hir> { /// /// The `PathSegment` represents the method name and its generic arguments /// (within the angle brackets). - /// The first element of the `&[Expr]` is the expression that evaluates + /// The `&Expr` is the expression that evaluates /// to the object on which the method is being called on (the receiver), - /// and the remaining elements are the rest of the arguments. + /// and the `&[Expr]` is the rest of the arguments. /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as - /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d], span)`. + /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d], span)`. /// The final `Span` represents the span of the function and arguments /// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)` /// @@ -1894,7 +1900,7 @@ pub enum ExprKind<'hir> { /// the `hir_id` of the `MethodCall` node itself. /// /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id - MethodCall(&'hir PathSegment<'hir>, &'hir [Expr<'hir>], Span), + MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span), /// A tuple (e.g., `(a, b, c, d)`). Tup(&'hir [Expr<'hir>]), /// A binary operation (e.g., `a + b`, `a * b`). @@ -2380,7 +2386,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug)] +#[derive(Debug, HashStable_Generic)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2402,6 +2408,14 @@ impl<'hir> Ty<'hir> { _ => None, } } + + pub fn peel_refs(&self) -> &Self { + let mut final_ty = self; + while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind { + final_ty = &ty; + } + final_ty + } } /// Not represented directly in the AST; referred to by name through a `ty_path`. @@ -2506,6 +2520,7 @@ pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, pub origin: OpaqueTyOrigin, + pub in_trait: bool, } /// From whence the opaque type came. @@ -2529,7 +2544,7 @@ pub enum TyKind<'hir> { /// A raw pointer (i.e., `*const T` or `*mut T`). Ptr(MutTy<'hir>), /// A reference (i.e., `&'a T` or `&'a mut T`). - Rptr(Lifetime, MutTy<'hir>), + Rptr(&'hir Lifetime, MutTy<'hir>), /// A bare function (e.g., `fn(usize) -> bool`). BareFn(&'hir BareFnTy<'hir>), /// The never type (`!`). @@ -2545,10 +2560,12 @@ pub enum TyKind<'hir> { /// /// The generic argument list contains the lifetimes (and in the future /// possibly parameters) that are actually bound on the `impl Trait`. - OpaqueDef(ItemId, &'hir [GenericArg<'hir>]), + /// + /// The last parameter specifies whether this opaque appears in a trait definition. + OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. - TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime, TraitObjectSyntax), + TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax), /// Unused for now. Typeof(AnonConst), /// `TyKind::Infer` means the type should be inferred instead of it having been @@ -2562,23 +2579,23 @@ pub enum TyKind<'hir> { pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, - expr: Expr<'hir>, + expr: &'hir Expr<'hir>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, - expr: Option<Expr<'hir>>, + expr: Option<&'hir Expr<'hir>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, - expr: Expr<'hir>, + expr: &'hir Expr<'hir>, }, SplitInOut { reg: InlineAsmRegOrRegClass, late: bool, - in_expr: Expr<'hir>, - out_expr: Option<Expr<'hir>>, + in_expr: &'hir Expr<'hir>, + out_expr: Option<&'hir Expr<'hir>>, }, Const { anon_const: AnonConst, @@ -2643,7 +2660,7 @@ pub struct FnDecl<'hir> { } /// Represents what type of implicit self a function has, if any. -#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum ImplicitSelfKind { /// Represents a `fn x(self);`. Imm, @@ -2992,7 +3009,7 @@ pub enum ItemKind<'hir> { /// A MBE macro definition (`macro_rules!` or `macro`). Macro(ast::MacroDef, MacroKind), /// A module. - Mod(Mod<'hir>), + Mod(&'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. ForeignMod { abi: Abi, items: &'hir [ForeignItemRef] }, /// Module-level inline assembly (from `global_asm!`). @@ -3217,7 +3234,7 @@ impl<'hir> OwnerNode<'hir> { } } - pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> { + pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> { match self { OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) @@ -3332,12 +3349,14 @@ pub enum Node<'hir> { Field(&'hir FieldDef<'hir>), AnonConst(&'hir AnonConst), Expr(&'hir Expr<'hir>), + ExprField(&'hir ExprField<'hir>), Stmt(&'hir Stmt<'hir>), PathSegment(&'hir PathSegment<'hir>), Ty(&'hir Ty<'hir>), TypeBinding(&'hir TypeBinding<'hir>), TraitRef(&'hir TraitRef<'hir>), Pat(&'hir Pat<'hir>), + PatField(&'hir PatField<'hir>), Arm(&'hir Arm<'hir>), Block(&'hir Block<'hir>), Local(&'hir Local<'hir>), @@ -3388,6 +3407,8 @@ impl<'hir> Node<'hir> { | Node::Block(..) | Node::Ctor(..) | Node::Pat(..) + | Node::PatField(..) + | Node::ExprField(..) | Node::Arm(..) | Node::Local(..) | Node::Crate(..) @@ -3397,19 +3418,20 @@ impl<'hir> Node<'hir> { } } - pub fn fn_decl(&self) -> Option<&'hir FnDecl<'hir>> { + pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl), - Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => { + Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) + | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => { Some(fn_decl) } _ => None, } } - pub fn fn_sig(&self) -> Option<&'hir FnSig<'hir>> { + pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) @@ -3491,16 +3513,37 @@ impl<'hir> Node<'hir> { mod size_asserts { use super::*; // These are in alphabetical order, which is easy to maintain. - rustc_data_structures::static_assert_size!(Block<'static>, 48); - rustc_data_structures::static_assert_size!(Expr<'static>, 56); - rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72); - rustc_data_structures::static_assert_size!(GenericBound<'_>, 48); - rustc_data_structures::static_assert_size!(Generics<'static>, 56); - rustc_data_structures::static_assert_size!(ImplItem<'static>, 88); - rustc_data_structures::static_assert_size!(Impl<'static>, 80); - rustc_data_structures::static_assert_size!(Item<'static>, 80); - rustc_data_structures::static_assert_size!(Pat<'static>, 88); - rustc_data_structures::static_assert_size!(QPath<'static>, 24); - rustc_data_structures::static_assert_size!(TraitItem<'static>, 96); - rustc_data_structures::static_assert_size!(Ty<'static>, 72); + static_assert_size!(Block<'_>, 48); + static_assert_size!(Body<'_>, 32); + static_assert_size!(Expr<'_>, 64); + static_assert_size!(ExprKind<'_>, 48); + static_assert_size!(FnDecl<'_>, 40); + static_assert_size!(ForeignItem<'_>, 72); + static_assert_size!(ForeignItemKind<'_>, 40); + #[cfg(not(bootstrap))] + static_assert_size!(GenericArg<'_>, 24); + static_assert_size!(GenericBound<'_>, 48); + static_assert_size!(Generics<'_>, 56); + static_assert_size!(Impl<'_>, 80); + #[cfg(not(bootstrap))] + static_assert_size!(ImplItem<'_>, 80); + #[cfg(not(bootstrap))] + static_assert_size!(ImplItemKind<'_>, 32); + static_assert_size!(Item<'_>, 80); + static_assert_size!(ItemKind<'_>, 48); + static_assert_size!(Local<'_>, 64); + static_assert_size!(Param<'_>, 32); + static_assert_size!(Pat<'_>, 72); + static_assert_size!(PatKind<'_>, 48); + static_assert_size!(Path<'_>, 48); + static_assert_size!(PathSegment<'_>, 56); + static_assert_size!(QPath<'_>, 24); + static_assert_size!(Stmt<'_>, 32); + static_assert_size!(StmtKind<'_>, 16); + #[cfg(not(bootstrap))] + static_assert_size!(TraitItem<'_>, 88); + #[cfg(not(bootstrap))] + static_assert_size!(TraitItemKind<'_>, 48); + static_assert_size!(Ty<'_>, 48); + static_assert_size!(TyKind<'_>, 32); } |