Auto merge of #81405 - bugadani:ast, r=cjgillot

Box the biggest ast::ItemKind variants

This PR is a different approach on https://github.com/rust-lang/rust/pull/81400, aiming to save memory in humongous ASTs.

The three affected item kind enums are:
 - `ast::ItemKind` (208 -> 112 bytes)
 - `ast::AssocItemKind` (176 -> 72 bytes)
 - `ast::ForeignItemKind` (176 -> 72 bytes)
This commit is contained in:
bors 2021-02-02 17:34:08 +00:00
commit 3182375e06
34 changed files with 319 additions and 204 deletions

View File

@ -2655,6 +2655,36 @@ impl Default for FnHeader {
}
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TraitKind(
pub IsAuto,
pub Unsafe,
pub Generics,
pub GenericBounds,
pub Vec<P<AssocItem>>,
);
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TyAliasKind(pub Defaultness, pub Generics, pub GenericBounds, pub Option<P<Ty>>);
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ImplKind {
pub unsafety: Unsafe,
pub polarity: ImplPolarity,
pub defaultness: Defaultness,
pub constness: Const,
pub generics: Generics,
/// The trait being implemented, if any.
pub of_trait: Option<TraitRef>,
pub self_ty: P<Ty>,
pub items: Vec<P<AssocItem>>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct FnKind(pub Defaultness, pub FnSig, pub Generics, pub Option<P<Block>>);
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ItemKind {
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
@ -2676,7 +2706,7 @@ pub enum ItemKind {
/// A function declaration (`fn`).
///
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
Fn(Box<FnKind>),
/// A module declaration (`mod`).
///
/// E.g., `mod foo;` or `mod foo { .. }`.
@ -2690,7 +2720,7 @@ pub enum ItemKind {
/// A type alias (`type`).
///
/// E.g., `type Foo = Bar<u8>;`.
TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
TyAlias(Box<TyAliasKind>),
/// An enum definition (`enum`).
///
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
@ -2706,7 +2736,7 @@ pub enum ItemKind {
/// A trait declaration (`trait`).
///
/// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
Trait(IsAuto, Unsafe, Generics, GenericBounds, Vec<P<AssocItem>>),
Trait(Box<TraitKind>),
/// Trait alias
///
/// E.g., `trait Foo = Bar + Quux;`.
@ -2714,19 +2744,7 @@ pub enum ItemKind {
/// An implementation.
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
Impl {
unsafety: Unsafe,
polarity: ImplPolarity,
defaultness: Defaultness,
constness: Const,
generics: Generics,
/// The trait being implemented, if any.
of_trait: Option<TraitRef>,
self_ty: P<Ty>,
items: Vec<P<AssocItem>>,
},
Impl(Box<ImplKind>),
/// A macro invocation.
///
/// E.g., `foo!(..)`.
@ -2736,6 +2754,9 @@ pub enum ItemKind {
MacroDef(MacroDef),
}
#[cfg(target_arch = "x86_64")]
rustc_data_structures::static_assert_size!(ItemKind, 112);
impl ItemKind {
pub fn article(&self) -> &str {
use ItemKind::*;
@ -2770,14 +2791,14 @@ impl ItemKind {
pub fn generics(&self) -> Option<&Generics> {
match self {
Self::Fn(_, _, generics, _)
| Self::TyAlias(_, generics, ..)
Self::Fn(box FnKind(_, _, generics, _))
| Self::TyAlias(box TyAliasKind(_, generics, ..))
| Self::Enum(_, generics)
| Self::Struct(_, generics)
| Self::Union(_, generics)
| Self::Trait(_, _, generics, ..)
| Self::Trait(box TraitKind(_, _, generics, ..))
| Self::TraitAlias(generics, _)
| Self::Impl { generics, .. } => Some(generics),
| Self::Impl(box ImplKind { generics, .. }) => Some(generics),
_ => None,
}
}
@ -2800,17 +2821,22 @@ pub enum AssocItemKind {
/// If `def` is parsed, then the constant is provided, and otherwise required.
Const(Defaultness, P<Ty>, Option<P<Expr>>),
/// An associated function.
Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
Fn(Box<FnKind>),
/// An associated type.
TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
TyAlias(Box<TyAliasKind>),
/// A macro expanding to associated items.
MacCall(MacCall),
}
#[cfg(target_arch = "x86_64")]
rustc_data_structures::static_assert_size!(AssocItemKind, 72);
impl AssocItemKind {
pub fn defaultness(&self) -> Defaultness {
match *self {
Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def,
Self::Const(def, ..)
| Self::Fn(box FnKind(def, ..))
| Self::TyAlias(box TyAliasKind(def, ..)) => def,
Self::MacCall(..) => Defaultness::Final,
}
}
@ -2820,8 +2846,8 @@ impl From<AssocItemKind> for ItemKind {
fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
match assoc_item_kind {
AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c),
AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
AssocItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
@ -2833,8 +2859,8 @@ impl TryFrom<ItemKind> for AssocItemKind {
fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d),
ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_alias_kind) => AssocItemKind::TyAlias(ty_alias_kind),
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
_ => return Err(item_kind),
})
@ -2846,20 +2872,23 @@ impl TryFrom<ItemKind> for AssocItemKind {
pub enum ForeignItemKind {
/// A foreign static item (`static FOO: u8`).
Static(P<Ty>, Mutability, Option<P<Expr>>),
/// A foreign function.
Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
/// A foreign type.
TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
/// An foreign function.
Fn(Box<FnKind>),
/// An foreign type.
TyAlias(Box<TyAliasKind>),
/// A macro expanding to foreign items.
MacCall(MacCall),
}
#[cfg(target_arch = "x86_64")]
rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
impl From<ForeignItemKind> for ItemKind {
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
match foreign_item_kind {
ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c),
ForeignItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
ForeignItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
@ -2871,8 +2900,8 @@ impl TryFrom<ItemKind> for ForeignItemKind {
fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
Ok(match item_kind {
ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d),
ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d),
ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
_ => return Err(item_kind),
})

View File

@ -9,6 +9,7 @@
test(attr(deny(warnings)))
)]
#![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_fn_transmute)]
#![feature(const_panic)]

View File

@ -912,7 +912,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
}
ItemKind::Fn(_, sig, generics, body) => {
ItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visit_fn_sig(sig, vis);
vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body));
@ -920,7 +920,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
ItemKind::Mod(m) => vis.visit_mod(m),
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(_ga) => {}
ItemKind::TyAlias(_, generics, bounds, ty) => {
ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty));
@ -933,7 +933,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
}
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety: _,
polarity: _,
defaultness: _,
@ -942,13 +942,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
of_trait,
self_ty,
items,
} => {
}) => {
vis.visit_generics(generics);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
}
ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => {
ItemKind::Trait(box TraitKind(.., generics, bounds, items)) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
@ -976,12 +976,12 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
AssocItemKind::Fn(_, sig, generics, body) => {
AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
AssocItemKind::TyAlias(_, generics, bounds, ty) => {
AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
@ -1066,12 +1066,12 @@ pub fn noop_flat_map_foreign_item<T: MutVisitor>(
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
ForeignItemKind::Fn(_, sig, generics, body) => {
ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
ForeignItemKind::TyAlias(_, generics, bounds, ty) => {
ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));

View File

@ -292,7 +292,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_ty(typ);
walk_list!(visitor, visit_expr, expr);
}
ItemKind::Fn(_, ref sig, ref generics, ref body) => {
ItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body)) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
visitor.visit_fn(kind, item.span, item.id)
@ -302,7 +302,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
}
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
ItemKind::TyAlias(_, ref generics, ref bounds, ref ty) => {
ItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref ty)) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
@ -311,7 +311,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_generics(generics);
visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
}
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety: _,
polarity: _,
defaultness: _,
@ -320,7 +320,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
ref of_trait,
ref self_ty,
ref items,
} => {
}) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait);
visitor.visit_ty(self_ty);
@ -331,7 +331,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_generics(generics);
visitor.visit_variant_data(struct_definition);
}
ItemKind::Trait(.., ref generics, ref bounds, ref items) => {
ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref items)) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
@ -543,12 +543,12 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
ForeignItemKind::Fn(_, sig, generics, body) => {
ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id);
}
ForeignItemKind::TyAlias(_, generics, bounds, ty) => {
ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
@ -653,12 +653,12 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
AssocItemKind::Fn(_, sig, generics, body) => {
AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id);
}
AssocItemKind::TyAlias(_, generics, bounds, ty) => {
AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);

