use rustc_macros::HashStable_Generic;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{def_id::LocalDefId, BytePos};
-use rustc_span::{MultiSpan, Span, DUMMY_SP};
+use rustc_span::{def_id::LocalDefId, BytePos, MultiSpan, Span, DUMMY_SP};
use rustc_target::asm::InlineAsmRegOrRegClass;
use rustc_target::spec::abi::Abi;
Param(ParamName),
/// User wrote nothing (e.g., the lifetime in `&u32`).
- Implicit,
+ ///
+ /// The bool indicates whether the user should have written something.
+ Implicit(bool),
/// Implicit lifetime in a context like `dyn Foo`. This is
/// distinguished from implicit lifetimes elsewhere because the
pub fn ident(&self) -> Ident {
match *self {
LifetimeName::ImplicitObjectLifetimeDefault
- | LifetimeName::Implicit
+ | LifetimeName::Implicit(_)
| LifetimeName::Error => Ident::empty(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
pub fn is_elided(&self) -> bool {
match self {
LifetimeName::ImplicitObjectLifetimeDefault
- | LifetimeName::Implicit
+ | LifetimeName::Implicit(_)
| LifetimeName::Underscore => true,
// It might seem surprising that `Fresh(_)` counts as
pub span: Span,
}
-#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
-pub enum InferKind {
- Const,
- Type,
-}
-
-impl InferKind {
- #[inline]
- pub fn is_type(self) -> bool {
- matches!(self, InferKind::Type)
- }
-}
-
#[derive(Encodable, Debug, HashStable_Generic)]
pub struct InferArg {
pub hir_id: HirId,
- pub kind: InferKind,
pub span: Span,
}
}
}
- pub fn to_ord(&self, feats: &rustc_feature::Features) -> ast::ParamKindOrd {
+ pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
GenericArg::Type(_) => ast::ParamKindOrd::Type,
- GenericArg::Const(_) => {
- ast::ParamKindOrd::Const { unordered: feats.unordered_const_ty_params() }
- }
+ GenericArg::Const(_) => ast::ParamKindOrd::Const,
GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
}
}
pub kind: GenericParamKind<'hir>,
}
-impl GenericParam<'hir> {
- pub fn bounds_span(&self) -> Option<Span> {
- self.bounds.iter().fold(None, |span, bound| {
- let span = span.map(|s| s.to(bound.span())).unwrap_or_else(|| bound.span());
-
- Some(span)
- })
+impl<'hir> GenericParam<'hir> {
+ pub fn bounds_span_for_suggestions(&self) -> Option<Span> {
+ self.bounds
+ .iter()
+ .fold(None, |span: Option<Span>, bound| {
+ // We include bounds that come from a `#[derive(_)]` but point at the user's code,
+ // as we use this method to get a span appropriate for suggestions.
+ if !bound.span().can_be_used_for_suggestions() {
+ None
+ } else {
+ let span = span.map(|s| s.to(bound.span())).unwrap_or_else(|| bound.span());
+ Some(span)
+ }
+ })
+ .map(|sp| sp.shrink_to_hi())
}
}
pub span: Span,
}
-impl Generics<'hir> {
+impl<'hir> Generics<'hir> {
pub const fn empty() -> Generics<'hir> {
Generics {
params: &[],
EqPredicate(WhereEqPredicate<'hir>),
}
-impl WherePredicate<'_> {
+impl<'hir> WherePredicate<'hir> {
pub fn span(&self) -> Span {
match self {
WherePredicate::BoundPredicate(p) => p.span,
pub bounds: GenericBounds<'hir>,
}
-impl WhereBoundPredicate<'hir> {
+impl<'hir> WhereBoundPredicate<'hir> {
/// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
let path = match self.bounded_ty.kind {
pub body: &'hir Expr<'hir>,
}
+/// Represents a `let <pat>[: <ty>] = <expr>` expression (not a Local), occurring in an `if-let` or
+/// `let-else`, evaluating to a boolean. Typically the pattern is refutable.
+///
+/// In an if-let, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of the
+/// desugaring to if-let. Only let-else supports the type annotation at present.
+#[derive(Debug, HashStable_Generic)]
+pub struct Let<'hir> {
+ pub hir_id: HirId,
+ pub span: Span,
+ pub pat: &'hir Pat<'hir>,
+ pub ty: Option<&'hir Ty<'hir>>,
+ pub init: &'hir Expr<'hir>,
+}
+
#[derive(Debug, HashStable_Generic)]
pub enum Guard<'hir> {
If(&'hir Expr<'hir>),
- // FIXME use ExprKind::Let for this.
+ // FIXME use hir::Let for this.
IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>),
}
UserProvided,
}
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)]
pub struct BodyId {
pub hir_id: HirId,
}
pub generator_kind: Option<GeneratorKind>,
}
-impl Body<'hir> {
+impl<'hir> Body<'hir> {
pub fn id(&self) -> BodyId {
BodyId { hir_id: self.value.hir_id }
}
/// A literal.
pub type Lit = Spanned<LitKind>;
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
+pub enum ArrayLen {
+ Infer(HirId, Span),
+ Body(AnonConst),
+}
+
+impl ArrayLen {
+ pub fn hir_id(&self) -> HirId {
+ match self {
+ &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, body: _ }) => hir_id,
+ }
+ }
+}
+
/// A constant (expression) that's not an item or associated item,
/// but needs its own `DefId` for type-checking, const-eval, etc.
/// These are usually found nested inside types (e.g., array lengths)
| LangItem::RangeFrom
| LangItem::RangeFull
| LangItem::RangeToInclusive,
- _,
+ ..
)
),
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
ExprKind::Call(ref func, _) => {
- matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
+ matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
}
_ => false,
///
/// These are not `Local` and only occur as expressions.
/// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`.
- Let(&'hir Pat<'hir>, &'hir Expr<'hir>, Span),
+ Let(&'hir Let<'hir>),
/// An `if` block, with an optional else block.
///
/// I.e., `if <expr> { <expr> } else { <expr> }`.
///
/// E.g., `[1; 5]`. The first expression is the element
/// to be repeated; the second is the number of times to repeat it.
- Repeat(&'hir Expr<'hir>, AnonConst),
+ Repeat(&'hir Expr<'hir>, ArrayLen),
/// A suspension point for generators (i.e., `yield <expr>`).
Yield(&'hir Expr<'hir>, YieldSource),
/// 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.
- LangItem(LangItem, Span),
+ /// Reference to a `#[lang = "foo"]` item. `HirId` of the inner expr.
+ LangItem(LangItem, Span, Option<HirId>),
}
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,
}
}
match *self {
QPath::Resolved(_, path) => path.span,
QPath::TypeRelative(qself, _) => qself.span,
- QPath::LangItem(_, span) => span,
+ QPath::LangItem(_, span, _) => 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,
}
}
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
pub struct TraitItemId {
pub def_id: LocalDefId,
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
pub struct ImplItemId {
pub def_id: LocalDefId,
}
pub struct OpaqueTy<'hir> {
pub generics: Generics<'hir>,
pub bounds: GenericBounds<'hir>,
- pub impl_trait_fn: Option<DefId>,
pub origin: OpaqueTyOrigin,
}
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum OpaqueTyOrigin {
/// `-> impl Trait`
- FnReturn,
+ FnReturn(LocalDefId),
/// `async fn`
- AsyncFn,
+ AsyncFn(LocalDefId),
/// type aliases: `type Foo = impl Trait;`
TyAlias,
}
/// A variable length slice (i.e., `[T]`).
Slice(&'hir Ty<'hir>),
/// A fixed length array (i.e., `[T; n]`).
- Array(&'hir Ty<'hir>, AnonConst),
+ Array(&'hir Ty<'hir>, ArrayLen),
/// A raw pointer (i.e., `*const T` or `*mut T`).
Ptr(MutTy<'hir>),
/// A reference (i.e., `&'a T` or `&'a mut T`).
}
}
-#[derive(Encodable, Debug)]
+#[derive(Encodable, Debug, HashStable_Generic)]
pub struct Mod<'hir> {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
Unit(HirId),
}
-impl VariantData<'hir> {
+impl<'hir> VariantData<'hir> {
/// Return the fields of this variant.
pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
match *self {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash)]
pub struct ItemId {
pub def_id: LocalDefId,
}
Some(match *self {
ItemKind::Fn(_, ref generics, _)
| ItemKind::TyAlias(_, ref generics)
- | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
+ | ItemKind::OpaqueTy(OpaqueTy {
+ ref generics, origin: OpaqueTyOrigin::TyAlias, ..
+ })
| ItemKind::Enum(_, ref generics)
| ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
pub struct ForeignItemId {
pub def_id: LocalDefId,
}
}
}
- pub fn hir_id(&self) -> Option<HirId> {
- match self {
- Node::Item(Item { def_id, .. })
- | Node::TraitItem(TraitItem { def_id, .. })
- | Node::ImplItem(ImplItem { def_id, .. })
- | Node::ForeignItem(ForeignItem { def_id, .. }) => Some(HirId::make_owner(*def_id)),
- Node::Field(FieldDef { hir_id, .. })
- | Node::AnonConst(AnonConst { hir_id, .. })
- | Node::Expr(Expr { hir_id, .. })
- | Node::Stmt(Stmt { hir_id, .. })
- | Node::Ty(Ty { hir_id, .. })
- | Node::Binding(Pat { hir_id, .. })
- | Node::Pat(Pat { hir_id, .. })
- | Node::Arm(Arm { hir_id, .. })
- | Node::Block(Block { hir_id, .. })
- | Node::Local(Local { hir_id, .. })
- | Node::Lifetime(Lifetime { hir_id, .. })
- | Node::Param(Param { hir_id, .. })
- | Node::Infer(InferArg { hir_id, .. })
- | Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
- Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
- Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
- Node::Variant(Variant { id, .. }) => Some(*id),
- Node::Ctor(variant) => variant.ctor_hir_id(),
- Node::Crate(_) | Node::Visibility(_) => None,
- }
- }
-
- /// Returns `Constness::Const` when this node is a const fn/impl/item.
- pub fn constness_for_typeck(&self) -> Constness {
- match self {
- Node::Item(Item {
- kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
- ..
- })
- | Node::TraitItem(TraitItem {
- kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
- ..
- })
- | Node::ImplItem(ImplItem {
- kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
- ..
- })
- | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
-
- Node::Item(Item { kind: ItemKind::Const(..), .. })
- | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
- | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
-
- _ => Constness::NotConst,
- }
- }
-
pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
match self {
Node::Item(i) => Some(OwnerNode::Item(i)),
rustc_data_structures::static_assert_size!(super::Expr<'static>, 64);
rustc_data_structures::static_assert_size!(super::Pat<'static>, 88);
rustc_data_structures::static_assert_size!(super::QPath<'static>, 24);
- rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);
+ rustc_data_structures::static_assert_size!(super::Ty<'static>, 80);
rustc_data_structures::static_assert_size!(super::Item<'static>, 184);
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128);