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:
commit
3182375e06
34 changed files with 319 additions and 204 deletions
|
@ -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),
|
||||
})
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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!(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(box_patterns)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
mod helpers;
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(internal_output_capture)]
|
||||
#![feature(nll)]
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
|
|
Loading…
Add table
Reference in a new issue