View File

@ -67,7 +67,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl { ref of_trait, .. } = item.kind {
if let ItemKind::Impl(box ImplKind { ref of_trait, .. }) = item.kind {
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
} else {
visit::walk_item(this, item);
@ -189,7 +189,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
vec
}
ItemKind::MacroDef(..) => SmallVec::new(),
ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id],
ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => {
smallvec![i.id]
}
_ => smallvec![i.id],
};
@ -276,12 +278,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id)
}
ItemKind::Fn(
ItemKind::Fn(box FnKind(
_,
FnSig { ref decl, header, span: fn_sig_span },
ref generics,
ref body,
) => {
)) => {
let fn_def_id = self.resolver.local_def_id(id);
self.with_new_scopes(|this| {
this.current_item = Some(ident.span);
@ -329,7 +331,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
ItemKind::TyAlias(box TyAliasKind(_, ref gen, _, Some(ref ty))) => {
// We lower
//
// type Foo = impl Trait
@ -348,7 +350,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
}
ItemKind::TyAlias(_, ref generics, _, None) => {
ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, None)) => {
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
@ -375,7 +377,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety,
polarity,
defaultness,
@ -384,7 +386,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
of_trait: ref trait_ref,
self_ty: ref ty,
items: ref impl_items,
} => {
}) => {
let def_id = self.resolver.local_def_id(id);
// Lower the "impl header" first. This ordering is important
@ -448,7 +450,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
items: new_impl_items,
})
}
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
ItemKind::Trait(box TraitKind(
is_auto,
unsafety,
ref generics,
ref bounds,
ref items,
)) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
let items = self
.arena
@ -698,7 +706,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
kind: match i.kind {
ForeignItemKind::Fn(_, ref sig, ref generics, _) => {
ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl;
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
generics,
@ -803,19 +811,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
}
AssocItemKind::Fn(_, ref sig, ref generics, None) => {
AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, None)) => {
let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
}
AssocItemKind::Fn(_, ref sig, ref generics, Some(ref body)) => {
AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, Some(ref body))) => {
let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
}
AssocItemKind::TyAlias(_, ref generics, ref bounds, ref default) => {
AssocItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref default)) => {
let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = hir::TraitItemKind::Type(
@ -841,10 +849,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let (kind, has_default) = match &i.kind {
AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
AssocItemKind::TyAlias(_, _, _, default) => {
AssocItemKind::TyAlias(box TyAliasKind(_, _, _, default)) => {
(hir::AssocItemKind::Type, default.is_some())
}
AssocItemKind::Fn(_, sig, _, default) => {
AssocItemKind::Fn(box FnKind(_, sig, _, default)) => {
(hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some())
}
AssocItemKind::MacCall(..) => unimplemented!(),
@ -870,7 +878,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
)
}
AssocItemKind::Fn(_, sig, generics, body) => {
AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
self.current_item = Some(i.span);
let asyncness = sig.header.asyncness;
let body_id =
@ -887,7 +895,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(generics, hir::ImplItemKind::Fn(sig, body_id))
}
AssocItemKind::TyAlias(_, generics, _, ty) => {
AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, ty)) => {
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = match ty {
None => {
@ -938,7 +946,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
AssocItemKind::Fn(_, sig, ..) => {
AssocItemKind::Fn(box FnKind(_, sig, ..)) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::MacCall(..) => unimplemented!(),

View File

@ -32,6 +32,7 @@
#![feature(crate_visibility_modifier)]
#![feature(or_patterns)]
#![feature(box_patterns)]
#![recursion_limit = "256"]
use rustc_ast::node_id::NodeMap;
@ -500,8 +501,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
| ItemKind::Enum(_, ref generics)
| ItemKind::TyAlias(_, ref generics, ..)
| ItemKind::Trait(_, _, ref generics, ..) => {
| ItemKind::TyAlias(box TyAliasKind(_, ref generics, ..))
| ItemKind::Trait(box TraitKind(_, _, ref generics, ..)) => {
let def_id = self.lctx.resolver.local_def_id(item.id);
let count = generics
.params

View File

@ -920,7 +920,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
match item.kind {
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety,
polarity,
defaultness: _,
@ -929,7 +929,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: Some(ref t),
ref self_ty,
items: _,
} => {
}) => {
self.with_in_trait_impl(true, |this| {
this.invalid_visibility(&item.vis, None);
if let TyKind::Err = self_ty.kind {
@ -957,7 +957,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
return; // Avoid visiting again.
}
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety,
polarity,
defaultness,
@ -966,7 +966,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: None,
ref self_ty,
items: _,
} => {
}) => {
let error = |annotation_span, annotation| {
let mut err = self.err_handler().struct_span_err(
self_ty.span,
@ -998,7 +998,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.emit();
}
}
ItemKind::Fn(def, _, _, ref body) => {
ItemKind::Fn(box FnKind(def, _, _, ref body)) => {
self.check_defaultness(item.span, def);
if body.is_none() {
@ -1027,7 +1027,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
}
ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
ItemKind::Trait(box TraitKind(
is_auto,
_,
ref generics,
ref bounds,
ref trait_items,
)) => {
if is_auto == IsAuto::Yes {
// Auto traits cannot have generics, super traits nor contain items.
self.deny_generic_params(generics, item.ident.span);
@ -1075,7 +1081,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let msg = "free static item without body";
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
}
ItemKind::TyAlias(def, _, ref bounds, ref body) => {
ItemKind::TyAlias(box TyAliasKind(def, _, ref bounds, ref body)) => {
self.check_defaultness(item.span, def);
if body.is_none() {
let msg = "free type alias without body";
@ -1091,12 +1097,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
match &fi.kind {
ForeignItemKind::Fn(def, sig, _, body) => {
ForeignItemKind::Fn(box FnKind(def, sig, _, body)) => {
self.check_defaultness(fi.span, *def);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
}
ForeignItemKind::TyAlias(def, generics, bounds, body) => {
ForeignItemKind::TyAlias(box TyAliasKind(def, generics, bounds, body)) => {
self.check_defaultness(fi.span, *def);
self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
@ -1336,10 +1342,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
AssocItemKind::Const(_, _, body) => {
self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
}
AssocItemKind::Fn(_, _, _, body) => {
AssocItemKind::Fn(box FnKind(_, _, _, body)) => {
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
}
AssocItemKind::TyAlias(_, _, bounds, body) => {
AssocItemKind::TyAlias(box TyAliasKind(_, _, bounds, body)) => {
self.check_impl_item_provided(item.span, body, "type", " = <type>;");
self.check_type_no_bounds(bounds, "`impl`s");
}
@ -1349,7 +1355,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
self.invalid_visibility(&item.vis, None);
if let AssocItemKind::Fn(_, sig, _, _) = &item.kind {
if let AssocItemKind::Fn(box FnKind(_, sig, _, _)) = &item.kind {
self.check_trait_fn_not_const(sig.header.constness);
self.check_trait_fn_not_async(item.span, sig.header.asyncness);
}

View File

@ -365,7 +365,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
ast::ItemKind::Impl { polarity, defaultness, ref of_trait, .. } => {
ast::ItemKind::Impl(box ast::ImplKind {
polarity, defaultness, ref of_trait, ..
}) => {
if let ast::ImplPolarity::Negative(span) = polarity {
gate_feature_post!(
&self,
@ -381,7 +383,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
ast::ItemKind::Trait(box ast::TraitKind(ast::IsAuto::Yes, ..)) => {
gate_feature_post!(
&self,
auto_traits,
@ -399,7 +401,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg);
}
ast::ItemKind::TyAlias(_, _, _, Some(ref ty)) => self.check_impl_trait(&ty),
ast::ItemKind::TyAlias(box ast::TyAliasKind(_, _, _, Some(ref ty))) => {
self.check_impl_trait(&ty)
}
_ => {}
}
@ -555,13 +559,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
let is_fn = match i.kind {
ast::AssocItemKind::Fn(_, ref sig, _, _) => {
ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => {
if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
}
true
}
ast::AssocItemKind::TyAlias(_, ref generics, _, ref ty) => {
ast::AssocItemKind::TyAlias(box ast::TyAliasKind(_, ref generics, _, ref ty)) => {
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!(
&self,

View File

@ -6,6 +6,8 @@
#![feature(bindings_after_at)]
#![feature(iter_is_partitioned)]
#![feature(box_syntax)]
#![feature(box_patterns)]
#![recursion_limit = "256"]
pub mod ast_validation;

View File

@ -68,7 +68,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_generics(self, g)
}
fn visit_fn(&mut self, fk: FnKind<'_>, s: Span, _: NodeId) {
fn visit_fn(&mut self, fk: visit::FnKind<'_>, s: Span, _: NodeId) {
self.count += 1;
walk_fn(self, fk, s)
}

View File

@ -1,6 +1,7 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(or_patterns)]
#![feature(box_patterns)]
#![recursion_limit = "256"]
mod helpers;

View File

@ -1022,14 +1022,14 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
ast::ForeignItemKind::Fn(def, sig, gen, body) => {
ast::ForeignItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
}
ast::ForeignItemKind::Static(ty, mutbl, body) => {
let def = ast::Defaultness::Final;
self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def);
}
ast::ForeignItemKind::TyAlias(def, generics, bounds, ty) => {
ast::ForeignItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
}
ast::ForeignItemKind::MacCall(m) => {
@ -1134,7 +1134,7 @@ impl<'a> State<'a> {
ast::ItemKind::Const(def, ref ty, ref body) => {
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def);
}
ast::ItemKind::Fn(def, ref sig, ref gen, ref body) => {
ast::ItemKind::Fn(box ast::FnKind(def, ref sig, ref gen, ref body)) => {
let body = body.as_deref();
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
@ -1175,7 +1175,7 @@ impl<'a> State<'a> {
self.s.word(ga.asm.to_string());
self.end();
}
ast::ItemKind::TyAlias(def, ref generics, ref bounds, ref ty) => {
ast::ItemKind::TyAlias(box ast::TyAliasKind(def, ref generics, ref bounds, ref ty)) => {
let ty = ty.as_deref();
self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
}
@ -1190,7 +1190,7 @@ impl<'a> State<'a> {
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident, item.span, true);
}
ast::ItemKind::Impl {
ast::ItemKind::Impl(box ast::ImplKind {
unsafety,
polarity,
defaultness,
@ -1199,7 +1199,7 @@ impl<'a> State<'a> {
ref of_trait,
ref self_ty,
ref items,
} => {
}) => {
self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness);
@ -1233,7 +1233,13 @@ impl<'a> State<'a> {
}
self.bclose(item.span);
}
ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
ast::ItemKind::Trait(box ast::TraitKind(
is_auto,
unsafety,
ref generics,
ref bounds,
ref trait_items,
)) => {
self.head("");
self.print_visibility(&item.vis);
self.print_unsafety(unsafety);
@ -1453,13 +1459,13 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
ast::AssocItemKind::Fn(def, sig, gen, body) => {
ast::AssocItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
}
ast::AssocItemKind::Const(def, ty, body) => {
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
}
ast::AssocItemKind::TyAlias(def, generics, bounds, ty) => {
ast::AssocItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
}
ast::AssocItemKind::MacCall(m) => {

View File

@ -527,12 +527,12 @@ impl<'a> TraitDef<'a> {
tokens: None,
},
attrs: Vec::new(),
kind: ast::AssocItemKind::TyAlias(
kind: ast::AssocItemKind::TyAlias(box ast::TyAliasKind(
ast::Defaultness::Final,
Generics::default(),
Vec::new(),
Some(type_def.to_ty(cx, self.span, type_ident, generics)),
),
)),
tokens: None,
})
});
@ -687,7 +687,7 @@ impl<'a> TraitDef<'a> {
self.span,
Ident::invalid(),
a,
ast::ItemKind::Impl {
ast::ItemKind::Impl(box ast::ImplKind {
unsafety,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
@ -696,7 +696,7 @@ impl<'a> TraitDef<'a> {
of_trait: opt_trait_ref,
self_ty: self_type,
items: methods.into_iter().chain(associated_types).collect(),
},
}),
)
}
@ -929,7 +929,7 @@ impl<'a> MethodDef<'a> {
tokens: None,
},
ident: method_ident,
kind: ast::AssocItemKind::Fn(def, sig, fn_generics, Some(body_block)),
kind: ast::AssocItemKind::Fn(box ast::FnKind(def, sig, fn_generics, Some(body_block))),
tokens: None,
})
}

View File

@ -2,7 +2,7 @@
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::{ItemKind, MetaItem};
use rustc_ast::{ImplKind, ItemKind, MetaItem};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@ -179,7 +179,7 @@ fn inject_impl_of_structural_trait(
span,
Ident::invalid(),
attrs,
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
@ -188,7 +188,7 @@ fn inject_impl_of_structural_trait(
of_trait: Some(trait_ref),
self_ty: self_type,
items: Vec::new(),
},
}),
);
push(Annotatable::Item(newitem));

View File

@ -5,7 +5,7 @@ use rustc_ast::expand::allocator::{
};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
use rustc_ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_ast::{FnKind, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
@ -85,7 +85,8 @@ impl AllocFnFactory<'_, '_> {
let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
let sig = FnSig { decl, header, span: self.span };
let block = Some(self.cx.block_expr(output_expr));
let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
let kind =
ItemKind::Fn(box FnKind(ast::Defaultness::Final, sig, Generics::default(), block));
let item = self.cx.item(
self.span,
Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),

View File

@ -2,6 +2,8 @@
//! injecting code into the crate before it is lowered to HIR.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]

View File

@ -425,7 +425,7 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
let sd = &cx.sess.parse_sess.span_diagnostic;
if let ast::ItemKind::Fn(_, ref sig, ref generics, _) = i.kind {
if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, ref generics, _)) = i.kind {
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
.span_label(span, "`unsafe` because of this")
@ -474,7 +474,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
}
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_sig = if let ast::ItemKind::Fn(_, ref sig, _, _) = i.kind {
let has_sig = if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) = i.kind {
// N.B., inadequate check, but we're running
// well before resolve, can't get too deep.
sig.decl.inputs.len() == 1

View File

@ -311,7 +311,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
let def = ast::Defaultness::Final;
let main = ast::ItemKind::Fn(def, sig, ast::Generics::default(), Some(main_body));
let main =
ast::ItemKind::Fn(box ast::FnKind(def, sig, ast::Generics::default(), Some(main_body)));
// Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main {

View File

@ -1,4 +1,5 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(internal_output_capture)]
#![feature(nll)]

View File

@ -759,7 +759,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
ast::ItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
_ => false,
};
self.run(is_const, |s| noop_visit_item_kind(i, s))
@ -768,7 +768,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn flat_map_trait_item(&mut self, i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
let is_const = match i.kind {
ast::AssocItemKind::Const(..) => true,
ast::AssocItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
_ => false,
};
self.run(is_const, |s| noop_flat_map_assoc_item(i, s))

View File

@ -357,17 +357,15 @@ impl EarlyLintPass for UnsafeCode {
fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
match it.kind {
ast::ItemKind::Trait(_, ast::Unsafe::Yes(_), ..) => {
self.report_unsafe(cx, it.span, |lint| {
ast::ItemKind::Trait(box ast::TraitKind(_, ast::Unsafe::Yes(_), ..)) => self
.report_unsafe(cx, it.span, |lint| {
lint.build("declaration of an `unsafe` trait").emit()
})
}
}),
ast::ItemKind::Impl { unsafety: ast::Unsafe::Yes(_), .. } => {
self.report_unsafe(cx, it.span, |lint| {
ast::ItemKind::Impl(box ast::ImplKind { unsafety: ast::Unsafe::Yes(_), .. }) => self
.report_unsafe(cx, it.span, |lint| {
lint.build("implementation of an `unsafe` trait").emit()
})
}
}),
_ => {}
}
@ -872,7 +870,7 @@ declare_lint_pass!(
impl EarlyLintPass for AnonymousParameters {
fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
if let ast::AssocItemKind::Fn(_, ref sig, _, _) = it.kind {
if let ast::AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) = it.kind {
for arg in sig.decl.inputs.iter() {
if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
if ident.name == kw::Empty {

View File

@ -2,7 +2,7 @@
//! Clippy.
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc_ast::{Item, ItemKind};
use rustc_ast::{ImplKind, Item, ItemKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
@ -243,7 +243,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
impl EarlyLintPass for LintPassImpl {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind {
if let ItemKind::Impl(box ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind {
if let Some(last) = lint_pass.path.segments.last() {
if last.ident.name == sym::LintPass {
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();

View File

@ -30,6 +30,7 @@
#![feature(array_windows)]
#![feature(bool_to_option)]
#![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(crate_visibility_modifier)]
#![feature(iter_order_by)]
#![feature(never_type)]

View File

@ -4,6 +4,8 @@
#![feature(bindings_after_at)]
#![feature(iter_order_by)]
#![feature(or_patterns)]
#![feature(box_syntax)]
#![feature(box_patterns)]
use rustc_ast as ast;
use rustc_ast::attr::HasAttrs;

View File

@ -4,11 +4,11 @@ use super::{FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
use crate::{maybe_collect_tokens, maybe_whole};
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
use rustc_ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind, Mod};
use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
use rustc_ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
@ -229,7 +229,7 @@ impl<'a> Parser<'a> {
} else if self.check_fn_front_matter() {
// FUNCTION ITEM
let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?;
(ident, ItemKind::Fn(def(), sig, generics, body))
(ident, ItemKind::Fn(box FnKind(def(), sig, generics, body)))
} else if self.eat_keyword(kw::Extern) {
if self.eat_keyword(kw::Crate) {
// EXTERN CRATE
@ -556,7 +556,7 @@ impl<'a> Parser<'a> {
};
let trait_ref = TraitRef { path, ref_id: ty_first.id };
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety,
polarity,
defaultness,
@ -565,11 +565,11 @@ impl<'a> Parser<'a> {
of_trait: Some(trait_ref),
self_ty: ty_second,
items: impl_items,
}
})
}
None => {
// impl Type
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
unsafety,
polarity,
defaultness,
@ -578,7 +578,7 @@ impl<'a> Parser<'a> {
of_trait: None,
self_ty: ty_first,
items: impl_items,
}
})
}
};
@ -718,7 +718,7 @@ impl<'a> Parser<'a> {
// It's a normal trait.
tps.where_clause = self.parse_where_clause()?;
let items = self.parse_item_list(attrs, |p| p.parse_trait_item())?;
Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, items)))
Ok((ident, ItemKind::Trait(box TraitKind(is_auto, unsafety, tps, bounds, items))))
}
}
@ -767,7 +767,7 @@ impl<'a> Parser<'a> {
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
self.expect_semi()?;
Ok((ident, ItemKind::TyAlias(def, generics, bounds, default)))
Ok((ident, ItemKind::TyAlias(box TyAliasKind(def, generics, bounds, default))))
}
/// Parses a `UseTree`.
@ -1013,7 +1013,9 @@ impl<'a> Parser<'a> {
let mut impl_info = self.parse_item_impl(attrs, defaultness)?;
match impl_info.1 {
// only try to recover if this is implementing a trait for a type
ItemKind::Impl { of_trait: Some(ref trai), ref mut constness, .. } => {
ItemKind::Impl(box ImplKind {
of_trait: Some(ref trai), ref mut constness, ..
}) => {
*constness = Const::Yes(const_span);
let before_trait = trai.path.span.shrink_to_lo();

View File

@ -16,8 +16,8 @@ use crate::{
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{self as ast, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
use rustc_ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind};
use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
use rustc_ast::{Block, FnKind, ForeignItem, ForeignItemKind, ImplKind, Item, ItemKind, NodeId};
use rustc_ast_lowering::ResolverAstLowering;
use rustc_attr as attr;
use rustc_data_structures::sync::Lrc;
@ -887,7 +887,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}
// These items do not add names to modules.
ItemKind::Impl { of_trait: Some(..), .. } => {
ItemKind::Impl(box ImplKind { of_trait: Some(..), .. }) => {
self.r.trait_impl_items.insert(local_def_id);
}
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
@ -1371,7 +1371,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
AssocCtxt::Trait => {
let (def_kind, ns) = match item.kind {
AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS),
AssocItemKind::Fn(_, ref sig, _, _) => {
AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) => {
if sig.decl.has_self() {
self.r.has_self.insert(def_id);
}

View File

@ -493,8 +493,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
}
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
match foreign_item.kind {
ForeignItemKind::Fn(_, _, ref generics, _)
| ForeignItemKind::TyAlias(_, ref generics, ..) => {
ForeignItemKind::Fn(box FnKind(_, _, ref generics, _))
| ForeignItemKind::TyAlias(box TyAliasKind(_, ref generics, ..)) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
visit::walk_foreign_item(this, foreign_item);
});
@ -938,7 +938,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
match item.kind {
ItemKind::TyAlias(_, ref generics, _, _) | ItemKind::Fn(_, _, ref generics, _) => {
ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, _))
| ItemKind::Fn(box FnKind(_, _, ref generics, _)) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
visit::walk_item(this, item)
});
@ -950,17 +951,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.resolve_adt(item, generics);
}
ItemKind::Impl {
ItemKind::Impl(box ImplKind {
ref generics,
ref of_trait,
ref self_ty,
items: ref impl_items,
..
} => {
}) => {
self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
}
ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref trait_items)) => {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
let local_def_id = this.r.local_def_id(item.id).to_def_id();
@ -995,10 +996,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
);
}
}
AssocItemKind::Fn(_, _, generics, _) => {
AssocItemKind::Fn(box FnKind(_, _, generics, _)) => {
walk_assoc_item(this, generics, item);
}
AssocItemKind::TyAlias(_, generics, _, _) => {
AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, _)) => {
walk_assoc_item(this, generics, item);
}
AssocItemKind::MacCall(_) => {
@ -1306,7 +1307,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
},
);
}
AssocItemKind::Fn(_, _, generics, _) => {
AssocItemKind::Fn(box FnKind(.., generics, _)) => {
// We also need a new scope for the impl item type parameters.
this.with_generic_param_rib(
generics,
@ -1329,7 +1330,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
},
);
}
AssocItemKind::TyAlias(_, generics, _, _) => {
AssocItemKind::TyAlias(box TyAliasKind(
_,
generics,
_,
_,
)) => {
// We also need a new scope for the impl item type parameters.
this.with_generic_param_rib(
generics,

View File

@ -1109,7 +1109,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
if assoc_item.ident == ident {
return Some(match &assoc_item.kind {
ast::AssocItemKind::Const(..) => AssocSuggestion::AssocConst,
ast::AssocItemKind::Fn(_, sig, ..) if sig.decl.has_self() => {
ast::AssocItemKind::Fn(box ast::FnKind(_, sig, ..))
if sig.decl.has_self() =>
{
AssocSuggestion::MethodWithSelf
}
ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn,

View File

@ -9,6 +9,7 @@
//! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]

View File

@ -1,7 +1,7 @@
use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
use if_chain::if_chain;
use itertools::Itertools;
use rustc_ast::ast::{Async, AttrKind, Attribute, FnRetTy, ItemKind};
use rustc_ast::ast::{Async, AttrKind, Attribute, FnKind, FnRetTy, ItemKind};
use rustc_ast::token::CommentKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
@ -492,7 +492,9 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
| ItemKind::ExternCrate(..)
| ItemKind::ForeignMod(..) => return false,
// We found a main function ...
ItemKind::Fn(_, sig, _, Some(block)) if item.ident.name == sym::main => {
ItemKind::Fn(box FnKind(_, sig, _, Some(block)))
if item.ident.name == sym::main =>
{
let is_async = matches!(sig.header.asyncness, Async::Yes { .. });
let returns_nothing = match &sig.decl.output {
FnRetTy::Default(..) => true,

View File

@ -1,5 +1,7 @@
use crate::utils::{attr_by_name, in_macro, match_path_ast, span_lint_and_help};
use rustc_ast::ast::{AssocItemKind, Extern, FnSig, Item, ItemKind, Ty, TyKind};
use rustc_ast::ast::{
AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind,
};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
@ -158,18 +160,16 @@ impl EarlyLintPass for ExcessiveBools {
"consider using a state machine or refactoring bools into two-variant enums",
);
}
},
ItemKind::Impl {
of_trait: None, items, ..
}
| ItemKind::Trait(_, _, _, _, items) => {
ItemKind::Impl(box ImplKind { of_trait: None, items, .. })
| ItemKind::Trait(box TraitKind(.., items)) => {
for item in items {
if let AssocItemKind::Fn(_, fn_sig, _, _) = &item.kind {
if let AssocItemKind::Fn(box FnKind(_, fn_sig, _, _)) = &item.kind {
self.check_fn_sig(cx, fn_sig, item.span);
}
}
},
ItemKind::Fn(_, fn_sig, _, _) => self.check_fn_sig(cx, fn_sig, item.span),
}
ItemKind::Fn(box FnKind(_, fn_sig, _, _)) => self.check_fn_sig(cx, fn_sig, item.span),
_ => (),
}
}

View File

@ -1,5 +1,8 @@
use crate::utils::{span_lint, span_lint_and_then};
use rustc_ast::ast::{Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind};
use rustc_ast::ast::{
Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, FnKind, Item, ItemKind, Local, Pat,
PatKind,
};
use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_middle::lint::in_external_macro;
@ -364,7 +367,7 @@ impl EarlyLintPass for NonExpressiveNames {
return;
}
if let ItemKind::Fn(_, ref sig, _, Some(ref blk)) = item.kind {
if let ItemKind::Fn(box FnKind(_, ref sig, _, Some(ref blk))) = item.kind {
do_check(self, cx, &item.attrs, &sig.decl, blk);
}
}
@ -374,7 +377,7 @@ impl EarlyLintPass for NonExpressiveNames {
return;
}
if let AssocItemKind::Fn(_, ref sig, _, Some(ref blk)) = item.kind {
if let AssocItemKind::Fn(box FnKind(_, ref sig, _, Some(ref blk))) = item.kind {
do_check(self, cx, &item.attrs, &sig.decl, blk);
}
}

View File

@ -229,17 +229,26 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
match (l, r) {
(ExternCrate(l), ExternCrate(r)) => l == r,
(Use(l), Use(r)) => eq_use_tree(l, r),
(Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
(Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
},
(Mod(l), Mod(r)) => l.inline == r.inline && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_item_kind)),
(Static(lt, lm, le), Static(rt, rm, re)) => {
lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re)
}
(Const(ld, lt, le), Const(rd, rt, re)) => {
eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re)
}
(Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf)
&& eq_generics(lg, rg)
&& both(lb, rb, |l, r| eq_block(l, r))
}
(Mod(l), Mod(r)) => {
l.inline == r.inline && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_item_kind))
}
(ForeignMod(l), ForeignMod(r)) => {
both(&l.abi, &r.abi, |l, r| eq_str_lit(l, r))
&& over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
},
(TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
}
(TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
eq_defaultness(*ld, *rd)
&& eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r))
@ -250,8 +259,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
},
(Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
eq_variant_data(lv, rv) && eq_generics(lg, rg)
},
(Trait(la, lu, lg, lb, li), Trait(ra, ru, rg, rb, ri)) => {
}
(Trait(box TraitKind(la, lu, lg, lb, li)), Trait(box TraitKind(ra, ru, rg, rb, ri))) => {
la == ra
&& matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
&& eq_generics(lg, rg)
@ -260,7 +269,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
},
(TraitAlias(lg, lb), TraitAlias(rg, rb)) => eq_generics(lg, rg) && over(lb, rb, |l, r| eq_generic_bound(l, r)),
(
Impl {
Impl(box ImplKind {
unsafety: lu,
polarity: lp,
defaultness: ld,
@ -269,8 +278,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
of_trait: lot,
self_ty: lst,
items: li,
},
Impl {
}),
Impl(box ImplKind {
unsafety: ru,
polarity: rp,
defaultness: rd,
@ -279,7 +288,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
of_trait: rot,
self_ty: rst,
items: ri,
},
}),
) => {
matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
&& matches!(lp, ImplPolarity::Positive) == matches!(rp, ImplPolarity::Positive)
@ -299,11 +308,16 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
use ForeignItemKind::*;
match (l, r) {
(Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
(Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
},
(TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
(Static(lt, lm, le), Static(rt, rm, re)) => {
lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re)
}
(Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf)
&& eq_generics(lg, rg)
&& both(lb, rb, |l, r| eq_block(l, r))
}
(TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
eq_defaultness(*ld, *rd)
&& eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r))
@ -317,11 +331,16 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
use AssocItemKind::*;
match (l, r) {
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
(Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => {
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
},
(TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => {
(Const(ld, lt, le), Const(rd, rt, re)) => {
eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re)
}
(Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf)
&& eq_generics(lg, rg)
&& both(lb, rb, |l, r| eq_block(l, r))
}
(TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
eq_defaultness(*ld, *rd)
&& eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r))

View File

@ -3,7 +3,9 @@ use std::ops::Range;
use crate::utils::{snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then};
use if_chain::if_chain;
use rustc_ast::ast::{Expr, ExprKind, Item, ItemKind, LitKind, MacCall, StrLit, StrStyle};
use rustc_ast::ast::{
Expr, ExprKind, ImplKind, Item, ItemKind, LitKind, MacCall, StrLit, StrStyle,
};
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::Applicability;
@ -231,11 +233,7 @@ impl_lint_pass!(Write => [
impl EarlyLintPass for Write {
fn check_item(&mut self, _: &EarlyContext<'_>, item: &Item) {
if let ItemKind::Impl {
of_trait: Some(trait_ref),
..
} = &item.kind
{
if let ItemKind::Impl(box ImplKind { of_trait: Some(trait_ref), .. }) = &item.kind {
let trait_name = trait_ref
.path
.segments
@ -377,10 +375,15 @@ impl Write {
/// (Some("string to write: {}"), Some(buf))
/// ```
#[allow(clippy::too_many_lines)]
fn check_tts<'a>(&self, cx: &EarlyContext<'a>, tts: TokenStream, is_write: bool) -> (Option<StrLit>, Option<Expr>) {
fn check_tts<'a>(
&self,
cx: &EarlyContext<'a>,
tts: TokenStream,
is_write: bool,
) -> (Option<StrLit>, Option<Expr>) {
use rustc_parse_format::{
AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied, FormatSpec, ParseMode, Parser,
Piece,
AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied,
FormatSpec, ParseMode, Parser, Piece,
};
let mut parser = parser::Parser::new(&cx.sess.parse_sess, tts, false, None);
@ -410,7 +413,12 @@ impl Write {
if let Piece::NextArgument(arg) = piece {
if !self.in_debug_impl && arg.format.ty == "?" {
// FIXME: modify rustc's fmt string parser to give us the current span
span_lint(cx, USE_DEBUG, parser.prev_token.span, "use of `Debug`-based formatting");
span_lint(
cx,
USE_DEBUG,
parser.prev_token.span,
"use of `Debug`-based formatting",
);
}
args.push(arg);
}
@ -438,7 +446,9 @@ impl Write {
return (Some(fmtstr), None);
};
match &token_expr.kind {
ExprKind::Lit(lit) if !matches!(lit.kind, LitKind::Int(..) | LitKind::Float(..)) => {
ExprKind::Lit(lit)
if !matches!(lit.kind, LitKind::Int(..) | LitKind::Float(..)) =>
{
let mut all_simple = true;
let mut seen = false;
for arg in &args {
@ -448,15 +458,15 @@ impl Write {
all_simple &= arg.format == SIMPLE;
seen = true;
}
},
ArgumentNamed(_) => {},
}
ArgumentNamed(_) => {}
}
}
if all_simple && seen {
span_lint(cx, lint, token_expr.span, "literal with an empty format string");
}
idx += 1;
},
}
ExprKind::Assign(lhs, rhs, _) => {
if_chain! {
if let ExprKind::Lit(ref lit) = rhs.kind;
@ -481,7 +491,7 @@ impl Write {
}
}
}
},
}
_ => idx += 1,
}
}
@ -513,11 +523,17 @@ impl Write {
cx,
PRINT_WITH_NEWLINE,
mac.span(),
&format!("using `{}!()` with a format string that ends in a single newline", name),
&format!(
"using `{}!()` with a format string that ends in a single newline",
name
),
|err| {
err.multipart_suggestion(
&format!("use `{}!` instead", suggested),
vec![(mac.path.span, suggested), (newline_span(&fmt_str), String::new())],
vec![
(mac.path.span, suggested),
(newline_span(&fmt_str), String::new()),
],
Applicability::MachineApplicable,
);
},