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

View file

@ -9,6 +9,7 @@
test(attr(deny(warnings))) test(attr(deny(warnings)))
)] )]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(const_fn)] // For the `transmute` in `P::new` #![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_fn_transmute)] #![feature(const_fn_transmute)]
#![feature(const_panic)] #![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); vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr)); 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); visit_fn_sig(sig, vis);
vis.visit_generics(generics); vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body)); 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::Mod(m) => vis.visit_mod(m),
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(_ga) => {} ItemKind::GlobalAsm(_ga) => {}
ItemKind::TyAlias(_, generics, bounds, ty) => { ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
vis.visit_generics(generics); vis.visit_generics(generics);
visit_bounds(bounds, vis); visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty)); 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_variant_data(variant_data);
vis.visit_generics(generics); vis.visit_generics(generics);
} }
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety: _, unsafety: _,
polarity: _, polarity: _,
defaultness: _, defaultness: _,
@ -942,13 +942,13 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
of_trait, of_trait,
self_ty, self_ty,
items, items,
} => { }) => {
vis.visit_generics(generics); vis.visit_generics(generics);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty); vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); 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); vis.visit_generics(generics);
visit_bounds(bounds, vis); visit_bounds(bounds, vis);
items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); 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); visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr)); visit_opt(expr, |expr| visitor.visit_expr(expr));
} }
AssocItemKind::Fn(_, sig, generics, body) => { AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_fn_sig(sig, visitor); visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body)); visit_opt(body, |body| visitor.visit_block(body));
} }
AssocItemKind::TyAlias(_, generics, bounds, ty) => { AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_bounds(bounds, visitor); visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty)); 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); visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr)); visit_opt(expr, |expr| visitor.visit_expr(expr));
} }
ForeignItemKind::Fn(_, sig, generics, body) => { ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_fn_sig(sig, visitor); visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body)); visit_opt(body, |body| visitor.visit_block(body));
} }
ForeignItemKind::TyAlias(_, generics, bounds, ty) => { ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_bounds(bounds, visitor); visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty)); 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); visitor.visit_ty(typ);
walk_list!(visitor, visit_expr, expr); 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); visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
visitor.visit_fn(kind, item.span, item.id) 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); walk_list!(visitor, visit_foreign_item, &foreign_module.items);
} }
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga), 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); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty); 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_generics(generics);
visitor.visit_enum_def(enum_definition, generics, item.id, item.span) visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
} }
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety: _, unsafety: _,
polarity: _, polarity: _,
defaultness: _, defaultness: _,
@ -320,7 +320,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
ref of_trait, ref of_trait,
ref self_ty, ref self_ty,
ref items, ref items,
} => { }) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait); walk_list!(visitor, visit_trait_ref, of_trait);
visitor.visit_ty(self_ty); 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_generics(generics);
visitor.visit_variant_data(struct_definition); 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); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); 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); visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr); walk_list!(visitor, visit_expr, expr);
} }
ForeignItemKind::Fn(_, sig, generics, body) => { ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref()); let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id); visitor.visit_fn(kind, span, id);
} }
ForeignItemKind::TyAlias(_, generics, bounds, ty) => { ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty); 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); visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr); walk_list!(visitor, visit_expr, expr);
} }
AssocItemKind::Fn(_, sig, generics, body) => { AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref()); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id); visitor.visit_fn(kind, span, id);
} }
AssocItemKind::TyAlias(_, generics, bounds, ty) => { AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty); 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 { if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: 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)); this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
} else { } else {
visit::walk_item(this, item); visit::walk_item(this, item);
@ -189,7 +189,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
vec vec
} }
ItemKind::MacroDef(..) => SmallVec::new(), 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], _ => smallvec![i.id],
}; };
@ -276,12 +278,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id) hir::ItemKind::Const(ty, body_id)
} }
ItemKind::Fn( ItemKind::Fn(box FnKind(
_, _,
FnSig { ref decl, header, span: fn_sig_span }, FnSig { ref decl, header, span: fn_sig_span },
ref generics, ref generics,
ref body, ref body,
) => { )) => {
let fn_def_id = self.resolver.local_def_id(id); let fn_def_id = self.resolver.local_def_id(id);
self.with_new_scopes(|this| { self.with_new_scopes(|this| {
this.current_item = Some(ident.span); 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::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 // We lower
// //
// type Foo = impl Trait // type Foo = impl Trait
@ -348,7 +350,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics) 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 ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics) hir::ItemKind::TyAlias(ty, generics)
@ -375,7 +377,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(generics, ImplTraitContext::disallowed()), self.lower_generics(generics, ImplTraitContext::disallowed()),
) )
} }
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety, unsafety,
polarity, polarity,
defaultness, defaultness,
@ -384,7 +386,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
of_trait: ref trait_ref, of_trait: ref trait_ref,
self_ty: ref ty, self_ty: ref ty,
items: ref impl_items, items: ref impl_items,
} => { }) => {
let def_id = self.resolver.local_def_id(id); let def_id = self.resolver.local_def_id(id);
// Lower the "impl header" first. This ordering is important // Lower the "impl header" first. This ordering is important
@ -448,7 +450,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
items: new_impl_items, 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 bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
let items = self let items = self
.arena .arena
@ -698,7 +706,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: i.ident, ident: i.ident,
attrs: self.lower_attrs(&i.attrs), attrs: self.lower_attrs(&i.attrs),
kind: match i.kind { kind: match i.kind {
ForeignItemKind::Fn(_, ref sig, ref generics, _) => { ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
let fdec = &sig.decl; let fdec = &sig.decl;
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs( let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
generics, generics,
@ -803,19 +811,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body)) (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 names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) = let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id); self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names))) (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 body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
let (generics, sig) = let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id); self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_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 ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = hir::TraitItemKind::Type( let kind = hir::TraitItemKind::Type(
@ -841,10 +849,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let (kind, has_default) = match &i.kind { let (kind, has_default) = match &i.kind {
AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()), AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
AssocItemKind::TyAlias(_, _, _, default) => { AssocItemKind::TyAlias(box TyAliasKind(_, _, _, default)) => {
(hir::AssocItemKind::Type, default.is_some()) (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()) (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some())
} }
AssocItemKind::MacCall(..) => unimplemented!(), AssocItemKind::MacCall(..) => unimplemented!(),
@ -870,7 +878,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())), 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); self.current_item = Some(i.span);
let asyncness = sig.header.asyncness; let asyncness = sig.header.asyncness;
let body_id = let body_id =
@ -887,7 +895,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(generics, hir::ImplItemKind::Fn(sig, body_id)) (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 generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = match ty { let kind = match ty {
None => { None => {
@ -938,7 +946,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: match &i.kind { kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
AssocItemKind::Fn(_, sig, ..) => { AssocItemKind::Fn(box FnKind(_, sig, ..)) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
} }
AssocItemKind::MacCall(..) => unimplemented!(), AssocItemKind::MacCall(..) => unimplemented!(),

View file

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

View file

@ -920,7 +920,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
match item.kind { match item.kind {
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety, unsafety,
polarity, polarity,
defaultness: _, defaultness: _,
@ -929,7 +929,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: Some(ref t), of_trait: Some(ref t),
ref self_ty, ref self_ty,
items: _, items: _,
} => { }) => {
self.with_in_trait_impl(true, |this| { self.with_in_trait_impl(true, |this| {
this.invalid_visibility(&item.vis, None); this.invalid_visibility(&item.vis, None);
if let TyKind::Err = self_ty.kind { if let TyKind::Err = self_ty.kind {
@ -957,7 +957,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}); });
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety, unsafety,
polarity, polarity,
defaultness, defaultness,
@ -966,7 +966,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: None, of_trait: None,
ref self_ty, ref self_ty,
items: _, items: _,
} => { }) => {
let error = |annotation_span, annotation| { let error = |annotation_span, annotation| {
let mut err = self.err_handler().struct_span_err( let mut err = self.err_handler().struct_span_err(
self_ty.span, self_ty.span,
@ -998,7 +998,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.emit(); .emit();
} }
} }
ItemKind::Fn(def, _, _, ref body) => { ItemKind::Fn(box FnKind(def, _, _, ref body)) => {
self.check_defaultness(item.span, def); self.check_defaultness(item.span, def);
if body.is_none() { 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 { if is_auto == IsAuto::Yes {
// Auto traits cannot have generics, super traits nor contain items. // Auto traits cannot have generics, super traits nor contain items.
self.deny_generic_params(generics, item.ident.span); 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"; let msg = "free static item without body";
self.error_item_without_body(item.span, "static", msg, " = <expr>;"); 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); self.check_defaultness(item.span, def);
if body.is_none() { if body.is_none() {
let msg = "free type alias without body"; 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) { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
match &fi.kind { match &fi.kind {
ForeignItemKind::Fn(def, sig, _, body) => { ForeignItemKind::Fn(box FnKind(def, sig, _, body)) => {
self.check_defaultness(fi.span, *def); self.check_defaultness(fi.span, *def);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref()); self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header); 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_defaultness(fi.span, *def);
self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span)); self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks"); self.check_type_no_bounds(bounds, "`extern` blocks");
@ -1336,10 +1342,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
AssocItemKind::Const(_, _, body) => { AssocItemKind::Const(_, _, body) => {
self.check_impl_item_provided(item.span, body, "constant", " = <expr>;"); 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> }"); 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_impl_item_provided(item.span, body, "type", " = <type>;");
self.check_type_no_bounds(bounds, "`impl`s"); 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 { if ctxt == AssocCtxt::Trait || self.in_trait_impl {
self.invalid_visibility(&item.vis, None); 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_const(sig.header.constness);
self.check_trait_fn_not_async(item.span, sig.header.asyncness); 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 { if let ast::ImplPolarity::Negative(span) = polarity {
gate_feature_post!( gate_feature_post!(
&self, &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!( gate_feature_post!(
&self, &self,
auto_traits, auto_traits,
@ -399,7 +401,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg); 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) { fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
let is_fn = match i.kind { 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) { if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
} }
true 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) { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!( gate_feature_post!(
&self, &self,

View file

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

View file

@ -68,7 +68,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1; self.count += 1;
walk_generics(self, g) 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; self.count += 1;
walk_fn(self, fk, s) walk_fn(self, fk, s)
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -5,7 +5,7 @@ use rustc_ast::expand::allocator::{
}; };
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; 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_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
@ -85,7 +85,8 @@ impl AllocFnFactory<'_, '_> {
let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() }; let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
let sig = FnSig { decl, header, span: self.span }; let sig = FnSig { decl, header, span: self.span };
let block = Some(self.cx.block_expr(output_expr)); 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( let item = self.cx.item(
self.span, self.span,
Ident::from_str_and_span(&self.kind.fn_name(method.name), 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. //! injecting code into the crate before it is lowered to HIR.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(decl_macro)] #![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 { 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 has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
let sd = &cx.sess.parse_sess.span_diagnostic; 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 { if let ast::Unsafe::Yes(span) = sig.header.unsafety {
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests") sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
.span_label(span, "`unsafe` because of this") .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 { 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 // N.B., inadequate check, but we're running
// well before resolve, can't get too deep. // well before resolve, can't get too deep.
sig.decl.inputs.len() == 1 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 decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp }; let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
let def = ast::Defaultness::Final; 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 // Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main { let main_id = match cx.reexport_test_harness_main {

View file

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

View file

@ -759,7 +759,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i { let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, 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, _ => false,
}; };
self.run(is_const, |s| noop_visit_item_kind(i, s)) 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]> { fn flat_map_trait_item(&mut self, i: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
let is_const = match i.kind { let is_const = match i.kind {
ast::AssocItemKind::Const(..) => true, 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, _ => false,
}; };
self.run(is_const, |s| noop_flat_map_assoc_item(i, s)) 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) { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
match it.kind { match it.kind {
ast::ItemKind::Trait(_, ast::Unsafe::Yes(_), ..) => { ast::ItemKind::Trait(box ast::TraitKind(_, ast::Unsafe::Yes(_), ..)) => self
self.report_unsafe(cx, it.span, |lint| { .report_unsafe(cx, it.span, |lint| {
lint.build("declaration of an `unsafe` trait").emit() lint.build("declaration of an `unsafe` trait").emit()
}) }),
}
ast::ItemKind::Impl { unsafety: ast::Unsafe::Yes(_), .. } => { ast::ItemKind::Impl(box ast::ImplKind { unsafety: ast::Unsafe::Yes(_), .. }) => self
self.report_unsafe(cx, it.span, |lint| { .report_unsafe(cx, it.span, |lint| {
lint.build("implementation of an `unsafe` trait").emit() lint.build("implementation of an `unsafe` trait").emit()
}) }),
}
_ => {} _ => {}
} }
@ -872,7 +870,7 @@ declare_lint_pass!(
impl EarlyLintPass for AnonymousParameters { impl EarlyLintPass for AnonymousParameters {
fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) { 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() { for arg in sig.decl.inputs.iter() {
if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind { if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
if ident.name == kw::Empty { if ident.name == kw::Empty {

View file

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

View file

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

View file

@ -4,6 +4,8 @@
#![feature(bindings_after_at)] #![feature(bindings_after_at)]
#![feature(iter_order_by)] #![feature(iter_order_by)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(box_syntax)]
#![feature(box_patterns)]
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::attr::HasAttrs; 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 crate::{maybe_collect_tokens, maybe_whole};
use rustc_ast::ast::*;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind}; use rustc_ast::token::{self, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID}; 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::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind}; use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
use rustc_ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; 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() { } else if self.check_fn_front_matter() {
// FUNCTION ITEM // FUNCTION ITEM
let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?; 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) { } else if self.eat_keyword(kw::Extern) {
if self.eat_keyword(kw::Crate) { if self.eat_keyword(kw::Crate) {
// EXTERN CRATE // EXTERN CRATE
@ -556,7 +556,7 @@ impl<'a> Parser<'a> {
}; };
let trait_ref = TraitRef { path, ref_id: ty_first.id }; let trait_ref = TraitRef { path, ref_id: ty_first.id };
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety, unsafety,
polarity, polarity,
defaultness, defaultness,
@ -565,11 +565,11 @@ impl<'a> Parser<'a> {
of_trait: Some(trait_ref), of_trait: Some(trait_ref),
self_ty: ty_second, self_ty: ty_second,
items: impl_items, items: impl_items,
} })
} }
None => { None => {
// impl Type // impl Type
ItemKind::Impl { ItemKind::Impl(box ImplKind {
unsafety, unsafety,
polarity, polarity,
defaultness, defaultness,
@ -578,7 +578,7 @@ impl<'a> Parser<'a> {
of_trait: None, of_trait: None,
self_ty: ty_first, self_ty: ty_first,
items: impl_items, items: impl_items,
} })
} }
}; };
@ -718,7 +718,7 @@ impl<'a> Parser<'a> {
// It's a normal trait. // It's a normal trait.
tps.where_clause = self.parse_where_clause()?; tps.where_clause = self.parse_where_clause()?;
let items = self.parse_item_list(attrs, |p| p.parse_trait_item())?; 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 }; let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
self.expect_semi()?; self.expect_semi()?;
Ok((ident, ItemKind::TyAlias(def, generics, bounds, default))) Ok((ident, ItemKind::TyAlias(box TyAliasKind(def, generics, bounds, default))))
} }
/// Parses a `UseTree`. /// Parses a `UseTree`.
@ -1013,7 +1013,9 @@ impl<'a> Parser<'a> {
let mut impl_info = self.parse_item_impl(attrs, defaultness)?; let mut impl_info = self.parse_item_impl(attrs, defaultness)?;
match impl_info.1 { match impl_info.1 {
// only try to recover if this is implementing a trait for a type // 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); *constness = Const::Yes(const_span);
let before_trait = trai.path.span.shrink_to_lo(); 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 crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{self as ast, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
use rustc_ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast::{Block, FnKind, ForeignItem, ForeignItemKind, ImplKind, Item, ItemKind, NodeId};
use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_lowering::ResolverAstLowering;
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -887,7 +887,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
} }
// These items do not add names to modules. // 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); self.r.trait_impl_items.insert(local_def_id);
} }
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
@ -1371,7 +1371,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
AssocCtxt::Trait => { AssocCtxt::Trait => {
let (def_kind, ns) = match item.kind { let (def_kind, ns) = match item.kind {
AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS), AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS),
AssocItemKind::Fn(_, ref sig, _, _) => { AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) => {
if sig.decl.has_self() { if sig.decl.has_self() {
self.r.has_self.insert(def_id); 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) { fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
match foreign_item.kind { match foreign_item.kind {
ForeignItemKind::Fn(_, _, ref generics, _) ForeignItemKind::Fn(box FnKind(_, _, ref generics, _))
| ForeignItemKind::TyAlias(_, ref generics, ..) => { | ForeignItemKind::TyAlias(box TyAliasKind(_, ref generics, ..)) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
visit::walk_foreign_item(this, foreign_item); 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); debug!("(resolving item) resolving {} ({:?})", name, item.kind);
match 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| { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
visit::walk_item(this, item) visit::walk_item(this, item)
}); });
@ -950,17 +951,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.resolve_adt(item, generics); self.resolve_adt(item, generics);
} }
ItemKind::Impl { ItemKind::Impl(box ImplKind {
ref generics, ref generics,
ref of_trait, ref of_trait,
ref self_ty, ref self_ty,
items: ref impl_items, items: ref impl_items,
.. ..
} => { }) => {
self.resolve_implementation(generics, of_trait, &self_ty, item.id, 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. // Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
let local_def_id = this.r.local_def_id(item.id).to_def_id(); 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); walk_assoc_item(this, generics, item);
} }
AssocItemKind::TyAlias(_, generics, _, _) => { AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, _)) => {
walk_assoc_item(this, generics, item); walk_assoc_item(this, generics, item);
} }
AssocItemKind::MacCall(_) => { 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. // We also need a new scope for the impl item type parameters.
this.with_generic_param_rib( this.with_generic_param_rib(
generics, 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. // We also need a new scope for the impl item type parameters.
this.with_generic_param_rib( this.with_generic_param_rib(
generics, generics,

View file

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

View file

@ -9,6 +9,7 @@
//! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`. //! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(format_args_capture)] #![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 crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
use if_chain::if_chain; use if_chain::if_chain;
use itertools::Itertools; 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_ast::token::CommentKind;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -492,7 +492,9 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
| ItemKind::ExternCrate(..) | ItemKind::ExternCrate(..)
| ItemKind::ForeignMod(..) => return false, | ItemKind::ForeignMod(..) => return false,
// We found a main function ... // 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 is_async = matches!(sig.header.asyncness, Async::Yes { .. });
let returns_nothing = match &sig.decl.output { let returns_nothing = match &sig.decl.output {
FnRetTy::Default(..) => true, 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 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_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span; use rustc_span::Span;
@ -158,18 +160,16 @@ impl EarlyLintPass for ExcessiveBools {
"consider using a state machine or refactoring bools into two-variant enums", "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 { 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); 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 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_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -364,7 +367,7 @@ impl EarlyLintPass for NonExpressiveNames {
return; 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); do_check(self, cx, &item.attrs, &sig.decl, blk);
} }
} }
@ -374,7 +377,7 @@ impl EarlyLintPass for NonExpressiveNames {
return; 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); 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) { match (l, r) {
(ExternCrate(l), ExternCrate(r)) => l == r, (ExternCrate(l), ExternCrate(r)) => l == r,
(Use(l), Use(r)) => eq_use_tree(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), (Static(lt, lm, le), Static(rt, rm, re)) => {
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, 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)) (Const(ld, lt, le), Const(rd, rt, re)) => {
}, eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re)
(Mod(l), Mod(r)) => l.inline == r.inline && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_item_kind)), }
(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)) => { (ForeignMod(l), ForeignMod(r)) => {
both(&l.abi, &r.abi, |l, r| eq_str_lit(l, 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)) && 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_defaultness(*ld, *rd)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r)) && 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)) => { (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
eq_variant_data(lv, rv) && eq_generics(lg, 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 la == ra
&& matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No) && matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
&& eq_generics(lg, rg) && 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)), (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, unsafety: lu,
polarity: lp, polarity: lp,
defaultness: ld, defaultness: ld,
@ -269,8 +278,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
of_trait: lot, of_trait: lot,
self_ty: lst, self_ty: lst,
items: li, items: li,
}, }),
Impl { Impl(box ImplKind {
unsafety: ru, unsafety: ru,
polarity: rp, polarity: rp,
defaultness: rd, defaultness: rd,
@ -279,7 +288,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
of_trait: rot, of_trait: rot,
self_ty: rst, self_ty: rst,
items: ri, items: ri,
}, }),
) => { ) => {
matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No) matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
&& matches!(lp, ImplPolarity::Positive) == matches!(rp, ImplPolarity::Positive) && 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 { pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
use ForeignItemKind::*; use ForeignItemKind::*;
match (l, r) { match (l, r) {
(Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), (Static(lt, lm, le), Static(rt, rm, re)) => {
(Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => { lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re)
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r)) }
}, (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
(TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => { 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_defaultness(*ld, *rd)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r)) && 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 { pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
use AssocItemKind::*; use AssocItemKind::*;
match (l, r) { match (l, r) {
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re), (Const(ld, lt, le), Const(rd, rt, re)) => {
(Fn(ld, lf, lg, lb), Fn(rd, rf, rg, rb)) => { eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re)
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r)) }
}, (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
(TyAlias(ld, lg, lb, lt), TyAlias(rd, rg, rb, rt)) => { 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_defaultness(*ld, *rd)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, |l, r| eq_generic_bound(l, r)) && 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 crate::utils::{snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then};
use if_chain::if_chain; 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::token;
use rustc_ast::tokenstream::TokenStream; use rustc_ast::tokenstream::TokenStream;
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -231,11 +233,7 @@ impl_lint_pass!(Write => [
impl EarlyLintPass for Write { impl EarlyLintPass for Write {
fn check_item(&mut self, _: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, _: &EarlyContext<'_>, item: &Item) {
if let ItemKind::Impl { if let ItemKind::Impl(box ImplKind { of_trait: Some(trait_ref), .. }) = &item.kind {
of_trait: Some(trait_ref),
..
} = &item.kind
{
let trait_name = trait_ref let trait_name = trait_ref
.path .path
.segments .segments
@ -377,10 +375,15 @@ impl Write {
/// (Some("string to write: {}"), Some(buf)) /// (Some("string to write: {}"), Some(buf))
/// ``` /// ```
#[allow(clippy::too_many_lines)] #[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::{ use rustc_parse_format::{
AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied, FormatSpec, ParseMode, Parser, AlignUnknown, ArgumentImplicitlyIs, ArgumentIs, ArgumentNamed, CountImplied,
Piece, FormatSpec, ParseMode, Parser, Piece,
}; };
let mut parser = parser::Parser::new(&cx.sess.parse_sess, tts, false, None); 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 let Piece::NextArgument(arg) = piece {
if !self.in_debug_impl && arg.format.ty == "?" { if !self.in_debug_impl && arg.format.ty == "?" {
// FIXME: modify rustc's fmt string parser to give us the current span // 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); args.push(arg);
} }
@ -438,7 +446,9 @@ impl Write {
return (Some(fmtstr), None); return (Some(fmtstr), None);
}; };
match &token_expr.kind { 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 all_simple = true;
let mut seen = false; let mut seen = false;
for arg in &args { for arg in &args {
@ -448,15 +458,15 @@ impl Write {
all_simple &= arg.format == SIMPLE; all_simple &= arg.format == SIMPLE;
seen = true; seen = true;
} }
}, }
ArgumentNamed(_) => {}, ArgumentNamed(_) => {}
} }
} }
if all_simple && seen { if all_simple && seen {
span_lint(cx, lint, token_expr.span, "literal with an empty format string"); span_lint(cx, lint, token_expr.span, "literal with an empty format string");
} }
idx += 1; idx += 1;
}, }
ExprKind::Assign(lhs, rhs, _) => { ExprKind::Assign(lhs, rhs, _) => {
if_chain! { if_chain! {
if let ExprKind::Lit(ref lit) = rhs.kind; if let ExprKind::Lit(ref lit) = rhs.kind;
@ -481,7 +491,7 @@ impl Write {
} }
} }
} }
}, }
_ => idx += 1, _ => idx += 1,
} }
} }
@ -513,11 +523,17 @@ impl Write {
cx, cx,
PRINT_WITH_NEWLINE, PRINT_WITH_NEWLINE,
mac.span(), 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| {
err.multipart_suggestion( err.multipart_suggestion(
&format!("use `{}!` instead", suggested), &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, Applicability::MachineApplicable,
); );
}, },