Auto merge of #138740 - nnethercote:ast-ItemKind-idents, r=fmease

Move `ast::Item::ident` into `ast::ItemKind`

The follow-up to #138384, which did the same thing for `hir::ItemKind`.

r? `@fmease`
This commit is contained in:
bors 2025-04-01 07:21:28 +00:00
commit ed201574c5
59 changed files with 1217 additions and 1015 deletions

View File

@ -3303,9 +3303,6 @@ pub struct Item<K = ItemKind> {
pub id: NodeId, pub id: NodeId,
pub span: Span, pub span: Span,
pub vis: Visibility, pub vis: Visibility,
/// The name of the item.
/// It might be a dummy name in case of anonymous items.
pub ident: Ident,
pub kind: K, pub kind: K,
@ -3327,23 +3324,23 @@ impl Item {
pub fn opt_generics(&self) -> Option<&Generics> { pub fn opt_generics(&self) -> Option<&Generics> {
match &self.kind { match &self.kind {
ItemKind::ExternCrate(_) ItemKind::ExternCrate(..)
| ItemKind::Use(_) | ItemKind::Use(_)
| ItemKind::Mod(_, _) | ItemKind::Mod(..)
| ItemKind::ForeignMod(_) | ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_) | ItemKind::GlobalAsm(_)
| ItemKind::MacCall(_) | ItemKind::MacCall(_)
| ItemKind::Delegation(_) | ItemKind::Delegation(_)
| ItemKind::DelegationMac(_) | ItemKind::DelegationMac(_)
| ItemKind::MacroDef(_) => None, | ItemKind::MacroDef(..) => None,
ItemKind::Static(_) => None, ItemKind::Static(_) => None,
ItemKind::Const(i) => Some(&i.generics), ItemKind::Const(i) => Some(&i.generics),
ItemKind::Fn(i) => Some(&i.generics), ItemKind::Fn(i) => Some(&i.generics),
ItemKind::TyAlias(i) => Some(&i.generics), ItemKind::TyAlias(i) => Some(&i.generics),
ItemKind::TraitAlias(generics, _) ItemKind::TraitAlias(_, generics, _)
| ItemKind::Enum(_, generics) | ItemKind::Enum(_, _, generics)
| ItemKind::Struct(_, generics) | ItemKind::Struct(_, _, generics)
| ItemKind::Union(_, generics) => Some(&generics), | ItemKind::Union(_, _, generics) => Some(&generics),
ItemKind::Trait(i) => Some(&i.generics), ItemKind::Trait(i) => Some(&i.generics),
ItemKind::Impl(i) => Some(&i.generics), ItemKind::Impl(i) => Some(&i.generics),
} }
@ -3420,6 +3417,7 @@ impl Default for FnHeader {
pub struct Trait { pub struct Trait {
pub safety: Safety, pub safety: Safety,
pub is_auto: IsAuto, pub is_auto: IsAuto,
pub ident: Ident,
pub generics: Generics, pub generics: Generics,
pub bounds: GenericBounds, pub bounds: GenericBounds,
pub items: ThinVec<P<AssocItem>>, pub items: ThinVec<P<AssocItem>>,
@ -3465,6 +3463,7 @@ pub struct TyAliasWhereClauses {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct TyAlias { pub struct TyAlias {
pub defaultness: Defaultness, pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics, pub generics: Generics,
pub where_clauses: TyAliasWhereClauses, pub where_clauses: TyAliasWhereClauses,
pub bounds: GenericBounds, pub bounds: GenericBounds,
@ -3493,6 +3492,7 @@ pub struct FnContract {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct Fn { pub struct Fn {
pub defaultness: Defaultness, pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics, pub generics: Generics,
pub sig: FnSig, pub sig: FnSig,
pub contract: Option<P<FnContract>>, pub contract: Option<P<FnContract>>,
@ -3506,6 +3506,7 @@ pub struct Delegation {
pub id: NodeId, pub id: NodeId,
pub qself: Option<P<QSelf>>, pub qself: Option<P<QSelf>>,
pub path: Path, pub path: Path,
pub ident: Ident,
pub rename: Option<Ident>, pub rename: Option<Ident>,
pub body: Option<P<Block>>, pub body: Option<P<Block>>,
/// The item was expanded from a glob delegation item. /// The item was expanded from a glob delegation item.
@ -3523,6 +3524,7 @@ pub struct DelegationMac {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct StaticItem { pub struct StaticItem {
pub ident: Ident,
pub ty: P<Ty>, pub ty: P<Ty>,
pub safety: Safety, pub safety: Safety,
pub mutability: Mutability, pub mutability: Mutability,
@ -3533,6 +3535,7 @@ pub struct StaticItem {
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
pub struct ConstItem { pub struct ConstItem {
pub defaultness: Defaultness, pub defaultness: Defaultness,
pub ident: Ident,
pub generics: Generics, pub generics: Generics,
pub ty: P<Ty>, pub ty: P<Ty>,
pub expr: Option<P<Expr>>, pub expr: Option<P<Expr>>,
@ -3545,7 +3548,7 @@ 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.
/// ///
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`. /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
ExternCrate(Option<Symbol>), ExternCrate(Option<Symbol>, Ident),
/// A use declaration item (`use`). /// A use declaration item (`use`).
/// ///
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`. /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
@ -3567,7 +3570,7 @@ pub enum ItemKind {
/// E.g., `mod foo;` or `mod foo { .. }`. /// E.g., `mod foo;` or `mod foo { .. }`.
/// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
/// semantically by Rust. /// semantically by Rust.
Mod(Safety, ModKind), Mod(Safety, Ident, ModKind),
/// An external module (`extern`). /// An external module (`extern`).
/// ///
/// E.g., `extern {}` or `extern "C" {}`. /// E.g., `extern {}` or `extern "C" {}`.
@ -3581,15 +3584,15 @@ pub enum ItemKind {
/// 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> }`.
Enum(EnumDef, Generics), Enum(Ident, EnumDef, Generics),
/// A struct definition (`struct`). /// A struct definition (`struct`).
/// ///
/// E.g., `struct Foo<A> { x: A }`. /// E.g., `struct Foo<A> { x: A }`.
Struct(VariantData, Generics), Struct(Ident, VariantData, Generics),
/// A union definition (`union`). /// A union definition (`union`).
/// ///
/// E.g., `union Foo<A, B> { x: A, y: B }`. /// E.g., `union Foo<A, B> { x: A, y: B }`.
Union(VariantData, Generics), Union(Ident, VariantData, Generics),
/// 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 {}`.
@ -3597,7 +3600,7 @@ pub enum ItemKind {
/// Trait alias. /// Trait alias.
/// ///
/// E.g., `trait Foo = Bar + Quux;`. /// E.g., `trait Foo = Bar + Quux;`.
TraitAlias(Generics, GenericBounds), TraitAlias(Ident, Generics, GenericBounds),
/// 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> { .. }`.
@ -3608,7 +3611,7 @@ pub enum ItemKind {
MacCall(P<MacCall>), MacCall(P<MacCall>),
/// A macro definition. /// A macro definition.
MacroDef(MacroDef), MacroDef(Ident, MacroDef),
/// A single delegation item (`reuse`). /// A single delegation item (`reuse`).
/// ///
@ -3620,6 +3623,31 @@ pub enum ItemKind {
} }
impl ItemKind { impl ItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
ItemKind::ExternCrate(_, ident)
| ItemKind::Static(box StaticItem { ident, .. })
| ItemKind::Const(box ConstItem { ident, .. })
| ItemKind::Fn(box Fn { ident, .. })
| ItemKind::Mod(_, ident, _)
| ItemKind::TyAlias(box TyAlias { ident, .. })
| ItemKind::Enum(ident, ..)
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(box Trait { ident, .. })
| ItemKind::TraitAlias(ident, ..)
| ItemKind::MacroDef(ident, _)
| ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
ItemKind::Use(_)
| ItemKind::ForeignMod(_)
| ItemKind::GlobalAsm(_)
| ItemKind::Impl(_)
| ItemKind::MacCall(_)
| ItemKind::DelegationMac(_) => None,
}
}
/// "a" or "an" /// "a" or "an"
pub fn article(&self) -> &'static str { pub fn article(&self) -> &'static str {
use ItemKind::*; use ItemKind::*;
@ -3660,11 +3688,11 @@ impl ItemKind {
Self::Fn(box Fn { generics, .. }) Self::Fn(box Fn { generics, .. })
| Self::TyAlias(box TyAlias { generics, .. }) | Self::TyAlias(box TyAlias { generics, .. })
| Self::Const(box ConstItem { generics, .. }) | Self::Const(box ConstItem { generics, .. })
| Self::Enum(_, generics) | Self::Enum(_, _, generics)
| Self::Struct(_, generics) | Self::Struct(_, _, generics)
| Self::Union(_, generics) | Self::Union(_, _, generics)
| Self::Trait(box Trait { generics, .. }) | Self::Trait(box Trait { generics, .. })
| Self::TraitAlias(generics, _) | Self::TraitAlias(_, generics, _)
| Self::Impl(box Impl { generics, .. }) => Some(generics), | Self::Impl(box Impl { generics, .. }) => Some(generics),
_ => None, _ => None,
} }
@ -3700,6 +3728,17 @@ pub enum AssocItemKind {
} }
impl AssocItemKind { impl AssocItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
AssocItemKind::Const(box ConstItem { ident, .. })
| AssocItemKind::Fn(box Fn { ident, .. })
| AssocItemKind::Type(box TyAlias { ident, .. })
| AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
}
}
pub fn defaultness(&self) -> Defaultness { pub fn defaultness(&self) -> Defaultness {
match *self { match *self {
Self::Const(box ConstItem { defaultness, .. }) Self::Const(box ConstItem { defaultness, .. })
@ -3746,14 +3785,26 @@ 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(Box<StaticItem>), Static(Box<StaticItem>),
/// An foreign function. /// A foreign function.
Fn(Box<Fn>), Fn(Box<Fn>),
/// An foreign type. /// A foreign type.
TyAlias(Box<TyAlias>), TyAlias(Box<TyAlias>),
/// A macro expanding to foreign items. /// A macro expanding to foreign items.
MacCall(P<MacCall>), MacCall(P<MacCall>),
} }
impl ForeignItemKind {
pub fn ident(&self) -> Option<Ident> {
match *self {
ForeignItemKind::Static(box StaticItem { ident, .. })
| ForeignItemKind::Fn(box Fn { ident, .. })
| ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
ForeignItemKind::MacCall(_) => None,
}
}
}
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 {
@ -3790,21 +3841,21 @@ mod size_asserts {
use super::*; use super::*;
// tidy-alphabetical-start // tidy-alphabetical-start
static_assert_size!(AssocItem, 88); static_assert_size!(AssocItem, 80);
static_assert_size!(AssocItemKind, 16); static_assert_size!(AssocItemKind, 16);
static_assert_size!(Attribute, 32); static_assert_size!(Attribute, 32);
static_assert_size!(Block, 32); static_assert_size!(Block, 32);
static_assert_size!(Expr, 72); static_assert_size!(Expr, 72);
static_assert_size!(ExprKind, 40); static_assert_size!(ExprKind, 40);
static_assert_size!(Fn, 176); static_assert_size!(Fn, 184);
static_assert_size!(ForeignItem, 88); static_assert_size!(ForeignItem, 80);
static_assert_size!(ForeignItemKind, 16); static_assert_size!(ForeignItemKind, 16);
static_assert_size!(GenericArg, 24); static_assert_size!(GenericArg, 24);
static_assert_size!(GenericBound, 88); static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 40); static_assert_size!(Generics, 40);
static_assert_size!(Impl, 136); static_assert_size!(Impl, 136);
static_assert_size!(Item, 136); static_assert_size!(Item, 144);
static_assert_size!(ItemKind, 64); static_assert_size!(ItemKind, 80);
static_assert_size!(LitKind, 24); static_assert_size!(LitKind, 24);
static_assert_size!(Local, 80); static_assert_size!(Local, 80);
static_assert_size!(MetaItemLit, 40); static_assert_size!(MetaItemLit, 40);

View File

@ -41,7 +41,6 @@ pub trait WalkItemKind {
&mut self, &mut self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility, visibility: &mut Visibility,
ctxt: Self::Ctxt, ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor, visitor: &mut impl MutVisitor,
@ -963,10 +962,10 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
match kind { match kind {
FnKind::Fn( FnKind::Fn(
_ctxt, _ctxt,
_ident,
_vis, _vis,
Fn { Fn {
defaultness, defaultness,
ident,
generics, generics,
contract, contract,
body, body,
@ -974,8 +973,9 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
define_opaque, define_opaque,
}, },
) => { ) => {
// Identifier and visibility are visited as a part of the item. // Visibility is visited as a part of the item.
visit_defaultness(vis, defaultness); visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_fn_header(header); vis.visit_fn_header(header);
vis.visit_generics(generics); vis.visit_generics(generics);
vis.visit_fn_decl(decl); vis.visit_fn_decl(decl);
@ -1233,12 +1233,11 @@ pub fn walk_item_kind<K: WalkItemKind>(
kind: &mut K, kind: &mut K,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility, visibility: &mut Visibility,
ctxt: K::Ctxt, ctxt: K::Ctxt,
vis: &mut impl MutVisitor, vis: &mut impl MutVisitor,
) { ) {
kind.walk(span, id, ident, visibility, ctxt, vis) kind.walk(span, id, visibility, ctxt, vis)
} }
impl WalkItemKind for ItemKind { impl WalkItemKind for ItemKind {
@ -1247,21 +1246,22 @@ impl WalkItemKind for ItemKind {
&mut self, &mut self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility, visibility: &mut Visibility,
_ctxt: Self::Ctxt, _ctxt: Self::Ctxt,
vis: &mut impl MutVisitor, vis: &mut impl MutVisitor,
) { ) {
match self { match self {
ItemKind::ExternCrate(_orig_name) => {} ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
ItemKind::Static(box StaticItem { ItemKind::Static(box StaticItem {
ident,
ty, ty,
safety: _, safety: _,
mutability: _, mutability: _,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
vis.visit_ident(ident);
vis.visit_ty(ty); vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr)); visit_opt(expr, |expr| vis.visit_expr(expr));
walk_define_opaques(vis, define_opaque); walk_define_opaques(vis, define_opaque);
@ -1270,10 +1270,11 @@ impl WalkItemKind for ItemKind {
walk_const_item(vis, item); walk_const_item(vis, item);
} }
ItemKind::Fn(func) => { ItemKind::Fn(func) => {
vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id); vis.visit_fn(FnKind::Fn(FnCtxt::Free, visibility, &mut *func), span, id);
} }
ItemKind::Mod(safety, mod_kind) => { ItemKind::Mod(safety, ident, mod_kind) => {
visit_safety(vis, safety); visit_safety(vis, safety);
vis.visit_ident(ident);
match mod_kind { match mod_kind {
ModKind::Loaded( ModKind::Loaded(
items, items,
@ -1290,18 +1291,29 @@ impl WalkItemKind for ItemKind {
} }
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty }) => { ItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
visit_defaultness(vis, defaultness); visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound); visit_bounds(vis, bounds, BoundKind::Bound);
visit_opt(ty, |ty| vis.visit_ty(ty)); visit_opt(ty, |ty| vis.visit_ty(ty));
walk_ty_alias_where_clauses(vis, where_clauses); walk_ty_alias_where_clauses(vis, where_clauses);
} }
ItemKind::Enum(EnumDef { variants }, generics) => { ItemKind::Enum(ident, EnumDef { variants }, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
} }
ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { ItemKind::Struct(ident, variant_data, generics)
| ItemKind::Union(ident, variant_data, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
vis.visit_variant_data(variant_data); vis.visit_variant_data(variant_data);
} }
@ -1326,22 +1338,28 @@ impl WalkItemKind for ItemKind {
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() }) vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
}); });
} }
ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
visit_safety(vis, safety); visit_safety(vis, safety);
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound); visit_bounds(vis, bounds, BoundKind::Bound);
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait)); items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
} }
ItemKind::TraitAlias(generics, bounds) => { ItemKind::TraitAlias(ident, generics, bounds) => {
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound); visit_bounds(vis, bounds, BoundKind::Bound);
} }
ItemKind::MacCall(m) => vis.visit_mac_call(m), ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(def) => vis.visit_macro_def(def), ItemKind::MacroDef(ident, def) => {
vis.visit_ident(ident);
vis.visit_macro_def(def)
}
ItemKind::Delegation(box Delegation { ItemKind::Delegation(box Delegation {
id, id,
qself, qself,
path, path,
ident,
rename, rename,
body, body,
from_glob: _, from_glob: _,
@ -1349,6 +1367,7 @@ impl WalkItemKind for ItemKind {
vis.visit_id(id); vis.visit_id(id);
vis.visit_qself(qself); vis.visit_qself(qself);
vis.visit_path(path); vis.visit_path(path);
vis.visit_ident(ident);
if let Some(rename) = rename { if let Some(rename) = rename {
vis.visit_ident(rename); vis.visit_ident(rename);
} }
@ -1381,7 +1400,6 @@ impl WalkItemKind for AssocItemKind {
&mut self, &mut self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility, visibility: &mut Visibility,
ctxt: Self::Ctxt, ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor, visitor: &mut impl MutVisitor,
@ -1391,20 +1409,18 @@ impl WalkItemKind for AssocItemKind {
walk_const_item(visitor, item); walk_const_item(visitor, item);
} }
AssocItemKind::Fn(func) => { AssocItemKind::Fn(func) => {
visitor.visit_fn( visitor.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &mut *func), span, id);
FnKind::Fn(FnCtxt::Assoc(ctxt), ident, visibility, &mut *func),
span,
id,
);
} }
AssocItemKind::Type(box TyAlias { AssocItemKind::Type(box TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
}) => { }) => {
visit_defaultness(visitor, defaultness); visit_defaultness(visitor, defaultness);
visitor.visit_ident(ident);
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_bounds(visitor, bounds, BoundKind::Bound); visit_bounds(visitor, bounds, BoundKind::Bound);
visit_opt(ty, |ty| visitor.visit_ty(ty)); visit_opt(ty, |ty| visitor.visit_ty(ty));
@ -1415,6 +1431,7 @@ impl WalkItemKind for AssocItemKind {
id, id,
qself, qself,
path, path,
ident,
rename, rename,
body, body,
from_glob: _, from_glob: _,
@ -1422,6 +1439,7 @@ impl WalkItemKind for AssocItemKind {
visitor.visit_id(id); visitor.visit_id(id);
visitor.visit_qself(qself); visitor.visit_qself(qself);
visitor.visit_path(path); visitor.visit_path(path);
visitor.visit_ident(ident);
if let Some(rename) = rename { if let Some(rename) = rename {
visitor.visit_ident(rename); visitor.visit_ident(rename);
} }
@ -1449,8 +1467,9 @@ impl WalkItemKind for AssocItemKind {
} }
fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) { fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
let ConstItem { defaultness, generics, ty, expr, define_opaque } = item; let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
visit_defaultness(vis, defaultness); visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics); vis.visit_generics(generics);
vis.visit_ty(ty); vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr)); visit_opt(expr, |expr| vis.visit_expr(expr));
@ -1487,12 +1506,11 @@ fn walk_item_ctxt<K: WalkItemKind>(
item: &mut P<Item<K>>, item: &mut P<Item<K>>,
ctxt: K::Ctxt, ctxt: K::Ctxt,
) { ) {
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); let Item { attrs, id, kind, vis, span, tokens } = item.deref_mut();
visitor.visit_id(id); visitor.visit_id(id);
visit_attrs(visitor, attrs); visit_attrs(visitor, attrs);
visitor.visit_vis(vis); visitor.visit_vis(vis);
visitor.visit_ident(ident); kind.walk(*span, *id, vis, ctxt, visitor);
kind.walk(*span, *id, ident, vis, ctxt, visitor);
visit_lazy_tts(visitor, tokens); visit_lazy_tts(visitor, tokens);
visitor.visit_span(span); visitor.visit_span(span);
} }
@ -1525,38 +1543,37 @@ impl WalkItemKind for ForeignItemKind {
&mut self, &mut self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &mut Ident,
visibility: &mut Visibility, visibility: &mut Visibility,
_ctxt: Self::Ctxt, _ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor, visitor: &mut impl MutVisitor,
) { ) {
match self { match self {
ForeignItemKind::Static(box StaticItem { ForeignItemKind::Static(box StaticItem {
ident,
ty, ty,
mutability: _, mutability: _,
expr, expr,
safety: _, safety: _,
define_opaque, define_opaque,
}) => { }) => {
visitor.visit_ident(ident);
visitor.visit_ty(ty); visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr)); visit_opt(expr, |expr| visitor.visit_expr(expr));
walk_define_opaques(visitor, define_opaque); walk_define_opaques(visitor, define_opaque);
} }
ForeignItemKind::Fn(func) => { ForeignItemKind::Fn(func) => {
visitor.visit_fn( visitor.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &mut *func), span, id);
FnKind::Fn(FnCtxt::Foreign, ident, visibility, &mut *func),
span,
id,
);
} }
ForeignItemKind::TyAlias(box TyAlias { ForeignItemKind::TyAlias(box TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
}) => { }) => {
visit_defaultness(visitor, defaultness); visit_defaultness(visitor, defaultness);
visitor.visit_ident(ident);
visitor.visit_generics(generics); visitor.visit_generics(generics);
visit_bounds(visitor, bounds, BoundKind::Bound); visit_bounds(visitor, bounds, BoundKind::Bound);
visit_opt(ty, |ty| visitor.visit_ty(ty)); visit_opt(ty, |ty| visitor.visit_ty(ty));
@ -1984,8 +2001,7 @@ impl DummyAstNode for Item {
span: Default::default(), span: Default::default(),
tokens: Default::default(), tokens: Default::default(),
}, },
ident: Ident::dummy(), kind: ItemKind::ExternCrate(None, Ident::dummy()),
kind: ItemKind::ExternCrate(None),
tokens: Default::default(), tokens: Default::default(),
} }
} }
@ -2052,7 +2068,7 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
#[derive(Debug)] #[derive(Debug)]
pub enum FnKind<'a> { pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn), Fn(FnCtxt, &'a mut Visibility, &'a mut Fn),
/// E.g., `|x, y| body`. /// E.g., `|x, y| body`.
Closure( Closure(

View File

@ -66,7 +66,7 @@ impl BoundKind {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> { pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
Fn(FnCtxt, &'a Ident, &'a Visibility, &'a Fn), Fn(FnCtxt, &'a Visibility, &'a Fn),
/// E.g., `|x, y| body`. /// E.g., `|x, y| body`.
Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr), Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr),
@ -75,21 +75,21 @@ pub enum FnKind<'a> {
impl<'a> FnKind<'a> { impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&'a FnHeader> { pub fn header(&self) -> Option<&'a FnHeader> {
match *self { match *self {
FnKind::Fn(_, _, _, Fn { sig, .. }) => Some(&sig.header), FnKind::Fn(_, _, Fn { sig, .. }) => Some(&sig.header),
FnKind::Closure(..) => None, FnKind::Closure(..) => None,
} }
} }
pub fn ident(&self) -> Option<&Ident> { pub fn ident(&self) -> Option<&Ident> {
match self { match self {
FnKind::Fn(_, ident, ..) => Some(ident), FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident),
_ => None, _ => None,
} }
} }
pub fn decl(&self) -> &'a FnDecl { pub fn decl(&self) -> &'a FnDecl {
match self { match self {
FnKind::Fn(_, _, _, Fn { sig, .. }) => &sig.decl, FnKind::Fn(_, _, Fn { sig, .. }) => &sig.decl,
FnKind::Closure(_, _, decl, _) => decl, FnKind::Closure(_, _, decl, _) => decl,
} }
} }
@ -118,7 +118,6 @@ pub trait WalkItemKind {
&'a self, &'a self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &'a Ident,
visibility: &'a Visibility, visibility: &'a Visibility,
ctxt: Self::Ctxt, ctxt: Self::Ctxt,
visitor: &mut V, visitor: &mut V,
@ -364,63 +363,72 @@ impl WalkItemKind for ItemKind {
&'a self, &'a self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &'a Ident,
vis: &'a Visibility, vis: &'a Visibility,
_ctxt: Self::Ctxt, _ctxt: Self::Ctxt,
visitor: &mut V, visitor: &mut V,
) -> V::Result { ) -> V::Result {
match self { match self {
ItemKind::ExternCrate(_rename) => {} ItemKind::ExternCrate(_rename, ident) => try_visit!(visitor.visit_ident(ident)),
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)), ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
ItemKind::Static(box StaticItem { ItemKind::Static(box StaticItem {
ident,
ty, ty,
safety: _, safety: _,
mutability: _, mutability: _,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr); visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque)); try_visit!(walk_define_opaques(visitor, define_opaque));
} }
ItemKind::Const(box ConstItem { ItemKind::Const(box ConstItem {
defaultness: _, defaultness: _,
ident,
generics, generics,
ty, ty,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr); visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque)); try_visit!(walk_define_opaques(visitor, define_opaque));
} }
ItemKind::Fn(func) => { ItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func); let kind = FnKind::Fn(FnCtxt::Free, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id)); try_visit!(visitor.visit_fn(kind, span, id));
} }
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { ItemKind::Mod(_unsafety, ident, mod_kind) => {
try_visit!(visitor.visit_ident(ident));
match mod_kind {
ModKind::Loaded(items, _inline, _inner_span, _) => { ModKind::Loaded(items, _inline, _inner_span, _) => {
walk_list!(visitor, visit_item, items); walk_list!(visitor, visit_item, items);
} }
ModKind::Unloaded => {} ModKind::Unloaded => {}
}, }
}
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => { ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items); walk_list!(visitor, visit_foreign_item, items);
} }
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias { ItemKind::TyAlias(box TyAlias {
generics, generics,
ident,
bounds, bounds,
ty, ty,
defaultness: _, defaultness: _,
where_clauses: _, where_clauses: _,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty); visit_opt!(visitor, visit_ty, ty);
} }
ItemKind::Enum(enum_definition, generics) => { ItemKind::Enum(ident, enum_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition)); try_visit!(visitor.visit_enum_def(enum_definition));
} }
@ -444,32 +452,47 @@ impl WalkItemKind for ItemKind {
AssocCtxt::Impl { of_trait: of_trait.is_some() } AssocCtxt::Impl { of_trait: of_trait.is_some() }
); );
} }
ItemKind::Struct(struct_definition, generics) ItemKind::Struct(ident, struct_definition, generics)
| ItemKind::Union(struct_definition, generics) => { | ItemKind::Union(ident, struct_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition)); try_visit!(visitor.visit_variant_data(struct_definition));
} }
ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => { ItemKind::Trait(box Trait {
safety: _,
is_auto: _,
ident,
generics,
bounds,
items,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
} }
ItemKind::TraitAlias(generics, bounds) => { ItemKind::TraitAlias(ident, generics, bounds) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
} }
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, id)), ItemKind::MacroDef(ident, ts) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mac_def(ts, id))
}
ItemKind::Delegation(box Delegation { ItemKind::Delegation(box Delegation {
id, id,
qself, qself,
path, path,
ident,
rename, rename,
body, body,
from_glob: _, from_glob: _,
}) => { }) => {
try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(path, *id)); try_visit!(visitor.visit_path(path, *id));
try_visit!(visitor.visit_ident(ident));
visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_block, body); visit_opt!(visitor, visit_block, body);
} }
@ -743,34 +766,37 @@ impl WalkItemKind for ForeignItemKind {
&'a self, &'a self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &'a Ident,
vis: &'a Visibility, vis: &'a Visibility,
_ctxt: Self::Ctxt, _ctxt: Self::Ctxt,
visitor: &mut V, visitor: &mut V,
) -> V::Result { ) -> V::Result {
match self { match self {
ForeignItemKind::Static(box StaticItem { ForeignItemKind::Static(box StaticItem {
ident,
ty, ty,
mutability: _, mutability: _,
expr, expr,
safety: _, safety: _,
define_opaque, define_opaque,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr); visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque)); try_visit!(walk_define_opaques(visitor, define_opaque));
} }
ForeignItemKind::Fn(func) => { ForeignItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func); let kind = FnKind::Fn(FnCtxt::Foreign, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id)); try_visit!(visitor.visit_fn(kind, span, id));
} }
ForeignItemKind::TyAlias(box TyAlias { ForeignItemKind::TyAlias(box TyAlias {
generics, generics,
ident,
bounds, bounds,
ty, ty,
defaultness: _, defaultness: _,
where_clauses: _, where_clauses: _,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty); visit_opt!(visitor, visit_ty, ty);
@ -917,10 +943,10 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
match kind { match kind {
FnKind::Fn( FnKind::Fn(
_ctxt, _ctxt,
_ident,
_vis, _vis,
Fn { Fn {
defaultness: _, defaultness: _,
ident,
sig: FnSig { header, decl, span: _ }, sig: FnSig { header, decl, span: _ },
generics, generics,
contract, contract,
@ -928,7 +954,8 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
define_opaque, define_opaque,
}, },
) => { ) => {
// Identifier and visibility are visited as a part of the item. // Visibility is visited as a part of the item.
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_fn_header(header)); try_visit!(visitor.visit_fn_header(header));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_decl(decl)); try_visit!(visitor.visit_fn_decl(decl));
@ -952,7 +979,6 @@ impl WalkItemKind for AssocItemKind {
&'a self, &'a self,
span: Span, span: Span,
id: NodeId, id: NodeId,
ident: &'a Ident,
vis: &'a Visibility, vis: &'a Visibility,
ctxt: Self::Ctxt, ctxt: Self::Ctxt,
visitor: &mut V, visitor: &mut V,
@ -960,28 +986,32 @@ impl WalkItemKind for AssocItemKind {
match self { match self {
AssocItemKind::Const(box ConstItem { AssocItemKind::Const(box ConstItem {
defaultness: _, defaultness: _,
ident,
generics, generics,
ty, ty,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr); visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque)); try_visit!(walk_define_opaques(visitor, define_opaque));
} }
AssocItemKind::Fn(func) => { AssocItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id)); try_visit!(visitor.visit_fn(kind, span, id));
} }
AssocItemKind::Type(box TyAlias { AssocItemKind::Type(box TyAlias {
generics, generics,
ident,
bounds, bounds,
ty, ty,
defaultness: _, defaultness: _,
where_clauses: _, where_clauses: _,
}) => { }) => {
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ident(ident));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty); visit_opt!(visitor, visit_ty, ty);
} }
@ -992,12 +1022,14 @@ impl WalkItemKind for AssocItemKind {
id, id,
qself, qself,
path, path,
ident,
rename, rename,
body, body,
from_glob: _, from_glob: _,
}) => { }) => {
try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(path, *id)); try_visit!(visitor.visit_path(path, *id));
try_visit!(visitor.visit_ident(ident));
visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_block, body); visit_opt!(visitor, visit_block, body);
} }
@ -1039,11 +1071,10 @@ fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
item: &'a Item<K>, item: &'a Item<K>,
ctxt: K::Ctxt, ctxt: K::Ctxt,
) -> V::Result { ) -> V::Result {
let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; let Item { id, span, vis, attrs, kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs); walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident)); try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
try_visit!(kind.walk(*span, *id, ident, vis, ctxt, visitor));
V::Result::output() V::Result::output()
} }

View File

@ -56,6 +56,7 @@ use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
pub(crate) struct DelegationResults<'hir> { pub(crate) struct DelegationResults<'hir> {
pub body_id: hir::BodyId, pub body_id: hir::BodyId,
pub sig: hir::FnSig<'hir>, pub sig: hir::FnSig<'hir>,
pub ident: Ident,
pub generics: &'hir hir::Generics<'hir>, pub generics: &'hir hir::Generics<'hir>,
} }
@ -104,9 +105,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span); let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
let sig = self.lower_delegation_sig(sig_id, decl, span); let sig = self.lower_delegation_sig(sig_id, decl, span);
let body_id = self.lower_delegation_body(delegation, param_count, span); let body_id = self.lower_delegation_body(delegation, param_count, span);
let ident = self.lower_ident(delegation.ident);
let generics = self.lower_delegation_generics(span); let generics = self.lower_delegation_generics(span);
DelegationResults { body_id, sig, generics } DelegationResults { body_id, sig, ident, generics }
} }
Err(err) => self.generate_delegation_error(err, span), Err(err) => self.generate_delegation_error(err, span),
} }
@ -405,8 +406,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let header = self.generate_header_error(); let header = self.generate_header_error();
let sig = hir::FnSig { decl, header, span }; let sig = hir::FnSig { decl, header, span };
let ident = Ident::dummy();
let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span))); let body_id = self.lower_body(|this| (&[], this.mk_expr(hir::ExprKind::Err(err), span)));
DelegationResults { generics, body_id, sig } DelegationResults { ident, generics, body_id, sig }
} }
fn generate_header_error(&self) -> hir::FnHeader { fn generate_header_error(&self) -> hir::FnHeader {

View File

@ -107,7 +107,6 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
} }
fn lower_foreign_item(&mut self, item: &ForeignItem) { fn lower_foreign_item(&mut self, item: &ForeignItem) {
debug_assert_ne!(item.ident.name, kw::Empty);
self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))) self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
} }
} }
@ -151,7 +150,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let vis_span = self.lower_span(i.vis.span); let vis_span = self.lower_span(i.vis.span);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let kind = self.lower_item_kind(i.span, i.id, hir_id, i.ident, attrs, vis_span, &i.kind); let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
let item = hir::Item { let item = hir::Item {
owner_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
kind, kind,
@ -166,41 +165,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span, span: Span,
id: NodeId, id: NodeId,
hir_id: hir::HirId, hir_id: hir::HirId,
ident: Ident,
attrs: &'hir [hir::Attribute], attrs: &'hir [hir::Attribute],
vis_span: Span, vis_span: Span,
i: &ItemKind, i: &ItemKind,
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
match i { match i {
ItemKind::ExternCrate(orig_name) => { ItemKind::ExternCrate(orig_name, ident) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
hir::ItemKind::ExternCrate(*orig_name, ident) hir::ItemKind::ExternCrate(*orig_name, ident)
} }
ItemKind::Use(use_tree) => { ItemKind::Use(use_tree) => {
debug_assert_eq!(ident.name, kw::Empty);
// Start with an empty prefix. // Start with an empty prefix.
let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs) self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
} }
ItemKind::Static(box ast::StaticItem { ItemKind::Static(box ast::StaticItem {
ident,
ty: t, ty: t,
safety: _, safety: _,
mutability: m, mutability: m,
expr: e, expr: e,
define_opaque, define_opaque,
}) => { }) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (ty, body_id) = let (ty, body_id) =
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy); self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
self.lower_define_opaque(hir_id, define_opaque); self.lower_define_opaque(hir_id, define_opaque);
hir::ItemKind::Static(ident, ty, *m, body_id) hir::ItemKind::Static(ident, ty, *m, body_id)
} }
ItemKind::Const(box ast::ConstItem { generics, ty, expr, define_opaque, .. }) => { ItemKind::Const(box ast::ConstItem {
debug_assert_ne!(ident.name, kw::Empty); ident,
let ident = self.lower_ident(ident); generics,
ty,
expr,
define_opaque,
..
}) => {
let ident = self.lower_ident(*ident);
let (generics, (ty, body_id)) = self.lower_generics( let (generics, (ty, body_id)) = self.lower_generics(
generics, generics,
id, id,
@ -214,13 +216,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
ItemKind::Fn(box Fn { ItemKind::Fn(box Fn {
sig: FnSig { decl, header, span: fn_sig_span }, sig: FnSig { decl, header, span: fn_sig_span },
ident,
generics, generics,
body, body,
contract, contract,
define_opaque, define_opaque,
.. ..
}) => { }) => {
debug_assert_ne!(ident.name, kw::Empty);
self.with_new_scopes(*fn_sig_span, |this| { self.with_new_scopes(*fn_sig_span, |this| {
// Note: we don't need to change the return type from `T` to // Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body // `impl Future<Output = T>` here because lower_body
@ -248,7 +250,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: this.lower_span(*fn_sig_span), span: this.lower_span(*fn_sig_span),
}; };
this.lower_define_opaque(hir_id, define_opaque); this.lower_define_opaque(hir_id, define_opaque);
let ident = this.lower_ident(ident); let ident = this.lower_ident(*ident);
hir::ItemKind::Fn { hir::ItemKind::Fn {
ident, ident,
sig, sig,
@ -258,9 +260,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
}) })
} }
ItemKind::Mod(_, mod_kind) => { ItemKind::Mod(_, ident, mod_kind) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
match mod_kind { match mod_kind {
ModKind::Loaded(items, _, spans, _) => { ModKind::Loaded(items, _, spans, _) => {
hir::ItemKind::Mod(ident, self.lower_mod(items, spans)) hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
@ -268,24 +269,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
} }
} }
ItemKind::ForeignMod(fm) => { ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
debug_assert_eq!(ident.name, kw::Empty);
hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)), abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
items: self items: self
.arena .arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
} },
}
ItemKind::GlobalAsm(asm) => { ItemKind::GlobalAsm(asm) => {
debug_assert_eq!(ident.name, kw::Empty);
let asm = self.lower_inline_asm(span, asm); let asm = self.lower_inline_asm(span, asm);
let fake_body = let fake_body =
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
hir::ItemKind::GlobalAsm { asm, fake_body } hir::ItemKind::GlobalAsm { asm, fake_body }
} }
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
debug_assert_ne!(ident.name, kw::Empty);
// We lower // We lower
// //
// type Foo = impl Trait // type Foo = impl Trait
@ -294,7 +290,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// //
// type Foo = Foo1 // type Foo = Foo1
// opaque type Foo1: Trait // opaque type Foo1: Trait
let ident = self.lower_ident(ident); let ident = self.lower_ident(*ident);
let mut generics = generics.clone(); let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, true); add_ty_alias_where_clause(&mut generics, *where_clauses, true);
let (generics, ty) = self.lower_generics( let (generics, ty) = self.lower_generics(
@ -322,9 +318,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::TyAlias(ident, ty, generics) hir::ItemKind::TyAlias(ident, ty, generics)
} }
ItemKind::Enum(enum_definition, generics) => { ItemKind::Enum(ident, enum_definition, generics) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (generics, variants) = self.lower_generics( let (generics, variants) = self.lower_generics(
generics, generics,
id, id,
@ -337,9 +332,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics) hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
} }
ItemKind::Struct(struct_def, generics) => { ItemKind::Struct(ident, struct_def, generics) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (generics, struct_def) = self.lower_generics( let (generics, struct_def) = self.lower_generics(
generics, generics,
id, id,
@ -348,9 +342,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::Struct(ident, struct_def, generics) hir::ItemKind::Struct(ident, struct_def, generics)
} }
ItemKind::Union(vdata, generics) => { ItemKind::Union(ident, vdata, generics) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (generics, vdata) = self.lower_generics( let (generics, vdata) = self.lower_generics(
generics, generics,
id, id,
@ -369,7 +362,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
self_ty: ty, self_ty: ty,
items: impl_items, items: impl_items,
}) => { }) => {
debug_assert_eq!(ident.name, kw::Empty);
// Lower the "impl header" first. This ordering is important // Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here: // for in-band lifetimes! Consider `'a` here:
// //
@ -435,9 +427,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
items: new_impl_items, items: new_impl_items,
})) }))
} }
ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (generics, (safety, items, bounds)) = self.lower_generics( let (generics, (safety, items, bounds)) = self.lower_generics(
generics, generics,
id, id,
@ -456,9 +447,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items) hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
} }
ItemKind::TraitAlias(generics, bounds) => { ItemKind::TraitAlias(ident, generics, bounds) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let (generics, bounds) = self.lower_generics( let (generics, bounds) = self.lower_generics(
generics, generics,
id, id,
@ -472,9 +462,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
hir::ItemKind::TraitAlias(ident, generics, bounds) hir::ItemKind::TraitAlias(ident, generics, bounds)
} }
ItemKind::MacroDef(MacroDef { body, macro_rules }) => { ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(*ident);
let ident = self.lower_ident(ident);
let body = P(self.lower_delim_args(body)); let body = P(self.lower_delim_args(body));
let def_id = self.local_def_id(id); let def_id = self.local_def_id(id);
let def_kind = self.tcx.def_kind(def_id); let def_kind = self.tcx.def_kind(def_id);
@ -488,11 +477,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ItemKind::Macro(ident, macro_def, macro_kind) hir::ItemKind::Macro(ident, macro_def, macro_kind)
} }
ItemKind::Delegation(box delegation) => { ItemKind::Delegation(box delegation) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let delegation_results = self.lower_delegation(delegation, id, false); let delegation_results = self.lower_delegation(delegation, id, false);
hir::ItemKind::Fn { hir::ItemKind::Fn {
ident, ident: delegation_results.ident,
sig: delegation_results.sig, sig: delegation_results.sig,
generics: delegation_results.generics, generics: delegation_results.generics,
body: delegation_results.body_id, body: delegation_results.body_id,
@ -649,24 +636,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let owner_id = hir_id.expect_owner(); let owner_id = hir_id.expect_owner();
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let item = hir::ForeignItem { let (ident, kind) = match &i.kind {
owner_id, ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
ident: self.lower_ident(i.ident),
kind: match &i.kind {
ForeignItemKind::Fn(box Fn { sig, generics, define_opaque, .. }) => {
let fdec = &sig.decl; let fdec = &sig.decl;
let itctx = ImplTraitContext::Universal; let itctx = ImplTraitContext::Universal;
let (generics, (decl, fn_args)) = let (generics, (decl, fn_args)) =
self.lower_generics(generics, i.id, itctx, |this| { self.lower_generics(generics, i.id, itctx, |this| {
( (
// Disallow `impl Trait` in foreign items. // Disallow `impl Trait` in foreign items.
this.lower_fn_decl( this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
fdec,
i.id,
sig.span,
FnDeclKind::ExternFn,
None,
),
this.lower_fn_params_to_names(fdec), this.lower_fn_params_to_names(fdec),
) )
}); });
@ -678,32 +656,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.dcx().span_err(i.span, "foreign functions cannot define opaque types"); self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
} }
(
ident,
hir::ForeignItemKind::Fn( hir::ForeignItemKind::Fn(
hir::FnSig { header, decl, span: self.lower_span(sig.span) }, hir::FnSig { header, decl, span: self.lower_span(sig.span) },
fn_args, fn_args,
generics, generics,
),
) )
} }
ForeignItemKind::Static(box StaticItem { ForeignItemKind::Static(box StaticItem {
ident,
ty, ty,
mutability, mutability,
expr: _, expr: _,
safety, safety,
define_opaque, define_opaque,
}) => { }) => {
let ty = self let ty =
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe); let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
// njn: where for this?
if define_opaque.is_some() { if define_opaque.is_some() {
self.dcx().span_err(i.span, "foreign statics cannot define opaque types"); self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
} }
hir::ForeignItemKind::Static(ty, *mutability, safety) (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
}
ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
(ident, hir::ForeignItemKind::Type)
} }
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
}, };
let item = hir::ForeignItem {
owner_id,
ident: self.lower_ident(*ident),
kind,
vis_span: self.lower_span(i.vis.span), vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span), span: self.lower_span(i.span),
}; };
@ -713,7 +703,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef { fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
hir::ForeignItemRef { hir::ForeignItemRef {
id: hir::ForeignItemId { owner_id: self.owner_id(i.id) }, id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
ident: self.lower_ident(i.ident), // `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
// without an identifier and it cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span), span: self.lower_span(i.span),
} }
} }
@ -800,13 +792,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
debug_assert_ne!(i.ident.name, kw::Empty);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let trait_item_def_id = hir_id.expect_owner(); let trait_item_def_id = hir_id.expect_owner();
let (generics, kind, has_default) = match &i.kind { let (ident, generics, kind, has_default) = match &i.kind {
AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => { AssocItemKind::Const(box ConstItem {
ident,
generics,
ty,
expr,
define_opaque,
..
}) => {
let (generics, kind) = self.lower_generics( let (generics, kind) = self.lower_generics(
generics, generics,
i.id, i.id,
@ -831,9 +829,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
} }
(generics, kind, expr.is_some()) (*ident, generics, kind, expr.is_some())
} }
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => { AssocItemKind::Fn(box Fn {
sig, ident, generics, body: None, define_opaque, ..
}) => {
// FIXME(contracts): Deny contract here since it won't apply to // FIXME(contracts): Deny contract here since it won't apply to
// any impl method or callees. // any impl method or callees.
let names = self.lower_fn_params_to_names(&sig.decl); let names = self.lower_fn_params_to_names(&sig.decl);
@ -851,10 +851,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
"only trait methods with default bodies can define opaque types", "only trait methods with default bodies can define opaque types",
); );
} }
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) (
*ident,
generics,
hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)),
false,
)
} }
AssocItemKind::Fn(box Fn { AssocItemKind::Fn(box Fn {
sig, sig,
ident,
generics, generics,
body: Some(body), body: Some(body),
contract, contract,
@ -880,9 +886,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
attrs, attrs,
); );
self.lower_define_opaque(hir_id, &define_opaque); self.lower_define_opaque(hir_id, &define_opaque);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) (
*ident,
generics,
hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
true,
)
} }
AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => { AssocItemKind::Type(box TyAlias {
ident, generics, where_clauses, bounds, ty, ..
}) => {
let mut generics = generics.clone(); let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false); add_ty_alias_where_clause(&mut generics, *where_clauses, false);
let (generics, kind) = self.lower_generics( let (generics, kind) = self.lower_generics(
@ -905,7 +918,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) )
}, },
); );
(generics, kind, ty.is_some()) (*ident, generics, kind, ty.is_some())
} }
AssocItemKind::Delegation(box delegation) => { AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id, false); let delegation_results = self.lower_delegation(delegation, i.id, false);
@ -913,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
delegation_results.sig, delegation_results.sig,
hir::TraitFn::Provided(delegation_results.body_id), hir::TraitFn::Provided(delegation_results.body_id),
); );
(delegation_results.generics, item_kind, true) (delegation.ident, delegation_results.generics, item_kind, true)
} }
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now") panic!("macros should have been expanded by now")
@ -922,7 +935,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let item = hir::TraitItem { let item = hir::TraitItem {
owner_id: trait_item_def_id, owner_id: trait_item_def_id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(ident),
generics, generics,
kind, kind,
span: self.lower_span(i.span), span: self.lower_span(i.span),
@ -932,15 +945,20 @@ 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 = match &i.kind { let (ident, kind) = match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::Const(box ConstItem { ident, .. }) => {
AssocItemKind::Type(..) => hir::AssocItemKind::Type, (*ident, hir::AssocItemKind::Const)
AssocItemKind::Fn(box Fn { sig, .. }) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
} }
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
(*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
}
AssocItemKind::Delegation(box delegation) => (
delegation.ident,
hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false), has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
}, },
),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now") panic!("macros should have been expanded by now")
} }
@ -948,7 +966,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let id = hir::TraitItemId { owner_id: self.owner_id(i.id) }; let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
hir::TraitItemRef { hir::TraitItemRef {
id, id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(ident),
span: self.lower_span(i.span), span: self.lower_span(i.span),
kind, kind,
} }
@ -964,16 +982,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
i: &AssocItem, i: &AssocItem,
is_in_trait_impl: bool, is_in_trait_impl: bool,
) -> &'hir hir::ImplItem<'hir> { ) -> &'hir hir::ImplItem<'hir> {
debug_assert_ne!(i.ident.name, kw::Empty);
// Since `default impl` is not yet implemented, this is always true in impls. // Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true; let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let (generics, kind) = match &i.kind { let (ident, (generics, kind)) = match &i.kind {
AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => self AssocItemKind::Const(box ConstItem {
.lower_generics( ident,
generics,
ty,
expr,
define_opaque,
..
}) => (
*ident,
self.lower_generics(
generics, generics,
i.id, i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic), ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
@ -982,11 +1007,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let body = this.lower_const_body(i.span, expr.as_deref()); let body = this.lower_const_body(i.span, expr.as_deref());
this.lower_define_opaque(hir_id, &define_opaque); this.lower_define_opaque(hir_id, &define_opaque);
hir::ImplItemKind::Const(ty, body) hir::ImplItemKind::Const(ty, body)
}, },
), ),
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => { ),
AssocItemKind::Fn(box Fn {
sig,
ident,
generics,
body,
contract,
define_opaque,
..
}) => {
let body_id = self.lower_maybe_coroutine_body( let body_id = self.lower_maybe_coroutine_body(
sig.span, sig.span,
i.span, i.span,
@ -1007,11 +1040,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
self.lower_define_opaque(hir_id, &define_opaque); self.lower_define_opaque(hir_id, &define_opaque);
(generics, hir::ImplItemKind::Fn(sig, body_id)) (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
} }
AssocItemKind::Type(box TyAlias { generics, where_clauses, ty, .. }) => { AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
let mut generics = generics.clone(); let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false); add_ty_alias_where_clause(&mut generics, *where_clauses, false);
(
*ident,
self.lower_generics( self.lower_generics(
&generics, &generics,
i.id, i.id,
@ -1038,13 +1073,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Type(ty) hir::ImplItemKind::Type(ty)
} }
}, },
),
) )
} }
AssocItemKind::Delegation(box delegation) => { AssocItemKind::Delegation(box delegation) => {
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl); let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
(
delegation.ident,
( (
delegation_results.generics, delegation_results.generics,
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id), hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
),
) )
} }
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
@ -1054,7 +1093,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let item = hir::ImplItem { let item = hir::ImplItem {
owner_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident), ident: self.lower_ident(ident),
generics, generics,
kind, kind,
vis_span: self.lower_span(i.vis.span), vis_span: self.lower_span(i.vis.span),
@ -1067,7 +1106,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef { fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
hir::ImplItemRef { hir::ImplItemRef {
id: hir::ImplItemId { owner_id: self.owner_id(i.id) }, id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
ident: self.lower_ident(i.ident), // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
// assoc item kinds without an identifier and they cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span), span: self.lower_span(i.span),
kind: match &i.kind { kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::Const(..) => hir::AssocItemKind::Const,

View File

@ -607,7 +607,7 @@ impl<'a> AstValidator<'a> {
fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) { fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) {
if !trait_items.is_empty() { if !trait_items.is_empty() {
let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect(); let spans: Vec<_> = trait_items.iter().map(|i| i.kind.ident().unwrap().span).collect();
let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span); let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span);
self.dcx().emit_err(errors::AutoTraitItems { spans, total, ident }); self.dcx().emit_err(errors::AutoTraitItems { spans, total, ident });
} }
@ -817,8 +817,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.has_proc_macro_decls = true; self.has_proc_macro_decls = true;
} }
if attr::contains_name(&item.attrs, sym::no_mangle) { if let Some(ident) = item.kind.ident()
self.check_nomangle_item_asciionly(item.ident, item.span); && attr::contains_name(&item.attrs, sym::no_mangle)
{
self.check_nomangle_item_asciionly(ident, item.span);
} }
match &item.kind { match &item.kind {
@ -852,7 +854,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
this.visit_vis(&item.vis); this.visit_vis(&item.vis);
this.visit_ident(&item.ident);
let disallowed = matches!(constness, Const::No) let disallowed = matches!(constness, Const::No)
.then(|| TildeConstReason::TraitImpl { span: item.span }); .then(|| TildeConstReason::TraitImpl { span: item.span });
this.with_tilde_const(disallowed, |this| this.visit_generics(generics)); this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
@ -906,7 +907,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
this.visit_vis(&item.vis); this.visit_vis(&item.vis);
this.visit_ident(&item.ident);
this.with_tilde_const( this.with_tilde_const(
Some(TildeConstReason::Impl { span: item.span }), Some(TildeConstReason::Impl { span: item.span }),
|this| this.visit_generics(generics), |this| this.visit_generics(generics),
@ -918,8 +918,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Fn( ItemKind::Fn(
func func @ box Fn {
@ box Fn { defaultness, generics: _, sig, contract: _, body, define_opaque: _ }, defaultness,
ident,
generics: _,
sig,
contract: _,
body,
define_opaque: _,
},
) => { ) => {
self.check_defaultness(item.span, *defaultness); self.check_defaultness(item.span, *defaultness);
@ -949,8 +956,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(&item.ident); self.visit_ident(ident);
let kind = FnKind::Fn(FnCtxt::Free, &item.ident, &item.vis, &*func); let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func);
self.visit_fn(kind, item.span, item.id); self.visit_fn(kind, item.span, item.id);
walk_list!(self, visit_attribute, &item.attrs); walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again. return; // Avoid visiting again.
@ -986,7 +993,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}); });
return; // Avoid visiting again. return; // Avoid visiting again.
} }
ItemKind::Enum(def, _) => { ItemKind::Enum(_, def, _) => {
for variant in &def.variants { for variant in &def.variants {
self.visibility_not_permitted( self.visibility_not_permitted(
&variant.vis, &variant.vis,
@ -1000,22 +1007,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
} }
} }
ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => { ItemKind::Trait(box Trait { is_auto, generics, ident, bounds, items, .. }) => {
let is_const_trait = let is_const_trait =
attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span); attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span);
self.with_in_trait(item.span, is_const_trait, |this| { self.with_in_trait(item.span, is_const_trait, |this| {
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.
this.deny_generic_params(generics, item.ident.span); this.deny_generic_params(generics, ident.span);
this.deny_super_traits(bounds, item.ident.span); this.deny_super_traits(bounds, ident.span);
this.deny_where_clause(&generics.where_clause, item.ident.span); this.deny_where_clause(&generics.where_clause, ident.span);
this.deny_items(items, item.ident.span); this.deny_items(items, ident.span);
} }
// Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
// context for the supertraits. // context for the supertraits.
this.visit_vis(&item.vis); this.visit_vis(&item.vis);
this.visit_ident(&item.ident); this.visit_ident(ident);
let disallowed = is_const_trait let disallowed = is_const_trait
.is_none() .is_none()
.then(|| TildeConstReason::Trait { span: item.span }); .then(|| TildeConstReason::Trait { span: item.span });
@ -1028,7 +1035,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs); walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again return; // Avoid visiting again
} }
ItemKind::Mod(safety, mod_kind) => { ItemKind::Mod(safety, ident, mod_kind) => {
if let &Safety::Unsafe(span) = safety { if let &Safety::Unsafe(span) = safety {
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" }); self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });
} }
@ -1036,13 +1043,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _))
&& !attr::contains_name(&item.attrs, sym::path) && !attr::contains_name(&item.attrs, sym::path)
{ {
self.check_mod_file_item_asciionly(item.ident); self.check_mod_file_item_asciionly(*ident);
} }
} }
ItemKind::Struct(vdata, generics) => match vdata { ItemKind::Struct(ident, vdata, generics) => match vdata {
VariantData::Struct { fields, .. } => { VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(&item.ident); self.visit_ident(ident);
self.visit_generics(generics); self.visit_generics(generics);
// Permit `Anon{Struct,Union}` as field type. // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields); walk_list!(self, visit_struct_field_def, fields);
@ -1051,14 +1058,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
_ => {} _ => {}
}, },
ItemKind::Union(vdata, generics) => { ItemKind::Union(ident, vdata, generics) => {
if vdata.fields().is_empty() { if vdata.fields().is_empty() {
self.dcx().emit_err(errors::FieldlessUnion { span: item.span }); self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
} }
match vdata { match vdata {
VariantData::Struct { fields, .. } => { VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(&item.ident); self.visit_ident(ident);
self.visit_generics(generics); self.visit_generics(generics);
// Permit `Anon{Struct,Union}` as field type. // Permit `Anon{Struct,Union}` as field type.
walk_list!(self, visit_struct_field_def, fields); walk_list!(self, visit_struct_field_def, fields);
@ -1121,14 +1128,15 @@ 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(box Fn { defaultness, sig, body, .. }) => { ForeignItemKind::Fn(box Fn { defaultness, ident, sig, body, .. }) => {
self.check_defaultness(fi.span, *defaultness); self.check_defaultness(fi.span, *defaultness);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref()); self.check_foreign_fn_bodyless(*ident, body.as_deref());
self.check_foreign_fn_headerless(sig.header); self.check_foreign_fn_headerless(sig.header);
self.check_foreign_item_ascii_only(fi.ident); self.check_foreign_item_ascii_only(*ident);
} }
ForeignItemKind::TyAlias(box TyAlias { ForeignItemKind::TyAlias(box TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
@ -1136,15 +1144,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.. ..
}) => { }) => {
self.check_defaultness(fi.span, *defaultness); self.check_defaultness(fi.span, *defaultness);
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span)); self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks"); self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics, where_clauses); self.check_foreign_ty_genericless(generics, where_clauses);
self.check_foreign_item_ascii_only(fi.ident); self.check_foreign_item_ascii_only(*ident);
} }
ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => { ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => {
self.check_item_safety(fi.span, *safety); self.check_item_safety(fi.span, *safety);
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span)); self.check_foreign_kind_bodyless(*ident, "static", expr.as_ref().map(|b| b.span));
self.check_foreign_item_ascii_only(fi.ident); self.check_foreign_item_ascii_only(*ident);
} }
ForeignItemKind::MacCall(..) => {} ForeignItemKind::MacCall(..) => {}
} }
@ -1351,7 +1359,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
if let FnKind::Fn( if let FnKind::Fn(
_,
_, _,
_, _,
Fn { Fn {
@ -1364,7 +1371,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
// Functions without bodies cannot have patterns. // Functions without bodies cannot have patterns.
if let FnKind::Fn(ctxt, _, _, Fn { body: None, sig, .. }) = fk { if let FnKind::Fn(ctxt, _, Fn { body: None, sig, .. }) = fk {
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
if let Some(ident) = ident { if let Some(ident) = ident {
@ -1398,15 +1405,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.is_some(); .is_some();
let disallowed = (!tilde_const_allowed).then(|| match fk { let disallowed = (!tilde_const_allowed).then(|| match fk {
FnKind::Fn(_, ident, _, _) => TildeConstReason::Function { ident: ident.span }, FnKind::Fn(_, _, f) => TildeConstReason::Function { ident: f.ident.span },
FnKind::Closure(..) => TildeConstReason::Closure, FnKind::Closure(..) => TildeConstReason::Closure,
}); });
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk)); self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
} }
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
if attr::contains_name(&item.attrs, sym::no_mangle) { if let Some(ident) = item.kind.ident()
self.check_nomangle_item_asciionly(item.ident, item.span); && attr::contains_name(&item.attrs, sym::no_mangle)
{
self.check_nomangle_item_asciionly(ident, item.span);
} }
if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() { if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
@ -1466,8 +1475,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
} }
if let AssocItemKind::Const(..) = item.kind { if let AssocItemKind::Const(ci) = &item.kind {
self.check_item_named(item.ident, "const"); self.check_item_named(ci.ident, "const");
} }
let parent_is_const = let parent_is_const =
@ -1480,8 +1489,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|| matches!(func.sig.header.constness, Const::Yes(_)) => || matches!(func.sig.header.constness, Const::Yes(_)) =>
{ {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(&item.ident); self.visit_ident(&func.ident);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, &item.vis, &*func); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func);
walk_list!(self, visit_attribute, &item.attrs); walk_list!(self, visit_attribute, &item.attrs);
self.visit_fn(kind, item.span, item.id); self.visit_fn(kind, item.span, item.id);
} }

View File

@ -236,7 +236,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate!(&self, trait_alias, i.span, "trait aliases are experimental"); gate!(&self, trait_alias, i.span, "trait aliases are experimental");
} }
ast::ItemKind::MacroDef(ast::MacroDef { macro_rules: false, .. }) => { ast::ItemKind::MacroDef(_, ast::MacroDef { macro_rules: false, .. }) => {
let msg = "`macro` is experimental"; let msg = "`macro` is experimental";
gate!(&self, decl_macro, i.span, msg); gate!(&self, decl_macro, i.span, msg);
} }

View File

@ -28,23 +28,24 @@ impl<'a> State<'a> {
} }
fn print_foreign_item(&mut self, item: &ast::ForeignItem) { fn print_foreign_item(&mut self, item: &ast::ForeignItem) {
let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
self.ann.pre(self, AnnNode::SubItem(id)); self.ann.pre(self, AnnNode::SubItem(id));
self.hardbreak_if_not_bol(); self.hardbreak_if_not_bol();
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(func) => { ast::ForeignItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func); self.print_fn_full(vis, attrs, &*func);
} }
ast::ForeignItemKind::Static(box ast::StaticItem { ast::ForeignItemKind::Static(box ast::StaticItem {
ident,
ty, ty,
mutability, mutability,
expr, expr,
safety, safety,
define_opaque, define_opaque,
}) => self.print_item_const( }) => self.print_item_const(
ident, *ident,
Some(*mutability), Some(*mutability),
&ast::Generics::default(), &ast::Generics::default(),
ty, ty,
@ -56,13 +57,14 @@ impl<'a> State<'a> {
), ),
ast::ForeignItemKind::TyAlias(box ast::TyAlias { ast::ForeignItemKind::TyAlias(box ast::TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
}) => { }) => {
self.print_associated_type( self.print_associated_type(
ident, *ident,
generics, generics,
*where_clauses, *where_clauses,
bounds, bounds,
@ -162,7 +164,7 @@ impl<'a> State<'a> {
self.print_outer_attributes(&item.attrs); self.print_outer_attributes(&item.attrs);
self.ann.pre(self, AnnNode::Item(item)); self.ann.pre(self, AnnNode::Item(item));
match &item.kind { match &item.kind {
ast::ItemKind::ExternCrate(orig_name) => { ast::ItemKind::ExternCrate(orig_name, ident) => {
self.head(visibility_qualified(&item.vis, "extern crate")); self.head(visibility_qualified(&item.vis, "extern crate"));
if let &Some(orig_name) = orig_name { if let &Some(orig_name) = orig_name {
self.print_name(orig_name); self.print_name(orig_name);
@ -170,7 +172,7 @@ impl<'a> State<'a> {
self.word("as"); self.word("as");
self.space(); self.space();
} }
self.print_ident(item.ident); self.print_ident(*ident);
self.word(";"); self.word(";");
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
@ -182,6 +184,7 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
} }
ast::ItemKind::Static(box StaticItem { ast::ItemKind::Static(box StaticItem {
ident,
ty, ty,
safety, safety,
mutability: mutbl, mutability: mutbl,
@ -190,7 +193,7 @@ impl<'a> State<'a> {
}) => { }) => {
self.print_safety(*safety); self.print_safety(*safety);
self.print_item_const( self.print_item_const(
item.ident, *ident,
Some(*mutbl), Some(*mutbl),
&ast::Generics::default(), &ast::Generics::default(),
ty, ty,
@ -203,13 +206,14 @@ impl<'a> State<'a> {
} }
ast::ItemKind::Const(box ast::ConstItem { ast::ItemKind::Const(box ast::ConstItem {
defaultness, defaultness,
ident,
generics, generics,
ty, ty,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
self.print_item_const( self.print_item_const(
item.ident, *ident,
None, None,
generics, generics,
ty, ty,
@ -221,15 +225,15 @@ impl<'a> State<'a> {
); );
} }
ast::ItemKind::Fn(func) => { ast::ItemKind::Fn(func) => {
self.print_fn_full(item.ident, &item.vis, &item.attrs, &*func); self.print_fn_full(&item.vis, &item.attrs, &*func);
} }
ast::ItemKind::Mod(safety, mod_kind) => { ast::ItemKind::Mod(safety, ident, mod_kind) => {
self.head(Self::to_string(|s| { self.head(Self::to_string(|s| {
s.print_visibility(&item.vis); s.print_visibility(&item.vis);
s.print_safety(*safety); s.print_safety(*safety);
s.word("mod"); s.word("mod");
})); }));
self.print_ident(item.ident); self.print_ident(*ident);
match mod_kind { match mod_kind {
ModKind::Loaded(items, ..) => { ModKind::Loaded(items, ..) => {
@ -273,13 +277,14 @@ impl<'a> State<'a> {
} }
ast::ItemKind::TyAlias(box ast::TyAlias { ast::ItemKind::TyAlias(box ast::TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
}) => { }) => {
self.print_associated_type( self.print_associated_type(
item.ident, *ident,
generics, generics,
*where_clauses, *where_clauses,
bounds, bounds,
@ -288,16 +293,16 @@ impl<'a> State<'a> {
*defaultness, *defaultness,
); );
} }
ast::ItemKind::Enum(enum_definition, params) => { ast::ItemKind::Enum(ident, enum_definition, params) => {
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); self.print_enum_def(enum_definition, params, *ident, item.span, &item.vis);
} }
ast::ItemKind::Struct(struct_def, generics) => { ast::ItemKind::Struct(ident, struct_def, generics) => {
self.head(visibility_qualified(&item.vis, "struct")); self.head(visibility_qualified(&item.vis, "struct"));
self.print_struct(struct_def, generics, item.ident, item.span, true); self.print_struct(struct_def, generics, *ident, item.span, true);
} }
ast::ItemKind::Union(struct_def, generics) => { ast::ItemKind::Union(ident, struct_def, generics) => {
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, *ident, item.span, true);
} }
ast::ItemKind::Impl(box ast::Impl { ast::ItemKind::Impl(box ast::Impl {
safety, safety,
@ -347,19 +352,19 @@ impl<'a> State<'a> {
self.bclose(item.span, empty); self.bclose(item.span, empty);
} }
ast::ItemKind::Trait(box ast::Trait { ast::ItemKind::Trait(box ast::Trait {
is_auto,
safety, safety,
is_auto,
ident,
generics, generics,
bounds, bounds,
items, items,
..
}) => { }) => {
self.head(""); self.head("");
self.print_visibility(&item.vis); self.print_visibility(&item.vis);
self.print_safety(*safety); self.print_safety(*safety);
self.print_is_auto(*is_auto); self.print_is_auto(*is_auto);
self.word_nbsp("trait"); self.word_nbsp("trait");
self.print_ident(item.ident); self.print_ident(*ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
if !bounds.is_empty() { if !bounds.is_empty() {
self.word_nbsp(":"); self.word_nbsp(":");
@ -375,9 +380,9 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && items.is_empty(); let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, empty); self.bclose(item.span, empty);
} }
ast::ItemKind::TraitAlias(generics, bounds) => { ast::ItemKind::TraitAlias(ident, generics, bounds) => {
self.head(visibility_qualified(&item.vis, "trait")); self.head(visibility_qualified(&item.vis, "trait"));
self.print_ident(item.ident); self.print_ident(*ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.nbsp(); self.nbsp();
if !bounds.is_empty() { if !bounds.is_empty() {
@ -395,8 +400,8 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
} }
} }
ast::ItemKind::MacroDef(macro_def) => { ast::ItemKind::MacroDef(ident, macro_def) => {
self.print_mac_def(macro_def, &item.ident, item.span, |state| { self.print_mac_def(macro_def, &ident, item.span, |state| {
state.print_visibility(&item.vis) state.print_visibility(&item.vis)
}); });
} }
@ -549,24 +554,25 @@ impl<'a> State<'a> {
} }
fn print_assoc_item(&mut self, item: &ast::AssocItem) { fn print_assoc_item(&mut self, item: &ast::AssocItem) {
let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; let ast::Item { id, span, ref attrs, ref kind, ref vis, tokens: _ } = *item;
self.ann.pre(self, AnnNode::SubItem(id)); self.ann.pre(self, AnnNode::SubItem(id));
self.hardbreak_if_not_bol(); self.hardbreak_if_not_bol();
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(func) => { ast::AssocItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func); self.print_fn_full(vis, attrs, &*func);
} }
ast::AssocItemKind::Const(box ast::ConstItem { ast::AssocItemKind::Const(box ast::ConstItem {
defaultness, defaultness,
ident,
generics, generics,
ty, ty,
expr, expr,
define_opaque, define_opaque,
}) => { }) => {
self.print_item_const( self.print_item_const(
ident, *ident,
None, None,
generics, generics,
ty, ty,
@ -579,13 +585,14 @@ impl<'a> State<'a> {
} }
ast::AssocItemKind::Type(box ast::TyAlias { ast::AssocItemKind::Type(box ast::TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
}) => { }) => {
self.print_associated_type( self.print_associated_type(
ident, *ident,
generics, generics,
*where_clauses, *where_clauses,
bounds, bounds,
@ -671,14 +678,8 @@ impl<'a> State<'a> {
} }
} }
fn print_fn_full( fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
&mut self, let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque } = func;
name: Ident,
vis: &ast::Visibility,
attrs: &[ast::Attribute],
func: &ast::Fn,
) {
let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
self.print_define_opaques(define_opaque.as_deref()); self.print_define_opaques(define_opaque.as_deref());
@ -687,7 +688,7 @@ impl<'a> State<'a> {
} }
self.print_visibility(vis); self.print_visibility(vis);
self.print_defaultness(*defaultness); self.print_defaultness(*defaultness);
self.print_fn(&sig.decl, sig.header, Some(name), generics); self.print_fn(&sig.decl, sig.header, Some(*ident), generics);
if let Some(contract) = &contract { if let Some(contract) = &contract {
self.nbsp(); self.nbsp();
self.print_contract(contract); self.print_contract(contract);
@ -734,13 +735,13 @@ impl<'a> State<'a> {
&mut self, &mut self,
decl: &ast::FnDecl, decl: &ast::FnDecl,
header: ast::FnHeader, header: ast::FnHeader,
name: Option<Ident>, ident: Option<Ident>,
generics: &ast::Generics, generics: &ast::Generics,
) { ) {
self.print_fn_header_info(header); self.print_fn_header_info(header);
if let Some(name) = name { if let Some(ident) = ident {
self.nbsp(); self.nbsp();
self.print_ident(name); self.print_ident(ident);
} }
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.print_fn_params_and_ret(decl, false); self.print_fn_params_and_ret(decl, false);

View File

@ -21,15 +21,15 @@ pub(crate) fn expand(
// Allow using `#[alloc_error_handler]` on an item statement // Allow using `#[alloc_error_handler]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here // FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, sig_span) = if let Annotatable::Item(item) = &item let (item, ident, is_stmt, sig_span) = if let Annotatable::Item(item) = &item
&& let ItemKind::Fn(fn_kind) = &item.kind && let ItemKind::Fn(fn_kind) = &item.kind
{ {
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)) (item, fn_kind.ident, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else if let Annotatable::Stmt(stmt) = &item } else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind && let StmtKind::Item(item) = &stmt.kind
&& let ItemKind::Fn(fn_kind) = &item.kind && let ItemKind::Fn(fn_kind) = &item.kind
{ {
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) (item, fn_kind.ident, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else { } else {
ecx.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() }); ecx.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
return vec![orig_item]; return vec![orig_item];
@ -39,7 +39,7 @@ pub(crate) fn expand(
let span = ecx.with_def_site_ctxt(item.span); let span = ecx.with_def_site_ctxt(item.span);
// Generate item statements for the allocator methods. // Generate item statements for the allocator methods.
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)]; let stmts = thin_vec![generate_handler(ecx, ident, span, sig_span)];
// Generate anonymous constant serving as container for the allocator methods. // Generate anonymous constant serving as container for the allocator methods.
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
@ -85,6 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
let kind = ItemKind::Fn(Box::new(Fn { let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
sig, sig,
ident: Ident::from_str_and_span("__rg_oom", span),
generics: Generics::default(), generics: Generics::default(),
contract: None, contract: None,
body, body,
@ -93,6 +94,6 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind); let item = cx.item(span, attrs, kind);
cx.stmt_item(sig_span, item) cx.stmt_item(sig_span, item)
} }

View File

@ -10,7 +10,7 @@ use rustc_index::bit_set::GrowableBitSet;
use rustc_parse::exp; use rustc_parse::exp;
use rustc_parse::parser::{ExpKeywordPair, Parser}; use rustc_parse::parser::{ExpKeywordPair, Parser};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::{ErrorGuaranteed, Ident, InnerSpan, Span, Symbol, kw}; use rustc_span::{ErrorGuaranteed, InnerSpan, Span, Symbol, kw};
use rustc_target::asm::InlineAsmArch; use rustc_target::asm::InlineAsmArch;
use smallvec::smallvec; use smallvec::smallvec;
use {rustc_ast as ast, rustc_parse_format as parse}; use {rustc_ast as ast, rustc_parse_format as parse};
@ -888,7 +888,6 @@ pub(super) fn expand_global_asm<'cx>(
}; };
match mac { match mac {
Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item { Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
ident: Ident::empty(),
attrs: ast::AttrVec::new(), attrs: ast::AttrVec::new(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),

View File

@ -112,7 +112,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
self.span, self.span,
self.cx.item( self.cx.item(
self.span, self.span,
Ident::empty(),
thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)], thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)],
ItemKind::Use(UseTree { ItemKind::Use(UseTree {
prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),

View File

@ -146,26 +146,26 @@ mod llvm_enzyme {
} }
let dcx = ecx.sess.dcx(); let dcx = ecx.sess.dcx();
// first get the annotable item: // first get the annotable item:
let (sig, is_impl): (FnSig, bool) = match &item { let (primal, sig, is_impl): (Ident, FnSig, bool) = match &item {
Annotatable::Item(iitem) => { Annotatable::Item(iitem) => {
let sig = match &iitem.kind { let (ident, sig) = match &iitem.kind {
ItemKind::Fn(box ast::Fn { sig, .. }) => sig, ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => { _ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item]; return vec![item];
} }
}; };
(sig.clone(), false) (*ident, sig.clone(), false)
} }
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => { Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
let sig = match &assoc_item.kind { let (ident, sig) = match &assoc_item.kind {
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig, ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
_ => { _ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item]; return vec![item];
} }
}; };
(sig.clone(), true) (*ident, sig.clone(), true)
} }
_ => { _ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
@ -184,11 +184,9 @@ mod llvm_enzyme {
let has_ret = has_ret(&sig.decl.output); let has_ret = has_ret(&sig.decl.output);
let sig_span = ecx.with_call_site_ctxt(sig.span); let sig_span = ecx.with_call_site_ctxt(sig.span);
let (vis, primal) = match &item { let vis = match &item {
Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()), Annotatable::Item(iitem) => iitem.vis.clone(),
Annotatable::AssocItem(assoc_item, _) => { Annotatable::AssocItem(assoc_item, _) => assoc_item.vis.clone(),
(assoc_item.vis.clone(), assoc_item.ident.clone())
}
_ => { _ => {
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
return vec![item]; return vec![item];
@ -237,12 +235,12 @@ mod llvm_enzyme {
let d_body = gen_enzyme_body( let d_body = gen_enzyme_body(
ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored, ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored,
); );
let d_ident = first_ident(&meta_item_vec[0]);
// The first element of it is the name of the function to be generated // The first element of it is the name of the function to be generated
let asdf = Box::new(ast::Fn { let asdf = Box::new(ast::Fn {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
sig: d_sig, sig: d_sig,
ident: first_ident(&meta_item_vec[0]),
generics: Generics::default(), generics: Generics::default(),
contract: None, contract: None,
body: Some(d_body), body: Some(d_body),
@ -323,14 +321,12 @@ mod llvm_enzyme {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span, span,
vis, vis,
ident: d_ident,
kind: assoc_item, kind: assoc_item,
tokens: None, tokens: None,
}); });
Annotatable::AssocItem(d_fn, Impl { of_trait: false }) Annotatable::AssocItem(d_fn, Impl { of_trait: false })
} else { } else {
let mut d_fn = let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
d_fn.vis = vis; d_fn.vis = vis;
Annotatable::Item(d_fn) Annotatable::Item(d_fn)
}; };

View File

@ -34,8 +34,8 @@ pub(crate) fn expand_deriving_clone(
let is_simple; let is_simple;
match item { match item {
Annotatable::Item(annitem) => match &annitem.kind { Annotatable::Item(annitem) => match &annitem.kind {
ItemKind::Struct(_, Generics { params, .. }) ItemKind::Struct(_, _, Generics { params, .. })
| ItemKind::Enum(_, Generics { params, .. }) => { | ItemKind::Enum(_, _, Generics { params, .. }) => {
let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
let has_derive_copy = cx.resolver.has_derive_copy(container_id); let has_derive_copy = cx.resolver.has_derive_copy(container_id);
if has_derive_copy if has_derive_copy

View File

@ -21,7 +21,7 @@ pub(crate) fn expand_deriving_partial_ord(
// Order in which to perform matching // Order in which to perform matching
let discr_then_data = if let Annotatable::Item(item) = item let discr_then_data = if let Annotatable::Item(item) = item
&& let ItemKind::Enum(def, _) = &item.kind && let ItemKind::Enum(_, def, _) = &item.kind
{ {
let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect(); let dataful: Vec<bool> = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect();
match dataful.iter().filter(|&&b| b).count() { match dataful.iter().filter(|&&b| b).count() {

View File

@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
item.visit_with(&mut DetectNonGenericPointeeAttr { cx }); item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
let (name_ident, generics) = if let Annotatable::Item(aitem) = item let (name_ident, generics) = if let Annotatable::Item(aitem) = item
&& let ItemKind::Struct(struct_data, g) = &aitem.kind && let ItemKind::Struct(ident, struct_data, g) = &aitem.kind
{ {
if !matches!( if !matches!(
struct_data, struct_data,
@ -40,7 +40,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
cx.dcx().emit_err(RequireOneField { span }); cx.dcx().emit_err(RequireOneField { span });
return; return;
} }
(aitem.ident, g) (*ident, g)
} else { } else {
cx.dcx().emit_err(RequireTransparent { span }); cx.dcx().emit_err(RequireTransparent { span });
return; return;
@ -108,7 +108,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
push(Annotatable::Item( push(Annotatable::Item(
cx.item( cx.item(
span, span,
Ident::empty(),
attrs.clone(), attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl { ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default, safety: ast::Safety::Default,
@ -153,7 +152,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
let trait_ref = cx.trait_ref(trait_path); let trait_ref = cx.trait_ref(trait_path);
let item = cx.item( let item = cx.item(
span, span,
Ident::empty(),
attrs.clone(), attrs.clone(),
ast::ItemKind::Impl(Box::new(ast::Impl { ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default, safety: ast::Safety::Default,

View File

@ -487,28 +487,28 @@ impl<'a> TraitDef<'a> {
); );
let newitem = match &item.kind { let newitem = match &item.kind {
ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def( ast::ItemKind::Struct(ident, struct_def, generics) => self.expand_struct_def(
cx, cx,
struct_def, struct_def,
item.ident, *ident,
generics, generics,
from_scratch, from_scratch,
is_packed, is_packed,
), ),
ast::ItemKind::Enum(enum_def, generics) => { ast::ItemKind::Enum(ident, enum_def, generics) => {
// We ignore `is_packed` here, because `repr(packed)` // We ignore `is_packed` here, because `repr(packed)`
// enums cause an error later on. // enums cause an error later on.
// //
// This can only cause further compilation errors // This can only cause further compilation errors
// downstream in blatantly illegal code, so it is fine. // downstream in blatantly illegal code, so it is fine.
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch) self.expand_enum_def(cx, enum_def, *ident, generics, from_scratch)
} }
ast::ItemKind::Union(struct_def, generics) => { ast::ItemKind::Union(ident, struct_def, generics) => {
if self.supports_unions { if self.supports_unions {
self.expand_struct_def( self.expand_struct_def(
cx, cx,
struct_def, struct_def,
item.ident, *ident,
generics, generics,
from_scratch, from_scratch,
is_packed, is_packed,
@ -596,7 +596,6 @@ impl<'a> TraitDef<'a> {
P(ast::AssocItem { P(ast::AssocItem {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span: self.span, span: self.span,
ident,
vis: ast::Visibility { vis: ast::Visibility {
span: self.span.shrink_to_lo(), span: self.span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited, kind: ast::VisibilityKind::Inherited,
@ -605,6 +604,7 @@ impl<'a> TraitDef<'a> {
attrs: ast::AttrVec::new(), attrs: ast::AttrVec::new(),
kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias { kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
ident,
generics: Generics::default(), generics: Generics::default(),
where_clauses: ast::TyAliasWhereClauses::default(), where_clauses: ast::TyAliasWhereClauses::default(),
bounds: Vec::new(), bounds: Vec::new(),
@ -789,7 +789,6 @@ impl<'a> TraitDef<'a> {
cx.item( cx.item(
self.span, self.span,
Ident::empty(),
attrs, attrs,
ast::ItemKind::Impl(Box::new(ast::Impl { ast::ItemKind::Impl(Box::new(ast::Impl {
safety: ast::Safety::Default, safety: ast::Safety::Default,
@ -1033,10 +1032,10 @@ impl<'a> MethodDef<'a> {
kind: ast::VisibilityKind::Inherited, kind: ast::VisibilityKind::Inherited,
tokens: None, tokens: None,
}, },
ident: method_ident,
kind: ast::AssocItemKind::Fn(Box::new(ast::Fn { kind: ast::AssocItemKind::Fn(Box::new(ast::Fn {
defaultness, defaultness,
sig, sig,
ident: method_ident,
generics: fn_generics, generics: fn_generics,
contract: None, contract: None,
body: Some(body_block), body: Some(body_block),

View File

@ -25,15 +25,15 @@ pub(crate) fn expand(
// Allow using `#[global_allocator]` on an item statement // Allow using `#[global_allocator]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here // FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, ty_span) = if let Annotatable::Item(item) = &item let (item, ident, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
&& let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind && let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
{ {
(item, false, ecx.with_def_site_ctxt(ty.span)) (item, *ident, false, ecx.with_def_site_ctxt(ty.span))
} else if let Annotatable::Stmt(stmt) = &item } else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind && let StmtKind::Item(item) = &stmt.kind
&& let ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind && let ItemKind::Static(box ast::StaticItem { ident, ty, .. }) = &item.kind
{ {
(item, true, ecx.with_def_site_ctxt(ty.span)) (item, *ident, true, ecx.with_def_site_ctxt(ty.span))
} else { } else {
ecx.dcx().emit_err(errors::AllocMustStatics { span: item.span() }); ecx.dcx().emit_err(errors::AllocMustStatics { span: item.span() });
return vec![orig_item]; return vec![orig_item];
@ -41,7 +41,7 @@ pub(crate) fn expand(
// Generate a bunch of new items using the AllocFnFactory // Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span); let span = ecx.with_def_site_ctxt(item.span);
let f = AllocFnFactory { span, ty_span, global: item.ident, cx: ecx }; let f = AllocFnFactory { span, ty_span, global: ident, cx: ecx };
// Generate item statements for the allocator methods. // Generate item statements for the allocator methods.
let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect(); let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();
@ -80,17 +80,13 @@ impl AllocFnFactory<'_, '_> {
let kind = ItemKind::Fn(Box::new(Fn { let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
sig, sig,
ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span),
generics: Generics::default(), generics: Generics::default(),
contract: None, contract: None,
body, body,
define_opaque: None, define_opaque: None,
})); }));
let item = self.cx.item( let item = self.cx.item(self.span, self.attrs(), kind);
self.span,
Ident::from_str_and_span(&global_fn_name(method.name), self.span),
self.attrs(),
kind,
);
self.cx.stmt_item(self.ty_span, item) self.cx.stmt_item(self.ty_span, item)
} }

View File

@ -92,7 +92,12 @@ impl<'a> CollectProcMacros<'a> {
} }
} }
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) { fn collect_custom_derive(
&mut self,
item: &'a ast::Item,
function_name: Ident,
attr: &'a ast::Attribute,
) {
let Some((trait_name, proc_attrs)) = let Some((trait_name, proc_attrs)) =
parse_macro_name_and_helper_attrs(self.dcx, attr, "derive") parse_macro_name_and_helper_attrs(self.dcx, attr, "derive")
else { else {
@ -104,7 +109,7 @@ impl<'a> CollectProcMacros<'a> {
id: item.id, id: item.id,
span: item.span, span: item.span,
trait_name, trait_name,
function_name: item.ident, function_name,
attrs: proc_attrs, attrs: proc_attrs,
})); }));
} else { } else {
@ -118,12 +123,12 @@ impl<'a> CollectProcMacros<'a> {
} }
} }
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) { fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
if self.in_root && item.vis.kind.is_pub() { if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Attr(ProcMacroDef { self.macros.push(ProcMacro::Attr(ProcMacroDef {
id: item.id, id: item.id,
span: item.span, span: item.span,
function_name: item.ident, function_name,
})); }));
} else { } else {
let msg = if !self.in_root { let msg = if !self.in_root {
@ -136,12 +141,12 @@ impl<'a> CollectProcMacros<'a> {
} }
} }
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) { fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, function_name: Ident) {
if self.in_root && item.vis.kind.is_pub() { if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Bang(ProcMacroDef { self.macros.push(ProcMacro::Bang(ProcMacroDef {
id: item.id, id: item.id,
span: item.span, span: item.span,
function_name: item.ident, function_name,
})); }));
} else { } else {
let msg = if !self.in_root { let msg = if !self.in_root {
@ -165,12 +170,6 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
} }
} }
// First up, make sure we're checking a bare function. If we're not then
// we're just not interested in this item.
//
// If we find one, try to locate a `#[proc_macro_derive]` attribute on it.
let is_fn = matches!(item.kind, ast::ItemKind::Fn(..));
let mut found_attr: Option<&'a ast::Attribute> = None; let mut found_attr: Option<&'a ast::Attribute> = None;
for attr in &item.attrs { for attr in &item.attrs {
@ -214,7 +213,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
return; return;
}; };
if !is_fn { // Make sure we're checking a bare function. If we're not then we're
// just not interested any further in this item.
let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
fn_.ident
} else {
self.dcx self.dcx
.create_err(errors::AttributeOnlyBeUsedOnBareFunctions { .create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
span: attr.span, span: attr.span,
@ -222,7 +225,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
}) })
.emit(); .emit();
return; return;
} };
if self.is_test_crate { if self.is_test_crate {
return; return;
@ -238,12 +241,13 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
return; return;
} }
// Try to locate a `#[proc_macro_derive]` attribute.
if attr.has_name(sym::proc_macro_derive) { if attr.has_name(sym::proc_macro_derive) {
self.collect_custom_derive(item, attr); self.collect_custom_derive(item, fn_ident, attr);
} else if attr.has_name(sym::proc_macro_attribute) { } else if attr.has_name(sym::proc_macro_attribute) {
self.collect_attr_proc_macro(item); self.collect_attr_proc_macro(item, fn_ident);
} else if attr.has_name(sym::proc_macro) { } else if attr.has_name(sym::proc_macro) {
self.collect_bang_proc_macro(item); self.collect_bang_proc_macro(item, fn_ident);
}; };
let prev_in_root = mem::replace(&mut self.in_root, false); let prev_in_root = mem::replace(&mut self.in_root, false);
@ -278,7 +282,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
let proc_macro = Ident::new(sym::proc_macro, span); let proc_macro = Ident::new(sym::proc_macro, span);
let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); let krate = cx.item(span, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, proc_macro));
let bridge = Ident::new(sym::bridge, span); let bridge = Ident::new(sym::bridge, span);
let client = Ident::new(sym::client, span); let client = Ident::new(sym::client, span);

View File

@ -43,9 +43,8 @@ pub fn inject(
let item = cx.item( let item = cx.item(
span, span,
Ident::new(name, ident_span),
thin_vec![cx.attr_word(sym::macro_use, span)], thin_vec![cx.attr_word(sym::macro_use, span)],
ast::ItemKind::ExternCrate(None), ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)),
); );
krate.items.insert(0, item); krate.items.insert(0, item);
@ -68,7 +67,6 @@ pub fn inject(
// Inject the relevant crate's prelude. // Inject the relevant crate's prelude.
let use_item = cx.item( let use_item = cx.item(
span, span,
Ident::empty(),
thin_vec![cx.attr_word(sym::prelude_import, span)], thin_vec![cx.attr_word(sym::prelude_import, span)],
ast::ItemKind::Use(ast::UseTree { ast::ItemKind::Use(ast::UseTree {
prefix: cx.path(span, import_path), prefix: cx.path(span, import_path),

View File

@ -51,21 +51,28 @@ pub(crate) fn expand_test_case(
return vec![]; return vec![];
} }
}; };
item = item.map(|mut item| {
// `#[test_case]` is valid on functions, consts, and statics. Only modify
// the item in those cases.
match &mut item.kind {
ast::ItemKind::Fn(box ast::Fn { ident, .. })
| ast::ItemKind::Const(box ast::ConstItem { ident, .. })
| ast::ItemKind::Static(box ast::StaticItem { ident, .. }) => {
ident.span = ident.span.with_ctxt(sp.ctxt());
let test_path_symbol = Symbol::intern(&item_path( let test_path_symbol = Symbol::intern(&item_path(
// skip the name of the root module // skip the name of the root module
&ecx.current_expansion.module.mod_path[1..], &ecx.current_expansion.module.mod_path[1..],
&item.ident, ident,
)); ));
item.vis = ast::Visibility { item.vis = ast::Visibility {
span: item.vis.span, span: item.vis.span,
kind: ast::VisibilityKind::Public, kind: ast::VisibilityKind::Public,
tokens: None, tokens: None,
}; };
item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp)); item.attrs.push(ecx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, sp));
item }
}); _ => {}
}
let ret = if is_stmt { let ret = if is_stmt {
Annotatable::Stmt(P(ecx.stmt_item(item.span, item))) Annotatable::Stmt(P(ecx.stmt_item(item.span, item)))
@ -162,17 +169,17 @@ pub(crate) fn expand_test_or_bench(
let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span()); let ret_ty_sp = cx.with_def_site_ctxt(fn_.sig.decl.output.span());
let attr_sp = cx.with_def_site_ctxt(attr_sp); let attr_sp = cx.with_def_site_ctxt(attr_sp);
let test_id = Ident::new(sym::test, attr_sp); let test_ident = Ident::new(sym::test, attr_sp);
// creates test::$name // creates test::$name
let test_path = |name| cx.path(ret_ty_sp, vec![test_id, Ident::from_str_and_span(name, sp)]); let test_path = |name| cx.path(ret_ty_sp, vec![test_ident, Ident::from_str_and_span(name, sp)]);
// creates test::ShouldPanic::$name // creates test::ShouldPanic::$name
let should_panic_path = |name| { let should_panic_path = |name| {
cx.path( cx.path(
sp, sp,
vec![ vec![
test_id, test_ident,
Ident::from_str_and_span("ShouldPanic", sp), Ident::from_str_and_span("ShouldPanic", sp),
Ident::from_str_and_span(name, sp), Ident::from_str_and_span(name, sp),
], ],
@ -184,7 +191,7 @@ pub(crate) fn expand_test_or_bench(
cx.path( cx.path(
sp, sp,
vec![ vec![
test_id, test_ident,
Ident::from_str_and_span("TestType", sp), Ident::from_str_and_span("TestType", sp),
Ident::from_str_and_span(name, sp), Ident::from_str_and_span(name, sp),
], ],
@ -223,7 +230,7 @@ pub(crate) fn expand_test_or_bench(
// super::$test_fn(b) // super::$test_fn(b)
cx.expr_call( cx.expr_call(
ret_ty_sp, ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])), cx.expr_path(cx.path(sp, vec![fn_.ident])),
thin_vec![cx.expr_ident(sp, b)], thin_vec![cx.expr_ident(sp, b)],
), ),
], ],
@ -249,7 +256,7 @@ pub(crate) fn expand_test_or_bench(
// $test_fn() // $test_fn()
cx.expr_call( cx.expr_call(
ret_ty_sp, ret_ty_sp,
cx.expr_path(cx.path(sp, vec![item.ident])), cx.expr_path(cx.path(sp, vec![fn_.ident])),
ThinVec::new(), ThinVec::new(),
), // ) ), // )
], ],
@ -262,15 +269,14 @@ pub(crate) fn expand_test_or_bench(
let test_path_symbol = Symbol::intern(&item_path( let test_path_symbol = Symbol::intern(&item_path(
// skip the name of the root module // skip the name of the root module
&cx.current_expansion.module.mod_path[1..], &cx.current_expansion.module.mod_path[1..],
&item.ident, &fn_.ident,
)); ));
let location_info = get_location_info(cx, &item); let location_info = get_location_info(cx, &fn_);
let mut test_const = let mut test_const =
cx.item( cx.item(
sp, sp,
Ident::new(item.ident.name, sp),
thin_vec![ thin_vec![
// #[cfg(test)] // #[cfg(test)]
cx.attr_nested_word(sym::cfg, sym::test, attr_sp), cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
@ -283,6 +289,7 @@ pub(crate) fn expand_test_or_bench(
ast::ItemKind::Const( ast::ItemKind::Const(
ast::ConstItem { ast::ConstItem {
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
ident: Ident::new(fn_.ident.name, sp),
generics: ast::Generics::default(), generics: ast::Generics::default(),
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
define_opaque: None, define_opaque: None,
@ -380,7 +387,8 @@ pub(crate) fn expand_test_or_bench(
}); });
// extern crate test // extern crate test
let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); let test_extern =
cx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident));
debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
@ -434,8 +442,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
.emit(); .emit();
} }
fn get_location_info(cx: &ExtCtxt<'_>, item: &ast::Item) -> (Symbol, usize, usize, usize, usize) { fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
let span = item.ident.span; let span = fn_.ident.span;
let (source_file, lo_line, lo_col, hi_line, hi_col) = let (source_file, lo_line, lo_col, hi_line, hi_col) =
cx.sess.source_map().span_to_location_info(span); cx.sess.source_map().span_to_location_info(span);

View File

@ -134,27 +134,21 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
if let Some(name) = get_test_name(&item) { if let Some(name) = get_test_name(&item) {
debug!("this is a test item"); debug!("this is a test item");
let test = Test { span: item.span, ident: item.ident, name }; // `unwrap` is ok because only functions, consts, and static should reach here.
let test = Test { span: item.span, ident: item.kind.ident().unwrap(), name };
self.tests.push(test); self.tests.push(test);
} }
// We don't want to recurse into anything other than mods, since // We don't want to recurse into anything other than mods, since
// mods or tests inside of functions will break things // mods or tests inside of functions will break things
if let ast::ItemKind::Mod( if let ast::ItemKind::Mod(
_,
_, _,
ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _), ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
) = item.kind ) = item.kind
{ {
let prev_tests = mem::take(&mut self.tests); let prev_tests = mem::take(&mut self.tests);
walk_item_kind( walk_item_kind(&mut item.kind, item.span, item.id, &mut item.vis, (), self);
&mut item.kind,
item.span,
item.id,
&mut item.ident,
&mut item.vis,
(),
self,
);
self.add_test_cases(item.id, span, prev_tests); self.add_test_cases(item.id, span, prev_tests);
} else { } else {
// But in those cases, we emit a lint to warn the user of these missing tests. // But in those cases, we emit a lint to warn the user of these missing tests.
@ -181,9 +175,9 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> {
} }
fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType { fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType {
match item.kind { match &item.kind {
ast::ItemKind::Fn(..) => { ast::ItemKind::Fn(fn_) => {
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(item.ident.name)) rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name))
} }
_ => EntryPointType::None, _ => EntryPointType::None,
} }
@ -295,7 +289,7 @@ fn generate_test_harness(
fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let sp = cx.def_site; let sp = cx.def_site;
let ecx = &cx.ext_cx; let ecx = &cx.ext_cx;
let test_id = Ident::new(sym::test, sp); let test_ident = Ident::new(sym::test, sp);
let runner_name = match cx.panic_strategy { let runner_name = match cx.panic_strategy {
PanicStrategy::Unwind => "test_main_static", PanicStrategy::Unwind => "test_main_static",
@ -303,10 +297,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
}; };
// test::test_main_static(...) // test::test_main_static(...)
let mut test_runner = cx let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
.test_runner ecx.path(sp, vec![test_ident, Ident::from_str_and_span(runner_name, sp)])
.clone() });
.unwrap_or_else(|| ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
test_runner.span = sp; test_runner.span = sp;
@ -317,7 +310,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
// extern crate test // extern crate test
let test_extern_stmt = ecx.stmt_item( let test_extern_stmt = ecx.stmt_item(
sp, sp,
ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)), ecx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident)),
); );
// #[rustc_main] // #[rustc_main]
@ -340,23 +333,24 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty)); let decl = ecx.fn_decl(ThinVec::new(), 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 defaultness = ast::Defaultness::Final; let defaultness = ast::Defaultness::Final;
// Honor the reexport_test_harness_main attribute
let main_ident = match cx.reexport_test_harness_main {
Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
None => Ident::new(sym::main, sp),
};
let main = ast::ItemKind::Fn(Box::new(ast::Fn { let main = ast::ItemKind::Fn(Box::new(ast::Fn {
defaultness, defaultness,
sig, sig,
ident: main_ident,
generics: ast::Generics::default(), generics: ast::Generics::default(),
contract: None, contract: None,
body: Some(main_body), body: Some(main_body),
define_opaque: None, define_opaque: None,
})); }));
// Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main {
Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
None => Ident::new(sym::main, sp),
};
let main = P(ast::Item { let main = P(ast::Item {
ident: main_id,
attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr], attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr],
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: main, kind: main,

View File

@ -1424,12 +1424,11 @@ pub fn parse_macro_name_and_helper_attrs(
/// See #73345 and #83125 for more details. /// See #73345 and #83125 for more details.
/// FIXME(#73933): Remove this eventually. /// FIXME(#73933): Remove this eventually.
fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) { fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
let name = item.ident.name; if let ast::ItemKind::Enum(ident, enum_def, _) = &item.kind
if name == sym::ProceduralMasqueradeDummyType && ident.name == sym::ProceduralMasqueradeDummyType
&& let ast::ItemKind::Enum(enum_def, _) = &item.kind
&& let [variant] = &*enum_def.variants && let [variant] = &*enum_def.variants
&& variant.ident.name == sym::Input && variant.ident.name == sym::Input
&& let FileName::Real(real) = psess.source_map().span_to_filename(item.ident.span) && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span)
&& let Some(c) = real && let Some(c) = real
.local_path() .local_path()
.unwrap_or(Path::new("")) .unwrap_or(Path::new(""))

View File

@ -662,15 +662,8 @@ impl<'a> ExtCtxt<'a> {
P(ast::FnDecl { inputs, output }) P(ast::FnDecl { inputs, output })
} }
pub fn item( pub fn item(&self, span: Span, attrs: ast::AttrVec, kind: ast::ItemKind) -> P<ast::Item> {
&self,
span: Span,
name: Ident,
attrs: ast::AttrVec,
kind: ast::ItemKind,
) -> P<ast::Item> {
P(ast::Item { P(ast::Item {
ident: name,
attrs, attrs,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind, kind,
@ -687,17 +680,17 @@ impl<'a> ExtCtxt<'a> {
pub fn item_static( pub fn item_static(
&self, &self,
span: Span, span: Span,
name: Ident, ident: Ident,
ty: P<ast::Ty>, ty: P<ast::Ty>,
mutability: ast::Mutability, mutability: ast::Mutability,
expr: P<ast::Expr>, expr: P<ast::Expr>,
) -> P<ast::Item> { ) -> P<ast::Item> {
self.item( self.item(
span, span,
name,
AttrVec::new(), AttrVec::new(),
ast::ItemKind::Static( ast::ItemKind::Static(
ast::StaticItem { ast::StaticItem {
ident,
ty, ty,
safety: ast::Safety::Default, safety: ast::Safety::Default,
mutability, mutability,
@ -712,18 +705,18 @@ impl<'a> ExtCtxt<'a> {
pub fn item_const( pub fn item_const(
&self, &self,
span: Span, span: Span,
name: Ident, ident: Ident,
ty: P<ast::Ty>, ty: P<ast::Ty>,
expr: P<ast::Expr>, expr: P<ast::Expr>,
) -> P<ast::Item> { ) -> P<ast::Item> {
let defaultness = ast::Defaultness::Final; let defaultness = ast::Defaultness::Final;
self.item( self.item(
span, span,
name,
AttrVec::new(), AttrVec::new(),
ast::ItemKind::Const( ast::ItemKind::Const(
ast::ConstItem { ast::ConstItem {
defaultness, defaultness,
ident,
// FIXME(generic_const_items): Pass the generics as a parameter. // FIXME(generic_const_items): Pass the generics as a parameter.
generics: ast::Generics::default(), generics: ast::Generics::default(),
ty, ty,

View File

@ -743,6 +743,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
&& matches!( && matches!(
item_inner.kind, item_inner.kind,
ItemKind::Mod( ItemKind::Mod(
_,
_, _,
ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _), ModKind::Unloaded | ModKind::Loaded(_, Inline::No, _, _),
) )
@ -911,7 +912,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> { impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
fn visit_item(&mut self, item: &'ast ast::Item) { fn visit_item(&mut self, item: &'ast ast::Item) {
match &item.kind { match &item.kind {
ItemKind::Mod(_, mod_kind) ItemKind::Mod(_, _, mod_kind)
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) => if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _, _)) =>
{ {
feature_err( feature_err(
@ -1221,9 +1222,8 @@ impl InvocationCollectorNode for P<ast::Item> {
} }
// Work around borrow checker not seeing through `P`'s deref. // Work around borrow checker not seeing through `P`'s deref.
let (ident, span, mut attrs) = (node.ident, node.span, mem::take(&mut node.attrs)); let (span, mut attrs) = (node.span, mem::take(&mut node.attrs));
let ItemKind::Mod(_, mod_kind) = &mut node.kind else { unreachable!() }; let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() };
let ecx = &mut collector.cx; let ecx = &mut collector.cx;
let (file_path, dir_path, dir_ownership) = match mod_kind { let (file_path, dir_path, dir_ownership) = match mod_kind {
ModKind::Loaded(_, inline, _, _) => { ModKind::Loaded(_, inline, _, _) => {
@ -1305,6 +1305,7 @@ impl InvocationCollectorNode for P<ast::Item> {
collector.cx.current_expansion.module = orig_module; collector.cx.current_expansion.module = orig_module;
res res
} }
fn declared_names(&self) -> Vec<Ident> { fn declared_names(&self) -> Vec<Ident> {
if let ItemKind::Use(ut) = &self.kind { if let ItemKind::Use(ut) = &self.kind {
fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) { fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
@ -1324,7 +1325,7 @@ impl InvocationCollectorNode for P<ast::Item> {
return idents; return idents;
} }
vec![self.ident] if let Some(ident) = self.kind.ident() { vec![ident] } else { vec![] }
} }
} }
@ -1844,11 +1845,11 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span: if from_glob { item_span } else { ident.span }, span: if from_glob { item_span } else { ident.span },
vis: item.vis.clone(), vis: item.vis.clone(),
ident: rename.unwrap_or(ident),
kind: Node::delegation_item_kind(Box::new(ast::Delegation { kind: Node::delegation_item_kind(Box::new(ast::Delegation {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
qself: deleg.qself.clone(), qself: deleg.qself.clone(),
path, path,
ident: rename.unwrap_or(ident),
rename, rename,
body: deleg.body.clone(), body: deleg.body.clone(),
from_glob, from_glob,

View File

@ -26,7 +26,7 @@ pub(crate) fn placeholder(
}) })
} }
let ident = Ident::empty(); let ident = Ident::dummy();
let attrs = ast::AttrVec::new(); let attrs = ast::AttrVec::new();
let vis = vis.unwrap_or(ast::Visibility { let vis = vis.unwrap_or(ast::Visibility {
span: DUMMY_SP, span: DUMMY_SP,
@ -62,7 +62,6 @@ pub(crate) fn placeholder(
AstFragmentKind::Items => AstFragment::Items(smallvec![P(ast::Item { AstFragmentKind::Items => AstFragment::Items(smallvec![P(ast::Item {
id, id,
span, span,
ident,
vis, vis,
attrs, attrs,
kind: ast::ItemKind::MacCall(mac_placeholder()), kind: ast::ItemKind::MacCall(mac_placeholder()),
@ -71,7 +70,6 @@ pub(crate) fn placeholder(
AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![P(ast::AssocItem { AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![P(ast::AssocItem {
id, id,
span, span,
ident,
vis, vis,
attrs, attrs,
kind: ast::AssocItemKind::MacCall(mac_placeholder()), kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@ -80,7 +78,6 @@ pub(crate) fn placeholder(
AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem { AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem {
id, id,
span, span,
ident,
vis, vis,
attrs, attrs,
kind: ast::AssocItemKind::MacCall(mac_placeholder()), kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@ -90,7 +87,6 @@ pub(crate) fn placeholder(
AstFragment::TraitImplItems(smallvec![P(ast::AssocItem { AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
id, id,
span, span,
ident,
vis, vis,
attrs, attrs,
kind: ast::AssocItemKind::MacCall(mac_placeholder()), kind: ast::AssocItemKind::MacCall(mac_placeholder()),
@ -101,7 +97,6 @@ pub(crate) fn placeholder(
AstFragment::ForeignItems(smallvec![P(ast::ForeignItem { AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
id, id,
span, span,
ident,
vis, vis,
attrs, attrs,
kind: ast::ForeignItemKind::MacCall(mac_placeholder()), kind: ast::ForeignItemKind::MacCall(mac_placeholder()),

View File

@ -330,7 +330,6 @@ impl EarlyLintPass for UnsafeCode {
if let FnKind::Fn( if let FnKind::Fn(
ctxt, ctxt,
_, _,
_,
ast::Fn { ast::Fn {
sig: ast::FnSig { header: ast::FnHeader { safety: ast::Safety::Unsafe(_), .. }, .. }, sig: ast::FnSig { header: ast::FnHeader { safety: ast::Safety::Unsafe(_), .. }, .. },
body, body,
@ -3116,6 +3115,7 @@ impl EarlyLintPass for SpecialModuleName {
for item in &krate.items { for item in &krate.items {
if let ast::ItemKind::Mod( if let ast::ItemKind::Mod(
_, _,
ident,
ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _), ast::ModKind::Unloaded | ast::ModKind::Loaded(_, ast::Inline::No, _, _),
) = item.kind ) = item.kind
{ {
@ -3123,7 +3123,7 @@ impl EarlyLintPass for SpecialModuleName {
continue; continue;
} }
match item.ident.name.as_str() { match ident.name.as_str() {
"lib" => cx.emit_span_lint( "lib" => cx.emit_span_lint(
SPECIAL_MODULE_NAME, SPECIAL_MODULE_NAME,
item.span, item.span,

View File

@ -172,20 +172,22 @@ impl EarlyLintPass for NonCamelCaseTypes {
} }
match &it.kind { match &it.kind {
ast::ItemKind::TyAlias(..) ast::ItemKind::TyAlias(box ast::TyAlias { ident, .. })
| ast::ItemKind::Enum(..) | ast::ItemKind::Enum(ident, ..)
| ast::ItemKind::Struct(..) | ast::ItemKind::Struct(ident, ..)
| ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), | ast::ItemKind::Union(ident, ..) => self.check_case(cx, "type", ident),
ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident), ast::ItemKind::Trait(box ast::Trait { ident, .. }) => {
ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident), self.check_case(cx, "trait", ident)
}
ast::ItemKind::TraitAlias(ident, _, _) => self.check_case(cx, "trait alias", ident),
// N.B. This check is only for inherent associated types, so that we don't lint against // N.B. This check is only for inherent associated types, so that we don't lint against
// trait impls where we should have warned for the trait definition already. // trait impls where we should have warned for the trait definition already.
ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => { ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => {
for it in items { for it in items {
// FIXME: this doesn't respect `#[allow(..)]` on the item itself. // FIXME: this doesn't respect `#[allow(..)]` on the item itself.
if let ast::AssocItemKind::Type(..) = it.kind { if let ast::AssocItemKind::Type(alias) = &it.kind {
self.check_case(cx, "associated type", &it.ident); self.check_case(cx, "associated type", &alias.ident);
} }
} }
} }
@ -194,8 +196,8 @@ impl EarlyLintPass for NonCamelCaseTypes {
} }
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::Type(..) = it.kind { if let ast::AssocItemKind::Type(alias) = &it.kind {
self.check_case(cx, "associated type", &it.ident); self.check_case(cx, "associated type", &alias.ident);
} }
} }

View File

@ -1032,14 +1032,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
} }
fn inject_allocator_crate(&mut self, krate: &ast::Crate) { fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(krate) { self.cstore.has_global_allocator =
match &*fn_spans(krate, Symbol::intern(&global_fn_name(sym::alloc))) {
[span1, span2, ..] => { [span1, span2, ..] => {
self.dcx().emit_err(errors::NoMultipleGlobalAlloc { span2: *span2, span1: *span1 }); self.dcx()
.emit_err(errors::NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
true true
} }
spans => !spans.is_empty(), spans => !spans.is_empty(),
}; };
self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) { self.cstore.has_alloc_error_handler = match &*fn_spans(
krate,
Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)),
) {
[span1, span2, ..] => { [span1, span2, ..] => {
self.dcx() self.dcx()
.emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 }); .emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 });
@ -1310,17 +1315,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
definitions: &Definitions, definitions: &Definitions,
) -> Option<CrateNum> { ) -> Option<CrateNum> {
match item.kind { match item.kind {
ast::ItemKind::ExternCrate(orig_name) => { ast::ItemKind::ExternCrate(orig_name, ident) => {
debug!( debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", ident, orig_name);
"resolving extern crate stmt. ident: {} orig_name: {:?}",
item.ident, orig_name
);
let name = match orig_name { let name = match orig_name {
Some(orig_name) => { Some(orig_name) => {
validate_crate_name(self.sess, orig_name, Some(item.span)); validate_crate_name(self.sess, orig_name, Some(item.span));
orig_name orig_name
} }
None => item.ident.name, None => ident.name,
}; };
let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) { let dep_kind = if attr::contains_name(&item.attrs, sym::no_link) {
CrateDepKind::MacrosOnly CrateDepKind::MacrosOnly
@ -1368,14 +1370,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
} }
} }
fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> { fn fn_spans(krate: &ast::Crate, name: Symbol) -> Vec<Span> {
struct Finder { struct Finder {
name: Symbol, name: Symbol,
spans: Vec<Span>, spans: Vec<Span>,
} }
impl<'ast> visit::Visitor<'ast> for Finder { impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, item: &'ast ast::Item) { fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name if let Some(ident) = item.kind.ident()
&& ident.name == self.name
&& attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
{ {
self.spans.push(item.span); self.spans.push(item.span);
@ -1384,29 +1387,6 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
} }
} }
let name = Symbol::intern(&global_fn_name(sym::alloc));
let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}
fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
struct Finder {
name: Symbol,
spans: Vec<Span>,
}
impl<'ast> visit::Visitor<'ast> for Finder {
fn visit_item(&mut self, item: &'ast ast::Item) {
if item.ident.name == self.name
&& attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
{
self.spans.push(item.span);
}
visit::walk_item(self, item)
}
}
let name = Symbol::intern(alloc_error_handler_name(AllocatorKind::Global));
let mut f = Finder { name, spans: Vec::new() }; let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate); visit::walk_crate(&mut f, krate);
f.spans f.spans

View File

@ -34,10 +34,10 @@ impl<'a> Parser<'a> {
} }
/// Parses a `mod <foo> { ... }` or `mod <foo>;` item. /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemInfo> { fn parse_item_mod(&mut self, attrs: &mut AttrVec) -> PResult<'a, ItemKind> {
let safety = self.parse_safety(Case::Sensitive); let safety = self.parse_safety(Case::Sensitive);
self.expect_keyword(exp!(Mod))?; self.expect_keyword(exp!(Mod))?;
let id = self.parse_ident()?; let ident = self.parse_ident()?;
let mod_kind = if self.eat(exp!(Semi)) { let mod_kind = if self.eat(exp!(Semi)) {
ModKind::Unloaded ModKind::Unloaded
} else { } else {
@ -46,7 +46,7 @@ impl<'a> Parser<'a> {
attrs.extend(inner_attrs); attrs.extend(inner_attrs);
ModKind::Loaded(items, Inline::Yes, inner_span, Ok(())) ModKind::Loaded(items, Inline::Yes, inner_span, Ok(()))
}; };
Ok((id, ItemKind::Mod(safety, mod_kind))) Ok(ItemKind::Mod(safety, ident, mod_kind))
} }
/// Parses the contents of a module (inner attributes followed by module items). /// Parses the contents of a module (inner attributes followed by module items).
@ -115,8 +115,6 @@ impl<'a> Parser<'a> {
} }
} }
pub(super) type ItemInfo = (Ident, ItemKind);
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<P<Item>>> { pub fn parse_item(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<P<Item>>> {
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
@ -163,11 +161,11 @@ impl<'a> Parser<'a> {
fn_parse_mode, fn_parse_mode,
Case::Sensitive, Case::Sensitive,
)?; )?;
if let Some((ident, kind)) = kind { if let Some(kind) = kind {
this.error_on_unconsumed_default(def, &kind); this.error_on_unconsumed_default(def, &kind);
let span = lo.to(this.prev_token.span); let span = lo.to(this.prev_token.span);
let id = DUMMY_NODE_ID; let id = DUMMY_NODE_ID;
let item = Item { ident, attrs, id, kind, vis, span, tokens: None }; let item = Item { attrs, id, kind, vis, span, tokens: None };
return Ok((Some(item), Trailing::No, UsePreAttrPos::No)); return Ok((Some(item), Trailing::No, UsePreAttrPos::No));
} }
@ -208,7 +206,7 @@ impl<'a> Parser<'a> {
def: &mut Defaultness, def: &mut Defaultness,
fn_parse_mode: FnParseMode, fn_parse_mode: FnParseMode,
case: Case, case: Case,
) -> PResult<'a, Option<ItemInfo>> { ) -> PResult<'a, Option<ItemKind>> {
let check_pub = def == &Defaultness::Final; let check_pub = def == &Defaultness::Final;
let mut def_ = || mem::replace(def, Defaultness::Final); let mut def_ = || mem::replace(def, Defaultness::Final);
@ -218,17 +216,15 @@ impl<'a> Parser<'a> {
// FUNCTION ITEM // FUNCTION ITEM
let (ident, sig, generics, contract, body) = let (ident, sig, generics, contract, body) =
self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?;
(
ident,
ItemKind::Fn(Box::new(Fn { ItemKind::Fn(Box::new(Fn {
defaultness: def_(), defaultness: def_(),
ident,
sig, sig,
generics, generics,
contract, contract,
body, body,
define_opaque: None, define_opaque: None,
})), }))
)
} else if self.eat_keyword(exp!(Extern)) { } else if self.eat_keyword(exp!(Extern)) {
if self.eat_keyword(exp!(Crate)) { if self.eat_keyword(exp!(Crate)) {
// EXTERN CRATE // EXTERN CRATE
@ -247,8 +243,7 @@ impl<'a> Parser<'a> {
// STATIC ITEM // STATIC ITEM
self.bump(); // `static` self.bump(); // `static`
let mutability = self.parse_mutability(); let mutability = self.parse_mutability();
let (ident, item) = self.parse_static_item(safety, mutability)?; self.parse_static_item(safety, mutability)?
(ident, ItemKind::Static(Box::new(item)))
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) { } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
// CONST ITEM // CONST ITEM
if self.token.is_keyword(kw::Impl) { if self.token.is_keyword(kw::Impl) {
@ -258,16 +253,14 @@ impl<'a> Parser<'a> {
self.recover_const_mut(const_span); self.recover_const_mut(const_span);
self.recover_missing_kw_before_item()?; self.recover_missing_kw_before_item()?;
let (ident, generics, ty, expr) = self.parse_const_item()?; let (ident, generics, ty, expr) = self.parse_const_item()?;
(
ident,
ItemKind::Const(Box::new(ConstItem { ItemKind::Const(Box::new(ConstItem {
defaultness: def_(), defaultness: def_(),
ident,
generics, generics,
ty, ty,
expr, expr,
define_opaque: None, define_opaque: None,
})), }))
)
} }
} else if self.check_keyword(exp!(Trait)) || self.check_auto_or_unsafe_trait_item() { } else if self.check_keyword(exp!(Trait)) || self.check_auto_or_unsafe_trait_item() {
// TRAIT ITEM // TRAIT ITEM
@ -334,14 +327,14 @@ impl<'a> Parser<'a> {
self.recover_missing_kw_before_item()?; self.recover_missing_kw_before_item()?;
} }
// MACRO INVOCATION ITEM // MACRO INVOCATION ITEM
(Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?))) ItemKind::MacCall(P(self.parse_item_macro(vis)?))
} else { } else {
return Ok(None); return Ok(None);
}; };
Ok(Some(info)) Ok(Some(info))
} }
fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemInfo>> { fn recover_import_as_use(&mut self) -> PResult<'a, Option<ItemKind>> {
let span = self.token.span; let span = self.token.span;
let token_name = super::token_descr(&self.token); let token_name = super::token_descr(&self.token);
let snapshot = self.create_snapshot_for_diagnostic(); let snapshot = self.create_snapshot_for_diagnostic();
@ -359,7 +352,7 @@ impl<'a> Parser<'a> {
} }
} }
fn parse_use_item(&mut self) -> PResult<'a, ItemInfo> { fn parse_use_item(&mut self) -> PResult<'a, ItemKind> {
let tree = self.parse_use_tree()?; let tree = self.parse_use_tree()?;
if let Err(mut e) = self.expect_semi() { if let Err(mut e) = self.expect_semi() {
match tree.kind { match tree.kind {
@ -373,7 +366,7 @@ impl<'a> Parser<'a> {
} }
return Err(e); return Err(e);
} }
Ok((Ident::empty(), ItemKind::Use(tree))) Ok(ItemKind::Use(tree))
} }
/// When parsing a statement, would the start of a path be an item? /// When parsing a statement, would the start of a path be an item?
@ -483,7 +476,7 @@ impl<'a> Parser<'a> {
if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) } if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
} }
fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> { fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemKind>> {
// To be expanded // To be expanded
Ok(None) Ok(None)
} }
@ -577,7 +570,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
attrs: &mut AttrVec, attrs: &mut AttrVec,
defaultness: Defaultness, defaultness: Defaultness,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemKind> {
let safety = self.parse_safety(Case::Sensitive); let safety = self.parse_safety(Case::Sensitive);
self.expect_keyword(exp!(Impl))?; self.expect_keyword(exp!(Impl))?;
@ -687,7 +680,7 @@ impl<'a> Parser<'a> {
} }
None => (None, ty_first), // impl Type None => (None, ty_first), // impl Type
}; };
let item_kind = ItemKind::Impl(Box::new(Impl { Ok(ItemKind::Impl(Box::new(Impl {
safety, safety,
polarity, polarity,
defaultness, defaultness,
@ -696,12 +689,10 @@ impl<'a> Parser<'a> {
of_trait, of_trait,
self_ty, self_ty,
items: impl_items, items: impl_items,
})); })))
Ok((Ident::empty(), item_kind))
} }
fn parse_item_delegation(&mut self) -> PResult<'a, ItemInfo> { fn parse_item_delegation(&mut self) -> PResult<'a, ItemKind> {
let span = self.token.span; let span = self.token.span;
self.expect_keyword(exp!(Reuse))?; self.expect_keyword(exp!(Reuse))?;
@ -724,7 +715,7 @@ impl<'a> Parser<'a> {
}) })
}; };
let (ident, item_kind) = if self.eat_path_sep() { let item_kind = if self.eat_path_sep() {
let suffixes = if self.eat(exp!(Star)) { let suffixes = if self.eat(exp!(Star)) {
None None
} else { } else {
@ -732,7 +723,7 @@ impl<'a> Parser<'a> {
Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0) Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
}; };
let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? }; let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
(Ident::empty(), ItemKind::DelegationMac(Box::new(deleg))) ItemKind::DelegationMac(Box::new(deleg))
} else { } else {
let rename = rename(self)?; let rename = rename(self)?;
let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident); let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
@ -740,17 +731,18 @@ impl<'a> Parser<'a> {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
qself, qself,
path, path,
ident,
rename, rename,
body: body(self)?, body: body(self)?,
from_glob: false, from_glob: false,
}; };
(ident, ItemKind::Delegation(Box::new(deleg))) ItemKind::Delegation(Box::new(deleg))
}; };
let span = span.to(self.prev_token.span); let span = span.to(self.prev_token.span);
self.psess.gated_spans.gate(sym::fn_delegation, span); self.psess.gated_spans.gate(sym::fn_delegation, span);
Ok((ident, item_kind)) Ok(item_kind)
} }
fn parse_item_list<T>( fn parse_item_list<T>(
@ -900,7 +892,7 @@ impl<'a> Parser<'a> {
} }
/// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemInfo> { fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
let safety = self.parse_safety(Case::Sensitive); let safety = self.parse_safety(Case::Sensitive);
// Parse optional `auto` prefix. // Parse optional `auto` prefix.
let is_auto = if self.eat_keyword(exp!(Auto)) { let is_auto = if self.eat_keyword(exp!(Auto)) {
@ -941,15 +933,12 @@ impl<'a> Parser<'a> {
self.psess.gated_spans.gate(sym::trait_alias, whole_span); self.psess.gated_spans.gate(sym::trait_alias, whole_span);
Ok((ident, ItemKind::TraitAlias(generics, bounds))) Ok(ItemKind::TraitAlias(ident, generics, bounds))
} else { } else {
// It's a normal trait. // It's a normal trait.
generics.where_clause = self.parse_where_clause()?; generics.where_clause = self.parse_where_clause()?;
let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?; let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
Ok(( Ok(ItemKind::Trait(Box::new(Trait { is_auto, safety, ident, generics, bounds, items })))
ident,
ItemKind::Trait(Box::new(Trait { is_auto, safety, generics, bounds, items })),
))
} }
} }
@ -977,11 +966,12 @@ impl<'a> Parser<'a> {
force_collect: ForceCollect, force_collect: ForceCollect,
) -> PResult<'a, Option<Option<P<AssocItem>>>> { ) -> PResult<'a, Option<Option<P<AssocItem>>>> {
Ok(self.parse_item_(fn_parse_mode, force_collect)?.map( Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
|Item { attrs, id, span, vis, ident, kind, tokens }| { |Item { attrs, id, span, vis, kind, tokens }| {
let kind = match AssocItemKind::try_from(kind) { let kind = match AssocItemKind::try_from(kind) {
Ok(kind) => kind, Ok(kind) => kind,
Err(kind) => match kind { Err(kind) => match kind {
ItemKind::Static(box StaticItem { ItemKind::Static(box StaticItem {
ident,
ty, ty,
safety: _, safety: _,
mutability: _, mutability: _,
@ -991,6 +981,7 @@ impl<'a> Parser<'a> {
self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span }); self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
AssocItemKind::Const(Box::new(ConstItem { AssocItemKind::Const(Box::new(ConstItem {
defaultness: Defaultness::Final, defaultness: Defaultness::Final,
ident,
generics: Generics::default(), generics: Generics::default(),
ty, ty,
expr, expr,
@ -1000,7 +991,7 @@ impl<'a> Parser<'a> {
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"), _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
}, },
}; };
Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) Some(P(Item { attrs, id, span, vis, kind, tokens }))
}, },
)) ))
} }
@ -1010,7 +1001,7 @@ impl<'a> Parser<'a> {
/// TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ; /// TypeAlias = "type" Ident Generics (":" GenericBounds)? WhereClause ("=" Ty)? WhereClause ";" ;
/// ``` /// ```
/// The `"type"` has already been eaten. /// The `"type"` has already been eaten.
fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemInfo> { fn parse_type_alias(&mut self, defaultness: Defaultness) -> PResult<'a, ItemKind> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?; let mut generics = self.parse_generics()?;
@ -1045,16 +1036,14 @@ impl<'a> Parser<'a> {
self.expect_semi()?; self.expect_semi()?;
Ok(( Ok(ItemKind::TyAlias(Box::new(TyAlias {
ident,
ItemKind::TyAlias(Box::new(TyAlias {
defaultness, defaultness,
ident,
generics, generics,
where_clauses, where_clauses,
bounds, bounds,
ty, ty,
})), })))
))
} }
/// Parses a `UseTree`. /// Parses a `UseTree`.
@ -1158,16 +1147,16 @@ impl<'a> Parser<'a> {
/// extern crate foo; /// extern crate foo;
/// extern crate bar as foo; /// extern crate bar as foo;
/// ``` /// ```
fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemInfo> { fn parse_item_extern_crate(&mut self) -> PResult<'a, ItemKind> {
// Accept `extern crate name-like-this` for better diagnostics // Accept `extern crate name-like-this` for better diagnostics
let orig_name = self.parse_crate_name_with_dashes()?; let orig_ident = self.parse_crate_name_with_dashes()?;
let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? { let (orig_name, item_ident) = if let Some(rename) = self.parse_rename()? {
(rename, Some(orig_name.name)) (Some(orig_ident.name), rename)
} else { } else {
(orig_name, None) (None, orig_ident)
}; };
self.expect_semi()?; self.expect_semi()?;
Ok((item_name, ItemKind::ExternCrate(orig_name))) Ok(ItemKind::ExternCrate(orig_name, item_ident))
} }
fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> { fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, Ident> {
@ -1218,7 +1207,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
attrs: &mut AttrVec, attrs: &mut AttrVec,
mut safety: Safety, mut safety: Safety,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemKind> {
let extern_span = self.prev_token.uninterpolated_span(); let extern_span = self.prev_token.uninterpolated_span();
let abi = self.parse_abi(); // ABI? let abi = self.parse_abi(); // ABI?
// FIXME: This recovery should be tested better. // FIXME: This recovery should be tested better.
@ -1230,13 +1219,12 @@ impl<'a> Parser<'a> {
safety = Safety::Unsafe(self.token.span); safety = Safety::Unsafe(self.token.span);
let _ = self.eat_keyword(exp!(Unsafe)); let _ = self.eat_keyword(exp!(Unsafe));
} }
let module = ast::ForeignMod { Ok(ItemKind::ForeignMod(ast::ForeignMod {
extern_span, extern_span,
safety, safety,
abi, abi,
items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?, items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
}; }))
Ok((Ident::empty(), ItemKind::ForeignMod(module)))
} }
/// Parses a foreign item (one in an `extern { ... }` block). /// Parses a foreign item (one in an `extern { ... }` block).
@ -1246,11 +1234,11 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Option<Option<P<ForeignItem>>>> { ) -> PResult<'a, Option<Option<P<ForeignItem>>>> {
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false }; let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: false };
Ok(self.parse_item_(fn_parse_mode, force_collect)?.map( Ok(self.parse_item_(fn_parse_mode, force_collect)?.map(
|Item { attrs, id, span, vis, ident, kind, tokens }| { |Item { attrs, id, span, vis, kind, tokens }| {
let kind = match ForeignItemKind::try_from(kind) { let kind = match ForeignItemKind::try_from(kind) {
Ok(kind) => kind, Ok(kind) => kind,
Err(kind) => match kind { Err(kind) => match kind {
ItemKind::Const(box ConstItem { ty, expr, .. }) => { ItemKind::Const(box ConstItem { ident, ty, expr, .. }) => {
let const_span = Some(span.with_hi(ident.span.lo())) let const_span = Some(span.with_hi(ident.span.lo()))
.filter(|span| span.can_be_used_for_suggestions()); .filter(|span| span.can_be_used_for_suggestions());
self.dcx().emit_err(errors::ExternItemCannotBeConst { self.dcx().emit_err(errors::ExternItemCannotBeConst {
@ -1258,6 +1246,7 @@ impl<'a> Parser<'a> {
const_span, const_span,
}); });
ForeignItemKind::Static(Box::new(StaticItem { ForeignItemKind::Static(Box::new(StaticItem {
ident,
ty, ty,
mutability: Mutability::Not, mutability: Mutability::Not,
expr, expr,
@ -1268,7 +1257,7 @@ impl<'a> Parser<'a> {
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
}, },
}; };
Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) Some(P(Item { attrs, id, span, vis, kind, tokens }))
}, },
)) ))
} }
@ -1343,13 +1332,13 @@ impl<'a> Parser<'a> {
const_span: Span, const_span: Span,
attrs: &mut AttrVec, attrs: &mut AttrVec,
defaultness: Defaultness, defaultness: Defaultness,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemKind> {
let impl_span = self.token.span; let impl_span = self.token.span;
let err = self.expected_ident_found_err(); let err = self.expected_ident_found_err();
// 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
let mut impl_info = match self.parse_item_impl(attrs, defaultness) { let mut item_kind = match self.parse_item_impl(attrs, defaultness) {
Ok(impl_info) => impl_info, Ok(item_kind) => item_kind,
Err(recovery_error) => { Err(recovery_error) => {
// Recovery failed, raise the "expected identifier" error // Recovery failed, raise the "expected identifier" error
recovery_error.cancel(); recovery_error.cancel();
@ -1357,7 +1346,7 @@ impl<'a> Parser<'a> {
} }
}; };
match &mut impl_info.1 { match &mut item_kind {
ItemKind::Impl(box Impl { of_trait: Some(trai), constness, .. }) => { ItemKind::Impl(box Impl { of_trait: Some(trai), constness, .. }) => {
*constness = Const::Yes(const_span); *constness = Const::Yes(const_span);
@ -1374,10 +1363,11 @@ impl<'a> Parser<'a> {
_ => unreachable!(), _ => unreachable!(),
} }
Ok(impl_info) Ok(item_kind)
} }
/// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in `mutability`. /// Parse a static item with the prefix `"static" "mut"?` already parsed and stored in
/// `mutability`.
/// ///
/// ```ebnf /// ```ebnf
/// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ; /// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
@ -1386,7 +1376,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
safety: Safety, safety: Safety,
mutability: Mutability, mutability: Mutability,
) -> PResult<'a, (Ident, StaticItem)> { ) -> PResult<'a, ItemKind> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
if self.token == TokenKind::Lt && self.may_recover() { if self.token == TokenKind::Lt && self.may_recover() {
@ -1398,7 +1388,8 @@ impl<'a> Parser<'a> {
// FIXME: This could maybe benefit from `.may_recover()`? // FIXME: This could maybe benefit from `.may_recover()`?
let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) { let ty = match (self.eat(exp!(Colon)), self.check(exp!(Eq)) | self.check(exp!(Semi))) {
(true, false) => self.parse_ty()?, (true, false) => self.parse_ty()?,
// If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing type. // If there wasn't a `:` or the colon was followed by a `=` or `;`, recover a missing
// type.
(colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)), (colon, _) => self.recover_missing_global_item_type(colon, Some(mutability)),
}; };
@ -1406,7 +1397,8 @@ impl<'a> Parser<'a> {
self.expect_semi()?; self.expect_semi()?;
Ok((ident, StaticItem { ty, safety, mutability, expr, define_opaque: None })) let item = StaticItem { ident, ty, safety, mutability, expr, define_opaque: None };
Ok(ItemKind::Static(Box::new(item)))
} }
/// Parse a constant item with the prefix `"const"` already parsed. /// Parse a constant item with the prefix `"const"` already parsed.
@ -1531,7 +1523,7 @@ impl<'a> Parser<'a> {
} }
/// Parses an enum declaration. /// Parses an enum declaration.
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> { fn parse_item_enum(&mut self) -> PResult<'a, ItemKind> {
if self.token.is_keyword(kw::Struct) { if self.token.is_keyword(kw::Struct) {
let span = self.prev_token.span.to(self.token.span); let span = self.prev_token.span.to(self.token.span);
let err = errors::EnumStructMutuallyExclusive { span }; let err = errors::EnumStructMutuallyExclusive { span };
@ -1544,7 +1536,7 @@ impl<'a> Parser<'a> {
} }
let prev_span = self.prev_token.span; let prev_span = self.prev_token.span;
let id = self.parse_ident()?; let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?; let mut generics = self.parse_generics()?;
generics.where_clause = self.parse_where_clause()?; generics.where_clause = self.parse_where_clause()?;
@ -1555,10 +1547,10 @@ impl<'a> Parser<'a> {
(thin_vec![], Trailing::No) (thin_vec![], Trailing::No)
} else { } else {
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| { self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
p.parse_enum_variant(id.span) p.parse_enum_variant(ident.span)
}) })
.map_err(|mut err| { .map_err(|mut err| {
err.span_label(id.span, "while parsing this enum"); err.span_label(ident.span, "while parsing this enum");
if self.token == token::Colon { if self.token == token::Colon {
let snapshot = self.create_snapshot_for_diagnostic(); let snapshot = self.create_snapshot_for_diagnostic();
self.bump(); self.bump();
@ -1584,7 +1576,7 @@ impl<'a> Parser<'a> {
}; };
let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() }; let enum_definition = EnumDef { variants: variants.into_iter().flatten().collect() };
Ok((id, ItemKind::Enum(enum_definition, generics))) Ok(ItemKind::Enum(ident, enum_definition, generics))
} }
fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> { fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option<Variant>> {
@ -1676,8 +1668,8 @@ impl<'a> Parser<'a> {
} }
/// Parses `struct Foo { ... }`. /// Parses `struct Foo { ... }`.
fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> { fn parse_item_struct(&mut self) -> PResult<'a, ItemKind> {
let class_name = self.parse_ident()?; let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?; let mut generics = self.parse_generics()?;
@ -1698,7 +1690,7 @@ impl<'a> Parser<'a> {
let vdata = if self.token.is_keyword(kw::Where) { let vdata = if self.token.is_keyword(kw::Where) {
let tuple_struct_body; let tuple_struct_body;
(generics.where_clause, tuple_struct_body) = (generics.where_clause, tuple_struct_body) =
self.parse_struct_where_clause(class_name, generics.span)?; self.parse_struct_where_clause(ident, generics.span)?;
if let Some(body) = tuple_struct_body { if let Some(body) = tuple_struct_body {
// If we see a misplaced tuple struct body: `struct Foo<T> where T: Copy, (T);` // If we see a misplaced tuple struct body: `struct Foo<T> where T: Copy, (T);`
@ -1712,7 +1704,7 @@ impl<'a> Parser<'a> {
// If we see: `struct Foo<T> where T: Copy { ... }` // If we see: `struct Foo<T> where T: Copy { ... }`
let (fields, recovered) = self.parse_record_struct_body( let (fields, recovered) = self.parse_record_struct_body(
"struct", "struct",
class_name.span, ident.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct { fields, recovered } VariantData::Struct { fields, recovered }
@ -1724,7 +1716,7 @@ impl<'a> Parser<'a> {
} else if self.token == token::OpenDelim(Delimiter::Brace) { } else if self.token == token::OpenDelim(Delimiter::Brace) {
let (fields, recovered) = self.parse_record_struct_body( let (fields, recovered) = self.parse_record_struct_body(
"struct", "struct",
class_name.span, ident.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct { fields, recovered } VariantData::Struct { fields, recovered }
@ -1740,12 +1732,12 @@ impl<'a> Parser<'a> {
return Err(self.dcx().create_err(err)); return Err(self.dcx().create_err(err));
}; };
Ok((class_name, ItemKind::Struct(vdata, generics))) Ok(ItemKind::Struct(ident, vdata, generics))
} }
/// Parses `union Foo { ... }`. /// Parses `union Foo { ... }`.
fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> { fn parse_item_union(&mut self) -> PResult<'a, ItemKind> {
let class_name = self.parse_ident()?; let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?; let mut generics = self.parse_generics()?;
@ -1753,14 +1745,14 @@ impl<'a> Parser<'a> {
generics.where_clause = self.parse_where_clause()?; generics.where_clause = self.parse_where_clause()?;
let (fields, recovered) = self.parse_record_struct_body( let (fields, recovered) = self.parse_record_struct_body(
"union", "union",
class_name.span, ident.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct { fields, recovered } VariantData::Struct { fields, recovered }
} else if self.token == token::OpenDelim(Delimiter::Brace) { } else if self.token == token::OpenDelim(Delimiter::Brace) {
let (fields, recovered) = self.parse_record_struct_body( let (fields, recovered) = self.parse_record_struct_body(
"union", "union",
class_name.span, ident.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct { fields, recovered } VariantData::Struct { fields, recovered }
@ -1772,7 +1764,7 @@ impl<'a> Parser<'a> {
return Err(err); return Err(err);
}; };
Ok((class_name, ItemKind::Union(vdata, generics))) Ok(ItemKind::Union(ident, vdata, generics))
} }
/// This function parses the fields of record structs: /// This function parses the fields of record structs:
@ -2124,15 +2116,17 @@ impl<'a> Parser<'a> {
} }
} else if self.eat_keyword(exp!(Struct)) { } else if self.eat_keyword(exp!(Struct)) {
match self.parse_item_struct() { match self.parse_item_struct() {
Ok((ident, _)) => self Ok(item) => {
.dcx() let ItemKind::Struct(ident, ..) = item else { unreachable!() };
self.dcx()
.struct_span_err( .struct_span_err(
lo.with_hi(ident.span.hi()), lo.with_hi(ident.span.hi()),
format!("structs are not allowed in {adt_ty} definitions"), format!("structs are not allowed in {adt_ty} definitions"),
) )
.with_help( .with_help(
"consider creating a new `struct` definition instead of nesting", "consider creating a new `struct` definition instead of nesting",
), )
}
Err(err) => { Err(err) => {
err.cancel(); err.cancel();
self.restore_snapshot(snapshot); self.restore_snapshot(snapshot);
@ -2177,7 +2171,7 @@ impl<'a> Parser<'a> {
/// MacParams = "(" TOKEN_STREAM ")" ; /// MacParams = "(" TOKEN_STREAM ")" ;
/// DeclMac = "macro" Ident MacParams? MacBody ; /// DeclMac = "macro" Ident MacParams? MacBody ;
/// ``` /// ```
fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> { fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemKind> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
let body = if self.check(exp!(OpenBrace)) { let body = if self.check(exp!(OpenBrace)) {
self.parse_delim_args()? // `MacBody` self.parse_delim_args()? // `MacBody`
@ -2199,7 +2193,7 @@ impl<'a> Parser<'a> {
}; };
self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span)); self.psess.gated_spans.gate(sym::decl_macro, lo.to(self.prev_token.span));
Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: false }))) Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: false }))
} }
/// Is this a possibly malformed start of a `macro_rules! foo` item definition? /// Is this a possibly malformed start of a `macro_rules! foo` item definition?
@ -2228,7 +2222,7 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
vis: &Visibility, vis: &Visibility,
has_bang: bool, has_bang: bool,
) -> PResult<'a, ItemInfo> { ) -> PResult<'a, ItemKind> {
self.expect_keyword(exp!(MacroRules))?; // `macro_rules` self.expect_keyword(exp!(MacroRules))?; // `macro_rules`
if has_bang { if has_bang {
@ -2246,7 +2240,7 @@ impl<'a> Parser<'a> {
self.eat_semi_for_macro_if_needed(&body); self.eat_semi_for_macro_if_needed(&body);
self.complain_if_pub_macro(vis, true); self.complain_if_pub_macro(vis, true);
Ok((ident, ItemKind::MacroDef(ast::MacroDef { body, macro_rules: true }))) Ok(ItemKind::MacroDef(ident, ast::MacroDef { body, macro_rules: true }))
} }
/// Item macro invocations or `macro_rules!` definitions need inherited visibility. /// Item macro invocations or `macro_rules!` definitions need inherited visibility.

View File

@ -2922,7 +2922,7 @@ fn out_of_line_mod() {
.unwrap() .unwrap()
.unwrap(); .unwrap();
let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() }; let ast::ItemKind::Mod(_, _, mod_kind) = &item.kind else { panic!() };
assert_matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2); assert_matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2);
}); });
} }

View File

@ -268,22 +268,22 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
fn visit_item(&mut self, i: &'ast ast::Item) { fn visit_item(&mut self, i: &'ast ast::Item) {
let target = match &i.kind { let target = match &i.kind {
ast::ItemKind::ExternCrate(_) => Target::ExternCrate, ast::ItemKind::ExternCrate(..) => Target::ExternCrate,
ast::ItemKind::Use(_) => Target::Use, ast::ItemKind::Use(_) => Target::Use,
ast::ItemKind::Static(_) => Target::Static, ast::ItemKind::Static(_) => Target::Static,
ast::ItemKind::Const(_) => Target::Const, ast::ItemKind::Const(_) => Target::Const,
ast::ItemKind::Fn(_) | ast::ItemKind::Delegation(..) => Target::Fn, ast::ItemKind::Fn(_) | ast::ItemKind::Delegation(..) => Target::Fn,
ast::ItemKind::Mod(_, _) => Target::Mod, ast::ItemKind::Mod(..) => Target::Mod,
ast::ItemKind::ForeignMod(_) => Target::ForeignFn, ast::ItemKind::ForeignMod(_) => Target::ForeignFn,
ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm, ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm,
ast::ItemKind::TyAlias(_) => Target::TyAlias, ast::ItemKind::TyAlias(_) => Target::TyAlias,
ast::ItemKind::Enum(_, _) => Target::Enum, ast::ItemKind::Enum(..) => Target::Enum,
ast::ItemKind::Struct(_, _) => Target::Struct, ast::ItemKind::Struct(..) => Target::Struct,
ast::ItemKind::Union(_, _) => Target::Union, ast::ItemKind::Union(..) => Target::Union,
ast::ItemKind::Trait(_) => Target::Trait, ast::ItemKind::Trait(_) => Target::Trait,
ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias, ast::ItemKind::TraitAlias(..) => Target::TraitAlias,
ast::ItemKind::Impl(_) => Target::Impl, ast::ItemKind::Impl(_) => Target::Impl,
ast::ItemKind::MacroDef(_) => Target::MacroDef, ast::ItemKind::MacroDef(..) => Target::MacroDef,
ast::ItemKind::MacCall(_) | ast::ItemKind::DelegationMac(_) => { ast::ItemKind::MacCall(_) | ast::ItemKind::DelegationMac(_) => {
unreachable!("macros should have been expanded") unreachable!("macros should have been expanded")
} }

View File

@ -10,8 +10,8 @@ use std::sync::Arc;
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind}; use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
use rustc_ast::{ use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ForeignItem, ForeignItemKind, Impl, Item, self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
ItemKind, MetaItemKind, NodeId, StmtKind, ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
}; };
use rustc_attr_parsing as attr; use rustc_attr_parsing as attr;
use rustc_expand::base::ResolverExpand; use rustc_expand::base::ResolverExpand;
@ -735,7 +735,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let parent_scope = &self.parent_scope; let parent_scope = &self.parent_scope;
let parent = parent_scope.module; let parent = parent_scope.module;
let expansion = parent_scope.expansion; let expansion = parent_scope.expansion;
let ident = item.ident;
let sp = item.span; let sp = item.span;
let vis = self.resolve_visibility(&item.vis); let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id); let feed = self.r.feed(item.id);
@ -762,17 +761,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
); );
} }
ItemKind::ExternCrate(orig_name) => { ItemKind::ExternCrate(orig_name, ident) => {
self.build_reduced_graph_for_extern_crate( self.build_reduced_graph_for_extern_crate(
orig_name, orig_name,
item, item,
ident,
local_def_id, local_def_id,
vis, vis,
parent, parent,
); );
} }
ItemKind::Mod(.., ref mod_kind) => { ItemKind::Mod(_, ident, ref mod_kind) => {
let module = self.r.new_module( let module = self.r.new_module(
Some(parent), Some(parent),
ModuleKind::Def(def_kind, def_id, Some(ident.name)), ModuleKind::Def(def_kind, def_id, Some(ident.name)),
@ -792,10 +792,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
// These items live in the value namespace. // These items live in the value namespace.
ItemKind::Const(..) | ItemKind::Delegation(..) | ItemKind::Static(..) => { ItemKind::Const(box ConstItem { ident, .. })
| ItemKind::Delegation(box Delegation { ident, .. })
| ItemKind::Static(box StaticItem { ident, .. }) => {
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
} }
ItemKind::Fn(..) => { ItemKind::Fn(box Fn { ident, .. }) => {
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
// Functions introducing procedural macros reserve a slot // Functions introducing procedural macros reserve a slot
@ -804,11 +806,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
// These items live in the type namespace. // These items live in the type namespace.
ItemKind::TyAlias(..) | ItemKind::TraitAlias(..) => { ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
} }
ItemKind::Enum(_, _) | ItemKind::Trait(..) => { ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => {
let module = self.r.new_module( let module = self.r.new_module(
Some(parent), Some(parent),
ModuleKind::Def(def_kind, def_id, Some(ident.name)), ModuleKind::Def(def_kind, def_id, Some(ident.name)),
@ -821,7 +823,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
// These items live in both the type and value namespaces. // These items live in both the type and value namespaces.
ItemKind::Struct(ref vdata, _) => { ItemKind::Struct(ident, ref vdata, _) => {
self.build_reduced_graph_for_struct_variant( self.build_reduced_graph_for_struct_variant(
vdata.fields(), vdata.fields(),
ident, ident,
@ -872,7 +874,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
} }
ItemKind::Union(ref vdata, _) => { ItemKind::Union(ident, ref vdata, _) => {
self.build_reduced_graph_for_struct_variant( self.build_reduced_graph_for_struct_variant(
vdata.fields(), vdata.fields(),
ident, ident,
@ -899,11 +901,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
&mut self, &mut self,
orig_name: Option<Symbol>, orig_name: Option<Symbol>,
item: &Item, item: &Item,
ident: Ident,
local_def_id: LocalDefId, local_def_id: LocalDefId,
vis: ty::Visibility, vis: ty::Visibility,
parent: Module<'ra>, parent: Module<'ra>,
) { ) {
let ident = item.ident;
let sp = item.span; let sp = item.span;
let parent_scope = self.parent_scope; let parent_scope = self.parent_scope;
let expansion = parent_scope.expansion; let expansion = parent_scope.expansion;
@ -987,7 +989,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
/// Constructs the reduced graph for one foreign item. /// Constructs the reduced graph for one foreign item.
fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) { fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, ident: Ident) {
let feed = self.r.feed(item.id); let feed = self.r.feed(item.id);
let local_def_id = feed.key(); let local_def_id = feed.key();
let def_id = local_def_id.to_def_id(); let def_id = local_def_id.to_def_id();
@ -1000,7 +1002,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let parent = self.parent_scope.module; let parent = self.parent_scope.module;
let expansion = self.parent_scope.expansion; let expansion = self.parent_scope.expansion;
let vis = self.resolve_visibility(&item.vis); let vis = self.resolve_visibility(&item.vis);
self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion)); self.r.define(parent, ident, ns, (self.res(def_id), vis, item.span, expansion));
self.r.feed_visibility(feed, vis); self.r.feed_visibility(feed, vis);
} }
@ -1043,7 +1045,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
span: item.span, span: item.span,
}); });
} }
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
&& orig_name == kw::SelfLower && orig_name == kw::SelfLower
{ {
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span }); self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
@ -1177,11 +1179,15 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id)) self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
} }
fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { fn proc_macro_stub(
&self,
item: &ast::Item,
fn_ident: Ident,
) -> Option<(MacroKind, Ident, Span)> {
if ast::attr::contains_name(&item.attrs, sym::proc_macro) { if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
return Some((MacroKind::Bang, item.ident, item.span)); return Some((MacroKind::Bang, fn_ident, item.span));
} else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) { } else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span)); return Some((MacroKind::Attr, fn_ident, item.span));
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) } else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
&& let Some(meta_item_inner) = && let Some(meta_item_inner) =
attr.meta_item_list().and_then(|list| list.get(0).cloned()) attr.meta_item_list().and_then(|list| list.get(0).cloned())
@ -1214,8 +1220,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let feed = self.r.feed(item.id); let feed = self.r.feed(item.id);
let def_id = feed.key(); let def_id = feed.key();
let (res, ident, span, macro_rules) = match &item.kind { let (res, ident, span, macro_rules) = match &item.kind {
ItemKind::MacroDef(def) => (self.res(def_id), item.ident, item.span, def.macro_rules), ItemKind::MacroDef(ident, def) => {
ItemKind::Fn(..) => match self.proc_macro_stub(item) { (self.res(def_id), *ident, item.span, def.macro_rules)
}
ItemKind::Fn(box ast::Fn { ident: fn_ident, .. }) => {
match self.proc_macro_stub(item, *fn_ident) {
Some((macro_kind, ident, span)) => { Some((macro_kind, ident, span)) => {
let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id()); let res = Res::Def(DefKind::Macro(macro_kind), def_id.to_def_id());
let macro_data = MacroData::new(self.r.dummy_ext(macro_kind)); let macro_data = MacroData::new(self.r.dummy_ext(macro_kind));
@ -1224,7 +1233,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
(res, ident, span, false) (res, ident, span, false)
} }
None => return parent_scope.macro_rules, None => return parent_scope.macro_rules,
}, }
}
_ => unreachable!(), _ => unreachable!(),
}; };
@ -1327,8 +1337,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// Visit attributes after items for backward compatibility. // Visit attributes after items for backward compatibility.
// This way they can use `macro_rules` defined later. // This way they can use `macro_rules` defined later.
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(&item.ident); item.kind.walk(item.span, item.id, &item.vis, (), self);
item.kind.walk(item.span, item.id, &item.ident, &item.vis, (), self);
visit::walk_list!(self, visit_attribute, &item.attrs); visit::walk_list!(self, visit_attribute, &item.attrs);
} }
_ => visit::walk_item(self, item), _ => visit::walk_item(self, item),
@ -1353,12 +1362,17 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) { fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
if let ForeignItemKind::MacCall(_) = foreign_item.kind { let ident = match foreign_item.kind {
ForeignItemKind::Static(box StaticItem { ident, .. })
| ForeignItemKind::Fn(box Fn { ident, .. })
| ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => ident,
ForeignItemKind::MacCall(_) => {
self.visit_invoc_in_module(foreign_item.id); self.visit_invoc_in_module(foreign_item.id);
return; return;
} }
};
self.build_reduced_graph_for_foreign_item(foreign_item); self.build_reduced_graph_for_foreign_item(foreign_item, ident);
visit::walk_item(self, foreign_item); visit::walk_item(self, foreign_item);
} }
@ -1372,7 +1386,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} }
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
if let AssocItemKind::MacCall(_) = item.kind { let (ident, ns) = match item.kind {
AssocItemKind::Const(box ConstItem { ident, .. })
| AssocItemKind::Fn(box Fn { ident, .. })
| AssocItemKind::Delegation(box Delegation { ident, .. }) => (ident, ValueNS),
AssocItemKind::Type(box TyAlias { ident, .. }) => (ident, TypeNS),
AssocItemKind::MacCall(_) => {
match ctxt { match ctxt {
AssocCtxt::Trait => { AssocCtxt::Trait => {
self.visit_invoc_in_module(item.id); self.visit_invoc_in_module(item.id);
@ -1392,6 +1413,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
return; return;
} }
AssocItemKind::DelegationMac(..) => bug!(),
};
let vis = self.resolve_visibility(&item.vis); let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id); let feed = self.r.feed(item.id);
let local_def_id = feed.key(); let local_def_id = feed.key();
@ -1406,20 +1429,13 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
self.r.feed_visibility(feed, vis); self.r.feed_visibility(feed, vis);
} }
let ns = match item.kind {
AssocItemKind::Const(..) | AssocItemKind::Delegation(..) | AssocItemKind::Fn(..) => {
ValueNS
}
AssocItemKind::Type(..) => TypeNS,
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => bug!(), // handled above
};
if ctxt == AssocCtxt::Trait { if ctxt == AssocCtxt::Trait {
let parent = self.parent_scope.module; let parent = self.parent_scope.module;
let expansion = self.parent_scope.expansion; let expansion = self.parent_scope.expansion;
self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion)); self.r.define(parent, ident, ns, (self.res(def_id), vis, item.span, expansion));
} else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) { } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) {
let impl_def_id = self.r.tcx.local_parent(local_def_id); let impl_def_id = self.r.tcx.local_parent(local_def_id);
let key = BindingKey::new(item.ident.normalize_to_macros_2_0(), ns); let key = BindingKey::new(ident.normalize_to_macros_2_0(), ns);
self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key); self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
} }

View File

@ -219,14 +219,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
// because this means that they were generated in some fashion by the // because this means that they were generated in some fashion by the
// compiler and we don't need to consider them. // compiler and we don't need to consider them.
ast::ItemKind::Use(..) if item.span.is_dummy() => return, ast::ItemKind::Use(..) if item.span.is_dummy() => return,
ast::ItemKind::ExternCrate(orig_name) => { ast::ItemKind::ExternCrate(orig_name, ident) => {
self.extern_crate_items.push(ExternCrateToLint { self.extern_crate_items.push(ExternCrateToLint {
id: item.id, id: item.id,
span: item.span, span: item.span,
vis_span: item.vis.span, vis_span: item.vis.span,
span_with_attributes: item.span_with_attributes(), span_with_attributes: item.span_with_attributes(),
has_attrs: !item.attrs.is_empty(), has_attrs: !item.attrs.is_empty(),
ident: item.ident, ident,
renames: orig_name.is_some(), renames: orig_name.is_some(),
}); });
} }

View File

@ -122,7 +122,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
}, },
ItemKind::Const(..) => DefKind::Const, ItemKind::Const(..) => DefKind::Const,
ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn, ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
ItemKind::MacroDef(def) => { ItemKind::MacroDef(ident, def) => {
let edition = i.span.edition(); let edition = i.span.edition();
// FIXME(jdonszelmann) make one of these in the resolver? // FIXME(jdonszelmann) make one of these in the resolver?
@ -141,7 +141,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
); );
let macro_data = let macro_data =
self.resolver.compile_macro(def, i.ident, &attrs, i.span, i.id, edition); self.resolver.compile_macro(def, *ident, &attrs, i.span, i.id, edition);
let macro_kind = macro_data.ext.macro_kind(); let macro_kind = macro_data.ext.macro_kind();
opt_macro_data = Some(macro_data); opt_macro_data = Some(macro_data);
DefKind::Macro(macro_kind) DefKind::Macro(macro_kind)
@ -152,7 +152,8 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
return self.visit_macro_invoc(i.id); return self.visit_macro_invoc(i.id);
} }
}; };
let def_id = self.create_def(i.id, Some(i.ident.name), def_kind, i.span); let def_id =
self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
if let Some(macro_data) = opt_macro_data { if let Some(macro_data) = opt_macro_data {
self.resolver.macro_map.insert(def_id.to_def_id(), macro_data); self.resolver.macro_map.insert(def_id.to_def_id(), macro_data);
@ -161,7 +162,8 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
self.with_parent(def_id, |this| { self.with_parent(def_id, |this| {
this.with_impl_trait(ImplTraitContext::Existential, |this| { this.with_impl_trait(ImplTraitContext::Existential, |this| {
match i.kind { match i.kind {
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { ItemKind::Struct(_, ref struct_def, _)
| ItemKind::Union(_, ref struct_def, _) => {
// If this is a unit or tuple-like struct, register the constructor. // If this is a unit or tuple-like struct, register the constructor.
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) { if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) {
this.create_def( this.create_def(
@ -183,10 +185,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
match fn_kind { match fn_kind {
FnKind::Fn( FnKind::Fn(
_ctxt, _ctxt,
_ident,
_vis, _vis,
Fn { sig: FnSig { header, decl, span: _ }, generics, contract, body, .. }, Fn {
sig: FnSig { header, decl, span: _ }, ident, generics, contract, body, ..
},
) if let Some(coroutine_kind) = header.coroutine_kind => { ) if let Some(coroutine_kind) = header.coroutine_kind => {
self.visit_ident(ident);
self.visit_fn_header(header); self.visit_fn_header(header);
self.visit_generics(generics); self.visit_generics(generics);
if let Some(contract) = contract { if let Some(contract) = contract {
@ -234,8 +238,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
} }
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
let def_kind = match fi.kind { let (ident, def_kind) = match fi.kind {
ForeignItemKind::Static(box StaticItem { ForeignItemKind::Static(box StaticItem {
ident,
ty: _, ty: _,
mutability, mutability,
expr: _, expr: _,
@ -247,14 +252,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
ast::Safety::Safe(_) => hir::Safety::Safe, ast::Safety::Safe(_) => hir::Safety::Safe,
}; };
DefKind::Static { safety, mutability, nested: false } (ident, DefKind::Static { safety, mutability, nested: false })
} }
ForeignItemKind::Fn(_) => DefKind::Fn, ForeignItemKind::Fn(box Fn { ident, .. }) => (ident, DefKind::Fn),
ForeignItemKind::TyAlias(_) => DefKind::ForeignTy, ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => (ident, DefKind::ForeignTy),
ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id),
}; };
let def = self.create_def(fi.id, Some(fi.ident.name), def_kind, fi.span); let def = self.create_def(fi.id, Some(ident.name), def_kind, fi.span);
self.with_parent(def, |this| visit::walk_item(this, fi)); self.with_parent(def, |this| visit::walk_item(this, fi));
} }
@ -318,16 +323,17 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
} }
fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
let def_kind = match &i.kind { let (ident, def_kind) = match &i.kind {
AssocItemKind::Fn(..) | AssocItemKind::Delegation(..) => DefKind::AssocFn, AssocItemKind::Fn(box Fn { ident, .. })
AssocItemKind::Const(..) => DefKind::AssocConst, | AssocItemKind::Delegation(box Delegation { ident, .. }) => (*ident, DefKind::AssocFn),
AssocItemKind::Type(..) => DefKind::AssocTy, AssocItemKind::Const(box ConstItem { ident, .. }) => (*ident, DefKind::AssocConst),
AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, DefKind::AssocTy),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
return self.visit_macro_invoc(i.id); return self.visit_macro_invoc(i.id);
} }
}; };
let def = self.create_def(i.id, Some(i.ident.name), def_kind, i.span); let def = self.create_def(i.id, Some(ident.name), def_kind, i.span);
self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt));
} }

View File

@ -3063,7 +3063,7 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
fn visit_item(&mut self, item: &'tcx ast::Item) { fn visit_item(&mut self, item: &'tcx ast::Item) {
if self.target_module == item.id { if self.target_module == item.id {
if let ItemKind::Mod(_, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind { if let ItemKind::Mod(_, _, ModKind::Loaded(items, _inline, mod_spans, _)) = &item.kind {
let inject = mod_spans.inject_use_span; let inject = mod_spans.inject_use_span;
if is_span_suitable_for_use_injection(inject) { if is_span_suitable_for_use_injection(inject) {
self.first_legal_span = Some(inject); self.first_legal_span = Some(inject);

View File

@ -252,7 +252,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx>
self.current_private_vis = prev_private_vis; self.current_private_vis = prev_private_vis;
} }
ast::ItemKind::Enum(EnumDef { ref variants }, _) => { ast::ItemKind::Enum(_, EnumDef { ref variants }, _) => {
self.set_bindings_effective_visibilities(def_id); self.set_bindings_effective_visibilities(def_id);
for variant in variants { for variant in variants {
let variant_def_id = self.r.local_def_id(variant.id); let variant_def_id = self.r.local_def_id(variant.id);
@ -262,7 +262,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx>
} }
} }
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { ast::ItemKind::Struct(_, ref def, _) | ast::ItemKind::Union(_, ref def, _) => {
for field in def.fields() { for field in def.fields() {
self.update_field(self.r.local_def_id(field.id), def_id); self.update_field(self.r.local_def_id(field.id), def_id);
} }

View File

@ -1025,9 +1025,10 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
match fn_kind { match fn_kind {
// Bail if the function is foreign, and thus cannot validly have // Bail if the function is foreign, and thus cannot validly have
// a body, or if there's no body for some other reason. // a body, or if there's no body for some other reason.
FnKind::Fn(FnCtxt::Foreign, _, _, Fn { sig, generics, .. }) FnKind::Fn(FnCtxt::Foreign, _, Fn { sig, ident, generics, .. })
| FnKind::Fn(_, _, _, Fn { sig, generics, body: None, .. }) => { | FnKind::Fn(_, _, Fn { sig, ident, generics, body: None, .. }) => {
self.visit_fn_header(&sig.header); self.visit_fn_header(&sig.header);
self.visit_ident(ident);
self.visit_generics(generics); self.visit_generics(generics);
self.with_lifetime_rib( self.with_lifetime_rib(
LifetimeRibKind::AnonymousCreateParameter { LifetimeRibKind::AnonymousCreateParameter {
@ -1058,7 +1059,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
// Create a label rib for the function. // Create a label rib for the function.
this.with_label_rib(RibKind::FnOrCoroutine, |this| { this.with_label_rib(RibKind::FnOrCoroutine, |this| {
match fn_kind { match fn_kind {
FnKind::Fn(_, _, _, Fn { sig, generics, contract, body, .. }) => { FnKind::Fn(_, _, Fn { sig, generics, contract, body, .. }) => {
this.visit_generics(generics); this.visit_generics(generics);
let declaration = &sig.decl; let declaration = &sig.decl;
@ -2632,8 +2633,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
} }
let name = item.ident.name; debug!("(resolving item) resolving {:?} ({:?})", item.kind.ident(), item.kind);
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
let def_kind = self.r.local_def_kind(item.id); let def_kind = self.r.local_def_kind(item.id);
match item.kind { match item.kind {
@ -2664,9 +2664,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.resolve_define_opaques(define_opaque); self.resolve_define_opaques(define_opaque);
} }
ItemKind::Enum(_, ref generics) ItemKind::Enum(_, _, ref generics)
| ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, _, ref generics)
| ItemKind::Union(_, ref generics) => { | ItemKind::Union(_, _, ref generics) => {
self.resolve_adt(item, generics); self.resolve_adt(item, generics);
} }
@ -2710,7 +2710,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
); );
} }
ItemKind::TraitAlias(ref generics, ref bounds) => { ItemKind::TraitAlias(_, ref generics, ref bounds) => {
// 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( self.with_generic_param_rib(
&generics.params, &generics.params,
@ -2748,7 +2748,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
} }
ItemKind::Static(box ast::StaticItem { ItemKind::Static(box ast::StaticItem {
ref ty, ref expr, ref define_opaque, .. ident,
ref ty,
ref expr,
ref define_opaque,
..
}) => { }) => {
self.with_static_rib(def_kind, |this| { self.with_static_rib(def_kind, |this| {
this.with_lifetime_rib( this.with_lifetime_rib(
@ -2762,13 +2766,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
if let Some(expr) = expr { if let Some(expr) = expr {
// We already forbid generic params because of the above item rib, // We already forbid generic params because of the above item rib,
// so it doesn't matter whether this is a trivial constant. // so it doesn't matter whether this is a trivial constant.
this.resolve_const_body(expr, Some((item.ident, ConstantItemKind::Static))); this.resolve_const_body(expr, Some((ident, ConstantItemKind::Static)));
} }
}); });
self.resolve_define_opaques(define_opaque); self.resolve_define_opaques(define_opaque);
} }
ItemKind::Const(box ast::ConstItem { ItemKind::Const(box ast::ConstItem {
ident,
ref generics, ref generics,
ref ty, ref ty,
ref expr, ref expr,
@ -2801,10 +2806,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
); );
if let Some(expr) = expr { if let Some(expr) = expr {
this.resolve_const_body( this.resolve_const_body(expr, Some((ident, ConstantItemKind::Const)));
expr,
Some((item.ident, ConstantItemKind::Const)),
);
} }
}, },
); );
@ -2821,7 +2823,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.future_proof_import(use_tree); self.future_proof_import(use_tree);
} }
ItemKind::MacroDef(ref macro_def) => { ItemKind::MacroDef(_, ref macro_def) => {
// Maintain macro_rules scopes in the same way as during early resolution // Maintain macro_rules scopes in the same way as during early resolution
// for diagnostics and doc links. // for diagnostics and doc links.
if macro_def.macro_rules { if macro_def.macro_rules {
@ -3319,7 +3321,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis))); self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
match &item.kind { match &item.kind {
AssocItemKind::Const(box ast::ConstItem { AssocItemKind::Const(box ast::ConstItem {
generics, ty, expr, define_opaque, .. ident,
generics,
ty,
expr,
define_opaque,
..
}) => { }) => {
debug!("resolve_implementation AssocItemKind::Const"); debug!("resolve_implementation AssocItemKind::Const");
self.with_generic_param_rib( self.with_generic_param_rib(
@ -3350,7 +3357,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// exists in trait // exists in trait
this.check_trait_item( this.check_trait_item(
item.id, item.id,
item.ident, *ident,
&item.kind, &item.kind,
ValueNS, ValueNS,
item.span, item.span,
@ -3376,7 +3383,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
); );
self.resolve_define_opaques(define_opaque); self.resolve_define_opaques(define_opaque);
} }
AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => { AssocItemKind::Fn(box Fn { ident, generics, define_opaque, .. }) => {
debug!("resolve_implementation AssocItemKind::Fn"); debug!("resolve_implementation AssocItemKind::Fn");
// We also need a new scope for the impl item type parameters. // We also need a new scope for the impl item type parameters.
self.with_generic_param_rib( self.with_generic_param_rib(
@ -3392,7 +3399,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// exists in trait // exists in trait
this.check_trait_item( this.check_trait_item(
item.id, item.id,
item.ident, *ident,
&item.kind, &item.kind,
ValueNS, ValueNS,
item.span, item.span,
@ -3406,7 +3413,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.resolve_define_opaques(define_opaque); self.resolve_define_opaques(define_opaque);
} }
AssocItemKind::Type(box TyAlias { generics, .. }) => { AssocItemKind::Type(box TyAlias { ident, generics, .. }) => {
self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty()); self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
debug!("resolve_implementation AssocItemKind::Type"); debug!("resolve_implementation AssocItemKind::Type");
// We also need a new scope for the impl item type parameters. // We also need a new scope for the impl item type parameters.
@ -3424,7 +3431,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// exists in trait // exists in trait
this.check_trait_item( this.check_trait_item(
item.id, item.id,
item.ident, *ident,
&item.kind, &item.kind,
TypeNS, TypeNS,
item.span, item.span,
@ -3451,7 +3458,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|this| { |this| {
this.check_trait_item( this.check_trait_item(
item.id, item.id,
item.ident, delegation.ident,
&item.kind, &item.kind,
ValueNS, ValueNS,
item.span, item.span,
@ -4337,7 +4344,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
if let Some(items) = self.diag_metadata.current_trait_assoc_items if let Some(items) = self.diag_metadata.current_trait_assoc_items
&& let [Segment { ident, .. }] = path && let [Segment { ident, .. }] = path
&& items.iter().any(|item| { && items.iter().any(|item| {
item.ident == *ident && matches!(item.kind, AssocItemKind::Type(_)) if let AssocItemKind::Type(alias) = &item.kind
&& alias.ident == *ident
{
true
} else {
false
}
}) })
{ {
let mut diag = self.r.tcx.dcx().struct_allow(""); let mut diag = self.r.tcx.dcx().struct_allow("");
@ -5159,12 +5172,12 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
ItemKind::TyAlias(box TyAlias { generics, .. }) ItemKind::TyAlias(box TyAlias { generics, .. })
| ItemKind::Const(box ConstItem { generics, .. }) | ItemKind::Const(box ConstItem { generics, .. })
| ItemKind::Fn(box Fn { generics, .. }) | ItemKind::Fn(box Fn { generics, .. })
| ItemKind::Enum(_, generics) | ItemKind::Enum(_, _, generics)
| ItemKind::Struct(_, generics) | ItemKind::Struct(_, _, generics)
| ItemKind::Union(_, generics) | ItemKind::Union(_, _, generics)
| ItemKind::Impl(box Impl { generics, .. }) | ItemKind::Impl(box Impl { generics, .. })
| ItemKind::Trait(box Trait { generics, .. }) | ItemKind::Trait(box Trait { generics, .. })
| ItemKind::TraitAlias(generics, _) => { | ItemKind::TraitAlias(_, generics, _) => {
if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind { if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind {
self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs); self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
} }

View File

@ -224,12 +224,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let suggestion = if self.current_trait_ref.is_none() let suggestion = if self.current_trait_ref.is_none()
&& let Some((fn_kind, _)) = self.diag_metadata.current_function && let Some((fn_kind, _)) = self.diag_metadata.current_function
&& let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt() && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt()
&& let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = fn_kind && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = fn_kind
&& let Some(items) = self.diag_metadata.current_impl_items && let Some(items) = self.diag_metadata.current_impl_items
&& let Some(item) = items.iter().find(|i| { && let Some(item) = items.iter().find(|i| {
i.ident.name == item_str.name i.kind.ident().is_some_and(|ident| {
// Don't suggest if the item is in Fn signature arguments (#112590). // Don't suggest if the item is in Fn signature arguments (#112590).
&& !sig.span.contains(item_span) ident.name == item_str.name && !sig.span.contains(item_span)
})
}) { }) {
let sp = item_span.shrink_to_lo(); let sp = item_span.shrink_to_lo();
@ -268,14 +269,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// you can't call `fn foo(&self)` from `fn bar()` (#115992). // you can't call `fn foo(&self)` from `fn bar()` (#115992).
// We also want to mention that the method exists. // We also want to mention that the method exists.
span_label = Some(( span_label = Some((
item.ident.span, fn_.ident.span,
"a method by that name is available on `Self` here", "a method by that name is available on `Self` here",
)); ));
None None
} }
AssocItemKind::Fn(fn_) if !fn_.sig.decl.has_self() && !is_call => { AssocItemKind::Fn(fn_) if !fn_.sig.decl.has_self() && !is_call => {
span_label = Some(( span_label = Some((
item.ident.span, fn_.ident.span,
"an associated function by that name is available on `Self` here", "an associated function by that name is available on `Self` here",
)); ));
None None
@ -604,7 +605,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
if !self.self_value_is_available(path[0].ident.span) { if !self.self_value_is_available(path[0].ident.span) {
if let Some((FnKind::Fn(_, _, _, ast::Fn { sig, .. }), fn_span)) = if let Some((FnKind::Fn(_, _, ast::Fn { sig, .. }), fn_span)) =
&self.diag_metadata.current_function &self.diag_metadata.current_function
{ {
let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) { let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) {
@ -1064,15 +1065,11 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
} }
err.code(E0411); err.code(E0411);
err.span_label(span, "`Self` is only available in impls, traits, and type definitions"); err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
if let Some(item_kind) = self.diag_metadata.current_item { if let Some(item) = self.diag_metadata.current_item {
if !item_kind.ident.span.is_dummy() { if let Some(ident) = item.kind.ident() {
err.span_label( err.span_label(
item_kind.ident.span, ident.span,
format!( format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
"`Self` not allowed in {} {}",
item_kind.kind.article(),
item_kind.kind.descr()
),
); );
} }
} }
@ -1150,17 +1147,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
); );
} }
} }
} else if let Some(item_kind) = self.diag_metadata.current_item { } else if let Some(item) = self.diag_metadata.current_item {
if matches!(item_kind.kind, ItemKind::Delegation(..)) { if matches!(item.kind, ItemKind::Delegation(..)) {
err.span_label(item_kind.span, format!("delegation supports {self_from_macro}")); err.span_label(item.span, format!("delegation supports {self_from_macro}"));
} else { } else {
let span = if let Some(ident) = item.kind.ident() { ident.span } else { item.span };
err.span_label( err.span_label(
item_kind.ident.span, span,
format!( format!("`self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
"`self` not allowed in {} {}",
item_kind.kind.article(),
item_kind.kind.descr()
),
); );
} }
} }
@ -2196,7 +2190,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
if let Some(items) = self.diag_metadata.current_trait_assoc_items { if let Some(items) = self.diag_metadata.current_trait_assoc_items {
for assoc_item in items { for assoc_item in items {
if assoc_item.ident == ident { if let Some(assoc_ident) = assoc_item.kind.ident()
&& assoc_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(box ast::Fn { sig, .. }) if sig.decl.has_self() => { ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) if sig.decl.has_self() => {
@ -2735,7 +2731,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
return None; return None;
} }
match (self.diag_metadata.current_item, single_uppercase_char, self.diag_metadata.currently_processing_generic_args) { match (self.diag_metadata.current_item, single_uppercase_char, self.diag_metadata.currently_processing_generic_args) {
(Some(Item { kind: ItemKind::Fn(..), ident, .. }), _, _) if ident.name == sym::main => { (Some(Item { kind: ItemKind::Fn(fn_), .. }), _, _) if fn_.ident.name == sym::main => {
// Ignore `fn main()` as we don't want to suggest `fn main<T>()` // Ignore `fn main()` as we don't want to suggest `fn main<T>()`
} }
( (
@ -3400,7 +3396,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
{ {
let pre = if lt.kind == MissingLifetimeKind::Ampersand let pre = if lt.kind == MissingLifetimeKind::Ampersand
&& let Some((kind, _span)) = self.diag_metadata.current_function && let Some((kind, _span)) = self.diag_metadata.current_function
&& let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
&& !sig.decl.inputs.is_empty() && !sig.decl.inputs.is_empty()
&& let sugg = sig && let sugg = sig
.decl .decl
@ -3441,7 +3437,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
} else if (lt.kind == MissingLifetimeKind::Ampersand } else if (lt.kind == MissingLifetimeKind::Ampersand
|| lt.kind == MissingLifetimeKind::Underscore) || lt.kind == MissingLifetimeKind::Underscore)
&& let Some((kind, _span)) = self.diag_metadata.current_function && let Some((kind, _span)) = self.diag_metadata.current_function
&& let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
&& let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output && let ast::FnRetTy::Ty(ret_ty) = &sig.decl.output
&& !sig.decl.inputs.is_empty() && !sig.decl.inputs.is_empty()
&& let arg_refs = sig && let arg_refs = sig
@ -3501,7 +3497,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand; let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand;
let mut sugg = vec![(lt.span, String::new())]; let mut sugg = vec![(lt.span, String::new())];
if let Some((kind, _span)) = self.diag_metadata.current_function if let Some((kind, _span)) = self.diag_metadata.current_function
&& let FnKind::Fn(_, _, _, ast::Fn { sig, .. }) = kind && let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
&& let ast::FnRetTy::Ty(ty) = &sig.decl.output && let ast::FnRetTy::Ty(ty) = &sig.decl.output
{ {
let mut lt_finder = let mut lt_finder =

View File

@ -350,21 +350,21 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
info.has_global_allocator = true; info.has_global_allocator = true;
} }
match item.kind { match item.kind {
ast::ItemKind::Fn(_) if !info.has_main_fn => { ast::ItemKind::Fn(ref fn_item) if !info.has_main_fn => {
// We only push if it's the top item because otherwise, we would duplicate // We only push if it's the top item because otherwise, we would duplicate
// its content since the top-level item was already added. // its content since the top-level item was already added.
if item.ident.name == sym::main { if fn_item.ident.name == sym::main {
info.has_main_fn = true; info.has_main_fn = true;
} }
} }
ast::ItemKind::ExternCrate(original) => { ast::ItemKind::ExternCrate(original, ident) => {
is_extern_crate = true; is_extern_crate = true;
if !info.already_has_extern_crate if !info.already_has_extern_crate
&& let Some(crate_name) = crate_name && let Some(crate_name) = crate_name
{ {
info.already_has_extern_crate = match original { info.already_has_extern_crate = match original {
Some(name) => name.as_str() == *crate_name, Some(name) => name.as_str() == *crate_name,
None => item.ident.as_str() == *crate_name, None => ident.as_str() == *crate_name,
}; };
} }
} }

View File

@ -53,7 +53,7 @@ declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]);
impl EarlyLintPass for CrateInMacroDef { impl EarlyLintPass for CrateInMacroDef {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::MacroDef(macro_def) = &item.kind if let ItemKind::MacroDef(_, macro_def) = &item.kind
&& item.attrs.iter().any(is_macro_export) && item.attrs.iter().any(is_macro_export)
&& let Some(span) = contains_unhygienic_crate_reference(&macro_def.body.tokens) && let Some(span) = contains_unhygienic_crate_reference(&macro_def.body.tokens)
{ {

View File

@ -13,16 +13,16 @@ use rustc_parse::parser::ForceCollect;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::{FileName, Pos, sym}; use rustc_span::{FileName, Ident, Pos, sym};
use super::Fragments; use super::Fragments;
fn get_test_spans(item: &Item, test_attr_spans: &mut Vec<Range<usize>>) { fn get_test_spans(item: &Item, ident: Ident, test_attr_spans: &mut Vec<Range<usize>>) {
test_attr_spans.extend( test_attr_spans.extend(
item.attrs item.attrs
.iter() .iter()
.find(|attr| attr.has_name(sym::test)) .find(|attr| attr.has_name(sym::test))
.map(|attr| attr.span.lo().to_usize()..item.ident.span.hi().to_usize()), .map(|attr| attr.span.lo().to_usize()..ident.span.hi().to_usize()),
); );
} }
@ -64,10 +64,10 @@ pub fn check(
match parser.parse_item(ForceCollect::No) { match parser.parse_item(ForceCollect::No) {
Ok(Some(item)) => match &item.kind { Ok(Some(item)) => match &item.kind {
ItemKind::Fn(box Fn { ItemKind::Fn(box Fn {
sig, body: Some(block), .. ident, sig, body: Some(block), ..
}) if item.ident.name == sym::main => { }) if ident.name == sym::main => {
if !ignore { if !ignore {
get_test_spans(&item, &mut test_attr_spans); get_test_spans(&item, *ident, &mut test_attr_spans);
} }
let is_async = matches!(sig.header.coroutine_kind, Some(CoroutineKind::Async { .. })); let is_async = matches!(sig.header.coroutine_kind, Some(CoroutineKind::Async { .. }));
let returns_nothing = match &sig.decl.output { let returns_nothing = match &sig.decl.output {
@ -85,10 +85,10 @@ pub fn check(
} }
}, },
// Another function was found; this case is ignored for needless_doctest_main // Another function was found; this case is ignored for needless_doctest_main
ItemKind::Fn(box Fn { .. }) => { ItemKind::Fn(fn_) => {
eligible = false; eligible = false;
if !ignore { if !ignore {
get_test_spans(&item, &mut test_attr_spans); get_test_spans(&item, fn_.ident, &mut test_attr_spans);
} }
}, },
// Tests with one of these items are ignored // Tests with one of these items are ignored

View File

@ -63,7 +63,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
impl EarlyLintPass for DuplicateMod { impl EarlyLintPass for DuplicateMod {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No, mod_spans, _)) = &item.kind
&& let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span) && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
&& let Some(local_path) = real.into_local_path() && let Some(local_path) = real.into_local_path()
&& let Ok(absolute_path) = local_path.canonicalize() && let Ok(absolute_path) = local_path.canonicalize()

View File

@ -8,8 +8,7 @@ use rustc_errors::{Applicability, Diag, SuggestionStyle};
use rustc_lexer::TokenKind; use rustc_lexer::TokenKind;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
use rustc_span::symbol::kw; use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol, kw};
use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol};
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -375,21 +374,23 @@ impl EmptyLineAfter {
&mut self, &mut self,
cx: &EarlyContext<'_>, cx: &EarlyContext<'_>,
kind: &ItemKind, kind: &ItemKind,
ident: &Ident, ident: Option<Ident>,
span: Span, span: Span,
attrs: &[Attribute], attrs: &[Attribute],
id: NodeId, id: NodeId,
) { ) {
self.items.push(ItemInfo { self.items.push(ItemInfo {
kind: kind.descr(), kind: kind.descr(),
name: ident.name, // FIXME: this `sym::empty` can be leaked, see
span: if span.contains(ident.span) { // https://github.com/rust-lang/rust/pull/138740#discussion_r2021979899
name: if let Some(ident) = ident { ident.name } else { kw::Empty },
span: if let Some(ident) = ident {
span.with_hi(ident.span.hi()) span.with_hi(ident.span.hi())
} else { } else {
span.with_hi(span.lo()) span.with_hi(span.lo())
}, },
mod_items: match kind { mod_items: match kind {
ItemKind::Mod(_, ModKind::Loaded(items, _, _, _)) => items ItemKind::Mod(_, _, ModKind::Loaded(items, _, _, _)) => items
.iter() .iter()
.filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_))) .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
.map(|i| i.id) .map(|i| i.id)
@ -471,7 +472,7 @@ impl EarlyLintPass for EmptyLineAfter {
self.check_item_kind( self.check_item_kind(
cx, cx,
&item.kind.clone().into(), &item.kind.clone().into(),
&item.ident, item.kind.ident(),
item.span, item.span,
&item.attrs, &item.attrs,
item.id, item.id,
@ -482,7 +483,7 @@ impl EarlyLintPass for EmptyLineAfter {
self.check_item_kind( self.check_item_kind(
cx, cx,
&item.kind.clone().into(), &item.kind.clone().into(),
&item.ident, item.kind.ident(),
item.span, item.span,
&item.attrs, &item.attrs,
item.id, item.id,
@ -490,6 +491,6 @@ impl EarlyLintPass for EmptyLineAfter {
} }
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
self.check_item_kind(cx, &item.kind, &item.ident, item.span, &item.attrs, item.id); self.check_item_kind(cx, &item.kind, item.kind.ident(), item.span, &item.attrs, item.id);
} }
} }

View File

@ -74,10 +74,9 @@ declare_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM
impl EarlyLintPass for EmptyWithBrackets { impl EarlyLintPass for EmptyWithBrackets {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
let span_after_ident = item.span.with_lo(item.ident.span.hi()); if let ItemKind::Struct(ident, var_data, _) = &item.kind
if let ItemKind::Struct(var_data, _) = &item.kind
&& has_brackets(var_data) && has_brackets(var_data)
&& let span_after_ident = item.span.with_lo(ident.span.hi())
&& has_no_fields(cx, var_data, span_after_ident) && has_no_fields(cx, var_data, span_after_ident)
{ {
span_lint_and_then( span_lint_and_then(

View File

@ -51,7 +51,7 @@ declare_lint_pass!(FieldScopedVisibilityModifiers => [FIELD_SCOPED_VISIBILITY_MO
impl EarlyLintPass for FieldScopedVisibilityModifiers { impl EarlyLintPass for FieldScopedVisibilityModifiers {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
let ItemKind::Struct(ref st, _) = item.kind else { let ItemKind::Struct(_, ref st, _) = item.kind else {
return; return;
}; };
for field in st.fields() { for field in st.fields() {

View File

@ -39,7 +39,7 @@ declare_lint_pass!(MultipleBoundLocations => [MULTIPLE_BOUND_LOCATIONS]);
impl EarlyLintPass for MultipleBoundLocations { impl EarlyLintPass for MultipleBoundLocations {
fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) { fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) {
if let FnKind::Fn(_, _, _, Fn { generics, .. }) = kind if let FnKind::Fn(_, _, Fn { generics, .. }) = kind
&& !generics.params.is_empty() && !generics.params.is_empty()
&& !generics.where_clause.predicates.is_empty() && !generics.where_clause.predicates.is_empty()
{ {

View File

@ -41,7 +41,7 @@ declare_lint_pass!(PartialPubFields => [PARTIAL_PUB_FIELDS]);
impl EarlyLintPass for PartialPubFields { impl EarlyLintPass for PartialPubFields {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
let ItemKind::Struct(ref st, _) = item.kind else { let ItemKind::Struct(_, ref st, _) = item.kind else {
return; return;
}; };

View File

@ -174,11 +174,11 @@ impl SingleComponentPathImports {
} }
match &item.kind { match &item.kind {
ItemKind::Mod(_, ModKind::Loaded(items, ..)) => { ItemKind::Mod(_, _, ModKind::Loaded(items, ..)) => {
self.check_mod(items); self.check_mod(items);
}, },
ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => { ItemKind::MacroDef(ident, MacroDef { macro_rules: true, .. }) => {
macros.push(item.ident.name); macros.push(ident.name);
}, },
ItemKind::Use(use_tree) => { ItemKind::Use(use_tree) => {
let segments = &use_tree.prefix.segments; let segments = &use_tree.prefix.segments;

View File

@ -321,17 +321,18 @@ pub fn eq_local_kind(l: &LocalKind, r: &LocalKind) -> bool {
} }
pub fn eq_item<K>(l: &Item<K>, r: &Item<K>, mut eq_kind: impl FnMut(&K, &K) -> bool) -> bool { pub fn eq_item<K>(l: &Item<K>, r: &Item<K>, mut eq_kind: impl FnMut(&K, &K) -> bool) -> bool {
eq_id(l.ident, r.ident) && over(&l.attrs, &r.attrs, eq_attr) && eq_vis(&l.vis, &r.vis) && eq_kind(&l.kind, &r.kind) over(&l.attrs, &r.attrs, eq_attr) && eq_vis(&l.vis, &r.vis) && eq_kind(&l.kind, &r.kind)
} }
#[expect(clippy::similar_names, clippy::too_many_lines)] // Just a big match statement #[expect(clippy::similar_names, clippy::too_many_lines)] // Just a big match statement
pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
use ItemKind::*; use ItemKind::*;
match (l, r) { match (l, r) {
(ExternCrate(l), ExternCrate(r)) => l == r, (ExternCrate(ls, li), ExternCrate(rs, ri)) => ls == rs && eq_id(*li, *ri),
(Use(l), Use(r)) => eq_use_tree(l, r), (Use(l), Use(r)) => eq_use_tree(l, r),
( (
Static(box StaticItem { Static(box StaticItem {
ident: li,
ty: lt, ty: lt,
mutability: lm, mutability: lm,
expr: le, expr: le,
@ -339,16 +340,22 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
define_opaque: _, define_opaque: _,
}), }),
Static(box StaticItem { Static(box StaticItem {
ident: ri,
ty: rt, ty: rt,
mutability: rm, mutability: rm,
expr: re, expr: re,
safety: rs, safety: rs,
define_opaque: _, define_opaque: _,
}), }),
) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()), ) => eq_id(*li, *ri)
&& lm == rm
&& ls == rs
&& eq_ty(lt, rt)
&& eq_expr_opt(le.as_ref(), re.as_ref()),
( (
Const(box ConstItem { Const(box ConstItem {
defaultness: ld, defaultness: ld,
ident: li,
generics: lg, generics: lg,
ty: lt, ty: lt,
expr: le, expr: le,
@ -356,16 +363,22 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
}), }),
Const(box ConstItem { Const(box ConstItem {
defaultness: rd, defaultness: rd,
ident: ri,
generics: rg, generics: rg,
ty: rt, ty: rt,
expr: re, expr: re,
define_opaque: _, define_opaque: _,
}), }),
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()), ) => eq_defaultness(*ld, *rd)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg)
&& eq_ty(lt, rt)
&& eq_expr_opt(le.as_ref(), re.as_ref()),
( (
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: ld, defaultness: ld,
sig: lf, sig: lf,
ident: li,
generics: lg, generics: lg,
contract: lc, contract: lc,
body: lb, body: lb,
@ -374,6 +387,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: rd, defaultness: rd,
sig: rf, sig: rf,
ident: ri,
generics: rg, generics: rg,
contract: rc, contract: rc,
body: rb, body: rb,
@ -382,12 +396,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
) => { ) => {
eq_defaultness(*ld, *rd) eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf) && eq_fn_sig(lf, rf)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& eq_opt_fn_contract(lc, rc) && eq_opt_fn_contract(lc, rc)
&& both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r)) && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
}, },
(Mod(lu, lmk), Mod(ru, rmk)) => { (Mod(ls, li, lmk), Mod(rs, ri, rmk)) => {
lu == ru ls == rs
&& eq_id(*li, *ri)
&& match (lmk, rmk) { && match (lmk, rmk) {
(ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => { (ModKind::Loaded(litems, linline, _, _), ModKind::Loaded(ritems, rinline, _, _)) => {
linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind)) linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))
@ -421,33 +437,40 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
&& over(lb, rb, eq_generic_bound) && over(lb, rb, eq_generic_bound)
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r)) && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
}, },
(Enum(le, lg), Enum(re, rg)) => over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg), (Enum(li, le, lg), Enum(ri, re, rg)) => {
(Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => { eq_id(*li, *ri) && over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg)
eq_variant_data(lv, rv) && eq_generics(lg, rg) }
(Struct(li, lv, lg), Struct(ri, rv, rg)) | (Union(li, lv, lg), Union(ri, rv, rg)) => {
eq_id(*li, *ri) && eq_variant_data(lv, rv) && eq_generics(lg, rg)
}, },
( (
Trait(box ast::Trait { Trait(box ast::Trait {
is_auto: la, is_auto: la,
safety: lu, safety: lu,
ident: li,
generics: lg, generics: lg,
bounds: lb, bounds: lb,
items: li, items: lis,
}), }),
Trait(box ast::Trait { Trait(box ast::Trait {
is_auto: ra, is_auto: ra,
safety: ru, safety: ru,
ident: ri,
generics: rg, generics: rg,
bounds: rb, bounds: rb,
items: ri, items: ris,
}), }),
) => { ) => {
la == ra la == ra
&& matches!(lu, Safety::Default) == matches!(ru, Safety::Default) && matches!(lu, Safety::Default) == matches!(ru, Safety::Default)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, eq_generic_bound) && over(lb, rb, eq_generic_bound)
&& over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind)) && over(lis, ris, |l, r| eq_item(l, r, eq_assoc_item_kind))
}, },
(TraitAlias(lg, lb), TraitAlias(rg, rb)) => eq_generics(lg, rg) && over(lb, rb, eq_generic_bound), (TraitAlias(li, lg, lb), TraitAlias(ri, rg, rb)) => {
eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound)
}
( (
Impl(box ast::Impl { Impl(box ast::Impl {
safety: lu, safety: lu,
@ -480,7 +503,9 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
&& over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind)) && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
}, },
(MacCall(l), MacCall(r)) => eq_mac_call(l, r), (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
(MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_delim_args(&l.body, &r.body), (MacroDef(li, ld), MacroDef(ri, rd)) => {
eq_id(*li, *ri) && ld.macro_rules == rd.macro_rules && eq_delim_args(&ld.body, &rd.body)
}
_ => false, _ => false,
} }
} }
@ -490,6 +515,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
match (l, r) { match (l, r) {
( (
Static(box StaticItem { Static(box StaticItem {
ident: li,
ty: lt, ty: lt,
mutability: lm, mutability: lm,
expr: le, expr: le,
@ -497,17 +523,25 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
define_opaque: _, define_opaque: _,
}), }),
Static(box StaticItem { Static(box StaticItem {
ident: ri,
ty: rt, ty: rt,
mutability: rm, mutability: rm,
expr: re, expr: re,
safety: rs, safety: rs,
define_opaque: _, define_opaque: _,
}), }),
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs, ) => {
eq_id(*li, *ri)
&& eq_ty(lt, rt)
&& lm == rm
&& eq_expr_opt(le.as_ref(), re.as_ref())
&& ls == rs
}
( (
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: ld, defaultness: ld,
sig: lf, sig: lf,
ident: li,
generics: lg, generics: lg,
contract: lc, contract: lc,
body: lb, body: lb,
@ -516,6 +550,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: rd, defaultness: rd,
sig: rf, sig: rf,
ident: ri,
generics: rg, generics: rg,
contract: rc, contract: rc,
body: rb, body: rb,
@ -524,6 +559,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
) => { ) => {
eq_defaultness(*ld, *rd) eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf) && eq_fn_sig(lf, rf)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& eq_opt_fn_contract(lc, rc) && eq_opt_fn_contract(lc, rc)
&& both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r)) && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
@ -531,20 +567,23 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
( (
TyAlias(box ast::TyAlias { TyAlias(box ast::TyAlias {
defaultness: ld, defaultness: ld,
ident: li,
generics: lg, generics: lg,
where_clauses: _,
bounds: lb, bounds: lb,
ty: lt, ty: lt,
..
}), }),
TyAlias(box ast::TyAlias { TyAlias(box ast::TyAlias {
defaultness: rd, defaultness: rd,
ident: ri,
generics: rg, generics: rg,
where_clauses: _,
bounds: rb, bounds: rb,
ty: rt, ty: rt,
..
}), }),
) => { ) => {
eq_defaultness(*ld, *rd) eq_defaultness(*ld, *rd)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, eq_generic_bound) && over(lb, rb, eq_generic_bound)
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r)) && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
@ -560,6 +599,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
( (
Const(box ConstItem { Const(box ConstItem {
defaultness: ld, defaultness: ld,
ident: li,
generics: lg, generics: lg,
ty: lt, ty: lt,
expr: le, expr: le,
@ -567,16 +607,24 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
}), }),
Const(box ConstItem { Const(box ConstItem {
defaultness: rd, defaultness: rd,
ident: ri,
generics: rg, generics: rg,
ty: rt, ty: rt,
expr: re, expr: re,
define_opaque: _, define_opaque: _,
}), }),
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()), ) => {
eq_defaultness(*ld, *rd)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg)
&& eq_ty(lt, rt)
&& eq_expr_opt(le.as_ref(), re.as_ref())
}
( (
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: ld, defaultness: ld,
sig: lf, sig: lf,
ident: li,
generics: lg, generics: lg,
contract: lc, contract: lc,
body: lb, body: lb,
@ -585,6 +633,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
Fn(box ast::Fn { Fn(box ast::Fn {
defaultness: rd, defaultness: rd,
sig: rf, sig: rf,
ident: ri,
generics: rg, generics: rg,
contract: rc, contract: rc,
body: rb, body: rb,
@ -593,6 +642,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
) => { ) => {
eq_defaultness(*ld, *rd) eq_defaultness(*ld, *rd)
&& eq_fn_sig(lf, rf) && eq_fn_sig(lf, rf)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& eq_opt_fn_contract(lc, rc) && eq_opt_fn_contract(lc, rc)
&& both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r)) && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
@ -600,20 +650,23 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
( (
Type(box TyAlias { Type(box TyAlias {
defaultness: ld, defaultness: ld,
ident: li,
generics: lg, generics: lg,
where_clauses: _,
bounds: lb, bounds: lb,
ty: lt, ty: lt,
..
}), }),
Type(box TyAlias { Type(box TyAlias {
defaultness: rd, defaultness: rd,
ident: ri,
generics: rg, generics: rg,
where_clauses: _,
bounds: rb, bounds: rb,
ty: rt, ty: rt,
..
}), }),
) => { ) => {
eq_defaultness(*ld, *rd) eq_defaultness(*ld, *rd)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg) && eq_generics(lg, rg)
&& over(lb, rb, eq_generic_bound) && over(lb, rb, eq_generic_bound)
&& both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r)) && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))

View File

@ -246,7 +246,7 @@ pub(crate) fn format_expr(
| ast::ExprKind::Await(_, _) | ast::ExprKind::Await(_, _)
| ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape), | ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape),
ast::ExprKind::MacCall(ref mac) => { ast::ExprKind::MacCall(ref mac) => {
rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|_| { rewrite_macro(mac, context, shape, MacroPosition::Expression).or_else(|_| {
wrap_str( wrap_str(
context.snippet(expr.span).to_owned(), context.snippet(expr.span).to_owned(),
context.config.max_width(), context.config.max_width(),

View File

@ -6,7 +6,7 @@ use std::cmp::{Ordering, max, min};
use regex::Regex; use regex::Regex;
use rustc_ast::visit; use rustc_ast::visit;
use rustc_ast::{ast, ptr}; use rustc_ast::{ast, ptr};
use rustc_span::{BytePos, DUMMY_SP, Span, symbol}; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, symbol};
use tracing::debug; use tracing::debug;
use crate::attr::filter_inline_attrs; use crate::attr::filter_inline_attrs;
@ -333,12 +333,12 @@ impl<'a> FnSig<'a> {
defaultness: ast::Defaultness, defaultness: ast::Defaultness,
) -> FnSig<'a> { ) -> FnSig<'a> {
match *fn_kind { match *fn_kind {
visit::FnKind::Fn(visit::FnCtxt::Assoc(..), _, vis, ast::Fn { sig, generics, .. }) => { visit::FnKind::Fn(visit::FnCtxt::Assoc(..), vis, ast::Fn { sig, generics, .. }) => {
let mut fn_sig = FnSig::from_method_sig(sig, generics, vis); let mut fn_sig = FnSig::from_method_sig(sig, generics, vis);
fn_sig.defaultness = defaultness; fn_sig.defaultness = defaultness;
fn_sig fn_sig
} }
visit::FnKind::Fn(_, _, vis, ast::Fn { sig, generics, .. }) => FnSig { visit::FnKind::Fn(_, vis, ast::Fn { sig, generics, .. }) => FnSig {
decl, decl,
generics, generics,
ext: sig.header.ext, ext: sig.header.ext,
@ -750,11 +750,10 @@ impl<'a> FmtVisitor<'a> {
(Type(lty), Type(rty)) (Type(lty), Type(rty))
if both_type(&lty.ty, &rty.ty) || both_opaque(&lty.ty, &rty.ty) => if both_type(&lty.ty, &rty.ty) || both_opaque(&lty.ty, &rty.ty) =>
{ {
a.ident.as_str().cmp(b.ident.as_str()) lty.ident.as_str().cmp(rty.ident.as_str())
}
(Const(..), Const(..)) | (MacCall(..), MacCall(..)) => {
a.ident.as_str().cmp(b.ident.as_str())
} }
(Const(ca), Const(cb)) => ca.ident.as_str().cmp(cb.ident.as_str()),
(MacCall(..), MacCall(..)) => Ordering::Equal,
(Fn(..), Fn(..)) | (Delegation(..), Delegation(..)) => { (Fn(..), Fn(..)) | (Delegation(..), Delegation(..)) => {
a.span.lo().cmp(&b.span.lo()) a.span.lo().cmp(&b.span.lo())
} }
@ -1105,14 +1104,16 @@ impl<'a> StructParts<'a> {
} }
pub(crate) fn from_item(item: &'a ast::Item) -> Self { pub(crate) fn from_item(item: &'a ast::Item) -> Self {
let (prefix, def, generics) = match item.kind { let (prefix, def, ident, generics) = match item.kind {
ast::ItemKind::Struct(ref def, ref generics) => ("struct ", def, generics), ast::ItemKind::Struct(ident, ref def, ref generics) => {
ast::ItemKind::Union(ref def, ref generics) => ("union ", def, generics), ("struct ", def, ident, generics)
}
ast::ItemKind::Union(ident, ref def, ref generics) => ("union ", def, ident, generics),
_ => unreachable!(), _ => unreachable!(),
}; };
StructParts { StructParts {
prefix, prefix,
ident: item.ident, ident,
vis: &item.vis, vis: &item.vis,
def, def,
generics: Some(generics), generics: Some(generics),
@ -1168,6 +1169,7 @@ pub(crate) fn format_trait(
let ast::Trait { let ast::Trait {
is_auto, is_auto,
safety, safety,
ident,
ref generics, ref generics,
ref bounds, ref bounds,
ref items, ref items,
@ -1186,13 +1188,13 @@ pub(crate) fn format_trait(
let shape = Shape::indented(offset, context.config).offset_left(result.len())?; let shape = Shape::indented(offset, context.config).offset_left(result.len())?;
let generics_str = let generics_str =
rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape).ok()?; rewrite_generics(context, rewrite_ident(context, ident), generics, shape).ok()?;
result.push_str(&generics_str); result.push_str(&generics_str);
// FIXME(#2055): rustfmt fails to format when there are comments between trait bounds. // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
if !bounds.is_empty() { if !bounds.is_empty() {
// Retrieve *unnormalized* ident (See #6069) // Retrieve *unnormalized* ident (See #6069)
let source_ident = context.snippet(item.ident.span); let source_ident = context.snippet(ident.span);
let ident_hi = context.snippet_provider.span_after(item.span, source_ident); let ident_hi = context.snippet_provider.span_after(item.span, source_ident);
let bound_hi = bounds.last().unwrap().span().hi(); let bound_hi = bounds.last().unwrap().span().hi();
let snippet = context.snippet(mk_sp(ident_hi, bound_hi)); let snippet = context.snippet(mk_sp(ident_hi, bound_hi));
@ -1679,11 +1681,12 @@ fn format_tuple_struct(
Some(result) Some(result)
} }
pub(crate) enum ItemVisitorKind<'a> { #[derive(Clone, Copy)]
Item(&'a ast::Item), pub(crate) enum ItemVisitorKind {
AssocTraitItem(&'a ast::AssocItem), Item,
AssocImplItem(&'a ast::AssocItem), AssocTraitItem,
ForeignItem(&'a ast::ForeignItem), AssocImplItem,
ForeignItem,
} }
struct TyAliasRewriteInfo<'c, 'g>( struct TyAliasRewriteInfo<'c, 'g>(
@ -1695,17 +1698,19 @@ struct TyAliasRewriteInfo<'c, 'g>(
Span, Span,
); );
pub(crate) fn rewrite_type_alias<'a, 'b>( pub(crate) fn rewrite_type_alias<'a>(
ty_alias_kind: &ast::TyAlias, ty_alias_kind: &ast::TyAlias,
vis: &ast::Visibility,
context: &RewriteContext<'a>, context: &RewriteContext<'a>,
indent: Indent, indent: Indent,
visitor_kind: &ItemVisitorKind<'b>, visitor_kind: ItemVisitorKind,
span: Span, span: Span,
) -> RewriteResult { ) -> RewriteResult {
use ItemVisitorKind::*; use ItemVisitorKind::*;
let ast::TyAlias { let ast::TyAlias {
defaultness, defaultness,
ident,
ref generics, ref generics,
ref bounds, ref bounds,
ref ty, ref ty,
@ -1715,11 +1720,6 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
let rhs_hi = ty let rhs_hi = ty
.as_ref() .as_ref()
.map_or(where_clauses.before.span.hi(), |ty| ty.span.hi()); .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi());
let (ident, vis) = match visitor_kind {
Item(i) => (i.ident, &i.vis),
AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
ForeignItem(i) => (i.ident, &i.vis),
};
let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span); let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span);
let op_ty = opaque_ty(ty); let op_ty = opaque_ty(ty);
// Type Aliases are formatted slightly differently depending on the context // Type Aliases are formatted slightly differently depending on the context
@ -1727,14 +1727,14 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
// https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html
// https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases
match (visitor_kind, &op_ty) { match (visitor_kind, &op_ty) {
(Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => { (Item | AssocTraitItem | ForeignItem, Some(op_bounds)) => {
let op = OpaqueType { bounds: op_bounds }; let op = OpaqueType { bounds: op_bounds };
rewrite_ty(rw_info, Some(bounds), Some(&op), rhs_hi, vis) rewrite_ty(rw_info, Some(bounds), Some(&op), rhs_hi, vis)
} }
(Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => { (Item | AssocTraitItem | ForeignItem, None) => {
rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis) rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
} }
(AssocImplItem(_), _) => { (AssocImplItem, _) => {
let result = if let Some(op_bounds) = op_ty { let result = if let Some(op_bounds) = op_ty {
let op = OpaqueType { bounds: op_bounds }; let op = OpaqueType { bounds: op_bounds };
rewrite_ty( rewrite_ty(
@ -2024,14 +2024,23 @@ pub(crate) struct StaticParts<'a> {
impl<'a> StaticParts<'a> { impl<'a> StaticParts<'a> {
pub(crate) fn from_item(item: &'a ast::Item) -> Self { pub(crate) fn from_item(item: &'a ast::Item) -> Self {
let (defaultness, prefix, safety, ty, mutability, expr, generics) = match &item.kind { let (defaultness, prefix, safety, ident, ty, mutability, expr, generics) = match &item.kind
ast::ItemKind::Static(s) => { {
(None, "static", s.safety, &s.ty, s.mutability, &s.expr, None) ast::ItemKind::Static(s) => (
} None,
"static",
s.safety,
s.ident,
&s.ty,
s.mutability,
&s.expr,
None,
),
ast::ItemKind::Const(c) => ( ast::ItemKind::Const(c) => (
Some(c.defaultness), Some(c.defaultness),
"const", "const",
ast::Safety::Default, ast::Safety::Default,
c.ident,
&c.ty, &c.ty,
ast::Mutability::Not, ast::Mutability::Not,
&c.expr, &c.expr,
@ -2043,7 +2052,7 @@ impl<'a> StaticParts<'a> {
prefix, prefix,
safety, safety,
vis: &item.vis, vis: &item.vis,
ident: item.ident, ident,
generics, generics,
ty, ty,
mutability, mutability,
@ -2053,7 +2062,7 @@ impl<'a> StaticParts<'a> {
} }
} }
pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self { pub(crate) fn from_trait_item(ti: &'a ast::AssocItem, ident: Ident) -> Self {
let (defaultness, ty, expr_opt, generics) = match &ti.kind { let (defaultness, ty, expr_opt, generics) = match &ti.kind {
ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)),
_ => unreachable!(), _ => unreachable!(),
@ -2062,7 +2071,7 @@ impl<'a> StaticParts<'a> {
prefix: "const", prefix: "const",
safety: ast::Safety::Default, safety: ast::Safety::Default,
vis: &ti.vis, vis: &ti.vis,
ident: ti.ident, ident,
generics, generics,
ty, ty,
mutability: ast::Mutability::Not, mutability: ast::Mutability::Not,
@ -2072,7 +2081,7 @@ impl<'a> StaticParts<'a> {
} }
} }
pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self { pub(crate) fn from_impl_item(ii: &'a ast::AssocItem, ident: Ident) -> Self {
let (defaultness, ty, expr, generics) = match &ii.kind { let (defaultness, ty, expr, generics) = match &ii.kind {
ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)), ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr, Some(&c.generics)),
_ => unreachable!(), _ => unreachable!(),
@ -2081,7 +2090,7 @@ impl<'a> StaticParts<'a> {
prefix: "const", prefix: "const",
safety: ast::Safety::Default, safety: ast::Safety::Default,
vis: &ii.vis, vis: &ii.vis,
ident: ii.ident, ident,
generics, generics,
ty, ty,
mutability: ast::Mutability::Not, mutability: ast::Mutability::Not,
@ -3442,6 +3451,7 @@ impl Rewrite for ast::ForeignItem {
let ast::Fn { let ast::Fn {
defaultness, defaultness,
ref sig, ref sig,
ident,
ref generics, ref generics,
ref body, ref body,
.. ..
@ -3453,7 +3463,8 @@ impl Rewrite for ast::ForeignItem {
let inner_attrs = inner_attributes(&self.attrs); let inner_attrs = inner_attributes(&self.attrs);
let fn_ctxt = visit::FnCtxt::Foreign; let fn_ctxt = visit::FnCtxt::Foreign;
visitor.visit_fn( visitor.visit_fn(
visit::FnKind::Fn(fn_ctxt, &self.ident, &self.vis, fn_kind), ident,
visit::FnKind::Fn(fn_ctxt, &self.vis, fn_kind),
&sig.decl, &sig.decl,
self.span, self.span,
defaultness, defaultness,
@ -3464,7 +3475,7 @@ impl Rewrite for ast::ForeignItem {
rewrite_fn_base( rewrite_fn_base(
context, context,
shape.indent, shape.indent,
self.ident, ident,
&FnSig::from_method_sig(sig, generics, &self.vis), &FnSig::from_method_sig(sig, generics, &self.vis),
span, span,
FnBraceStyle::None, FnBraceStyle::None,
@ -3483,7 +3494,7 @@ impl Rewrite for ast::ForeignItem {
vis, vis,
safety, safety,
mut_str, mut_str,
rewrite_ident(context, self.ident) rewrite_ident(context, static_foreign_item.ident)
); );
// 1 = ; // 1 = ;
rewrite_assign_rhs( rewrite_assign_rhs(
@ -3498,11 +3509,11 @@ impl Rewrite for ast::ForeignItem {
.map(|s| s + ";") .map(|s| s + ";")
} }
ast::ForeignItemKind::TyAlias(ref ty_alias) => { ast::ForeignItemKind::TyAlias(ref ty_alias) => {
let (kind, span) = (&ItemVisitorKind::ForeignItem(self), self.span); let kind = ItemVisitorKind::ForeignItem;
rewrite_type_alias(ty_alias, context, shape.indent, kind, span) rewrite_type_alias(ty_alias, &self.vis, context, shape.indent, kind, self.span)
} }
ast::ForeignItemKind::MacCall(ref mac) => { ast::ForeignItemKind::MacCall(ref mac) => {
rewrite_macro(mac, None, context, shape, MacroPosition::Item) rewrite_macro(mac, context, shape, MacroPosition::Item)
} }
}?; }?;
@ -3562,12 +3573,13 @@ fn rewrite_attrs(
pub(crate) fn rewrite_mod( pub(crate) fn rewrite_mod(
context: &RewriteContext<'_>, context: &RewriteContext<'_>,
item: &ast::Item, item: &ast::Item,
ident: Ident,
attrs_shape: Shape, attrs_shape: Shape,
) -> Option<String> { ) -> Option<String> {
let mut result = String::with_capacity(32); let mut result = String::with_capacity(32);
result.push_str(&*format_visibility(context, &item.vis)); result.push_str(&*format_visibility(context, &item.vis));
result.push_str("mod "); result.push_str("mod ");
result.push_str(rewrite_ident(context, item.ident)); result.push_str(rewrite_ident(context, ident));
result.push(';'); result.push(';');
rewrite_attrs(context, item, &result, attrs_shape) rewrite_attrs(context, item, &result, attrs_shape)
} }
@ -3594,7 +3606,7 @@ pub(crate) fn rewrite_extern_crate(
pub(crate) fn is_mod_decl(item: &ast::Item) -> bool { pub(crate) fn is_mod_decl(item: &ast::Item) -> bool {
!matches!( !matches!(
item.kind, item.kind,
ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _)) ast::ItemKind::Mod(_, _, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _))
) )
} }

View File

@ -16,10 +16,7 @@ use rustc_ast::token::{Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree}; use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree};
use rustc_ast::{ast, ptr}; use rustc_ast::{ast, ptr};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_span::{ use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol};
BytePos, DUMMY_SP, Span, Symbol,
symbol::{self, kw},
};
use tracing::debug; use tracing::debug;
use crate::comment::{ use crate::comment::{
@ -60,7 +57,7 @@ pub(crate) enum MacroArg {
Ty(ptr::P<ast::Ty>), Ty(ptr::P<ast::Ty>),
Pat(ptr::P<ast::Pat>), Pat(ptr::P<ast::Pat>),
Item(ptr::P<ast::Item>), Item(ptr::P<ast::Item>),
Keyword(symbol::Ident, Span), Keyword(Ident, Span),
} }
impl MacroArg { impl MacroArg {
@ -103,20 +100,12 @@ impl Rewrite for MacroArg {
} }
/// Rewrite macro name without using pretty-printer if possible. /// Rewrite macro name without using pretty-printer if possible.
fn rewrite_macro_name( fn rewrite_macro_name(context: &RewriteContext<'_>, path: &ast::Path) -> String {
context: &RewriteContext<'_>, if path.segments.len() == 1 {
path: &ast::Path,
extra_ident: Option<symbol::Ident>,
) -> String {
let name = if path.segments.len() == 1 {
// Avoid using pretty-printer in the common case. // Avoid using pretty-printer in the common case.
format!("{}!", rewrite_ident(context, path.segments[0].ident)) format!("{}!", rewrite_ident(context, path.segments[0].ident))
} else { } else {
format!("{}!", pprust::path_to_string(path)) format!("{}!", pprust::path_to_string(path))
};
match extra_ident {
Some(ident) if ident.name != kw::Empty => format!("{name} {ident}"),
_ => name,
} }
} }
@ -165,7 +154,6 @@ fn return_macro_parse_failure_fallback(
pub(crate) fn rewrite_macro( pub(crate) fn rewrite_macro(
mac: &ast::MacCall, mac: &ast::MacCall,
extra_ident: Option<symbol::Ident>,
context: &RewriteContext<'_>, context: &RewriteContext<'_>,
shape: Shape, shape: Shape,
position: MacroPosition, position: MacroPosition,
@ -179,14 +167,7 @@ pub(crate) fn rewrite_macro(
} else { } else {
let guard = context.enter_macro(); let guard = context.enter_macro();
let result = catch_unwind(AssertUnwindSafe(|| { let result = catch_unwind(AssertUnwindSafe(|| {
rewrite_macro_inner( rewrite_macro_inner(mac, context, shape, position, guard.is_nested())
mac,
extra_ident,
context,
shape,
position,
guard.is_nested(),
)
})); }));
match result { match result {
Err(..) => { Err(..) => {
@ -207,7 +188,6 @@ pub(crate) fn rewrite_macro(
fn rewrite_macro_inner( fn rewrite_macro_inner(
mac: &ast::MacCall, mac: &ast::MacCall,
extra_ident: Option<symbol::Ident>,
context: &RewriteContext<'_>, context: &RewriteContext<'_>,
shape: Shape, shape: Shape,
position: MacroPosition, position: MacroPosition,
@ -222,7 +202,7 @@ fn rewrite_macro_inner(
let original_style = macro_style(mac, context); let original_style = macro_style(mac, context);
let macro_name = rewrite_macro_name(context, &mac.path, extra_ident); let macro_name = rewrite_macro_name(context, &mac.path);
let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&&macro_name[..]); let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&&macro_name[..]);
let style = if is_forced_bracket && !is_nested_macro { let style = if is_forced_bracket && !is_nested_macro {
@ -432,7 +412,7 @@ pub(crate) fn rewrite_macro_def(
shape: Shape, shape: Shape,
indent: Indent, indent: Indent,
def: &ast::MacroDef, def: &ast::MacroDef,
ident: symbol::Ident, ident: Ident,
vis: &ast::Visibility, vis: &ast::Visibility,
span: Span, span: Span,
) -> RewriteResult { ) -> RewriteResult {

View File

@ -152,7 +152,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
let mut visitor = visitor::CfgIfVisitor::new(self.psess); let mut visitor = visitor::CfgIfVisitor::new(self.psess);
visitor.visit_item(&item); visitor.visit_item(&item);
for module_item in visitor.mods() { for module_item in visitor.mods() {
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = module_item.item.kind { if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = module_item.item.kind {
self.visit_sub_mod( self.visit_sub_mod(
&module_item.item, &module_item.item,
Module::new( Module::new(
@ -178,7 +178,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
continue; continue;
} }
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind { if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = item.kind {
let span = item.span; let span = item.span;
self.visit_sub_mod( self.visit_sub_mod(
&item, &item,
@ -204,7 +204,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
self.visit_cfg_if(Cow::Borrowed(item))?; self.visit_cfg_if(Cow::Borrowed(item))?;
} }
if let ast::ItemKind::Mod(_, ref sub_mod_kind) = item.kind { if let ast::ItemKind::Mod(_, _, ref sub_mod_kind) = item.kind {
let span = item.span; let span = item.span;
self.visit_sub_mod( self.visit_sub_mod(
item, item,
@ -248,7 +248,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
if is_mod_decl(item) { if is_mod_decl(item) {
// mod foo; // mod foo;
// Look for an extern file. // Look for an extern file.
self.find_external_module(item.ident, &item.attrs, sub_mod) self.find_external_module(item.kind.ident().unwrap(), &item.attrs, sub_mod)
} else { } else {
// An internal module (`mod foo { /* ... */ }`); // An internal module (`mod foo { /* ... */ }`);
Ok(Some(SubModKind::Internal(item))) Ok(Some(SubModKind::Internal(item)))
@ -291,7 +291,7 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> {
self.visit_sub_mod_after_directory_update(sub_mod, Some(directory)) self.visit_sub_mod_after_directory_update(sub_mod, Some(directory))
} }
SubModKind::Internal(item) => { SubModKind::Internal(item) => {
self.push_inline_mod_directory(item.ident, &item.attrs); self.push_inline_mod_directory(item.kind.ident().unwrap(), &item.attrs);
self.visit_sub_mod_after_directory_update(sub_mod, None) self.visit_sub_mod_after_directory_update(sub_mod, None)
} }
SubModKind::MultiExternal(mods) => { SubModKind::MultiExternal(mods) => {

View File

@ -307,9 +307,7 @@ impl Rewrite for Pat {
context, context,
shape, shape,
), ),
PatKind::MacCall(ref mac) => { PatKind::MacCall(ref mac) => rewrite_macro(mac, context, shape, MacroPosition::Pat),
rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
}
PatKind::Paren(ref pat) => pat PatKind::Paren(ref pat) => pat
.rewrite_result( .rewrite_result(
context, context,

View File

@ -25,14 +25,17 @@ use crate::visitor::FmtVisitor;
/// Choose the ordering between the given two items. /// Choose the ordering between the given two items.
fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering { fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering {
match (&a.kind, &b.kind) { match (&a.kind, &b.kind) {
(&ast::ItemKind::Mod(..), &ast::ItemKind::Mod(..)) => { (&ast::ItemKind::Mod(_, a_ident, _), &ast::ItemKind::Mod(_, b_ident, _)) => {
a.ident.as_str().cmp(b.ident.as_str()) a_ident.as_str().cmp(b_ident.as_str())
} }
(&ast::ItemKind::ExternCrate(ref a_name), &ast::ItemKind::ExternCrate(ref b_name)) => { (
&ast::ItemKind::ExternCrate(ref a_name, a_ident),
&ast::ItemKind::ExternCrate(ref b_name, b_ident),
) => {
// `extern crate foo as bar;` // `extern crate foo as bar;`
// ^^^ Comparing this. // ^^^ Comparing this.
let a_orig_name = a_name.unwrap_or(a.ident.name); let a_orig_name = a_name.unwrap_or(a_ident.name);
let b_orig_name = b_name.unwrap_or(b.ident.name); let b_orig_name = b_name.unwrap_or(b_ident.name);
let result = a_orig_name.as_str().cmp(b_orig_name.as_str()); let result = a_orig_name.as_str().cmp(b_orig_name.as_str());
if result != Ordering::Equal { if result != Ordering::Equal {
return result; return result;
@ -44,7 +47,7 @@ fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering {
(Some(..), None) => Ordering::Greater, (Some(..), None) => Ordering::Greater,
(None, Some(..)) => Ordering::Less, (None, Some(..)) => Ordering::Less,
(None, None) => Ordering::Equal, (None, None) => Ordering::Equal,
(Some(..), Some(..)) => a.ident.as_str().cmp(b.ident.as_str()), (Some(..), Some(..)) => a_ident.as_str().cmp(b_ident.as_str()),
} }
} }
_ => unreachable!(), _ => unreachable!(),
@ -69,7 +72,7 @@ fn rewrite_reorderable_item(
) -> Option<String> { ) -> Option<String> {
match item.kind { match item.kind {
ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item, shape), ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item, shape),
ast::ItemKind::Mod(..) => rewrite_mod(context, item, shape), ast::ItemKind::Mod(_, ident, _) => rewrite_mod(context, item, ident, shape),
_ => None, _ => None,
} }
} }

View File

@ -1018,7 +1018,7 @@ impl Rewrite for ast::Ty {
ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape), ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape),
ast::TyKind::Never => Ok(String::from("!")), ast::TyKind::Never => Ok(String::from("!")),
ast::TyKind::MacCall(ref mac) => { ast::TyKind::MacCall(ref mac) => {
rewrite_macro(mac, None, context, shape, MacroPosition::Expression) rewrite_macro(mac, context, shape, MacroPosition::Expression)
} }
ast::TyKind::ImplicitSelf => Ok(String::from("")), ast::TyKind::ImplicitSelf => Ok(String::from("")),
ast::TyKind::ImplTrait(_, ref it) => { ast::TyKind::ImplTrait(_, ref it) => {

View File

@ -3,7 +3,7 @@ use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use rustc_ast::{ast, token::Delimiter, visit}; use rustc_ast::{ast, token::Delimiter, visit};
use rustc_span::{BytePos, Pos, Span, symbol}; use rustc_span::{BytePos, Ident, Pos, Span, symbol};
use tracing::debug; use tracing::debug;
use crate::attr::*; use crate::attr::*;
@ -172,7 +172,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
get_span_without_attrs(stmt.as_ast_node()), get_span_without_attrs(stmt.as_ast_node()),
); );
} else { } else {
self.visit_mac(&mac_stmt.mac, None, MacroPosition::Statement); self.visit_mac(&mac_stmt.mac, MacroPosition::Statement);
} }
self.format_missing(stmt.span().hi()); self.format_missing(stmt.span().hi());
} }
@ -377,6 +377,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
// on traits do not get handled here. // on traits do not get handled here.
pub(crate) fn visit_fn( pub(crate) fn visit_fn(
&mut self, &mut self,
ident: Ident,
fk: visit::FnKind<'_>, fk: visit::FnKind<'_>,
fd: &ast::FnDecl, fd: &ast::FnDecl,
s: Span, s: Span,
@ -388,7 +389,6 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let rewrite = match fk { let rewrite = match fk {
visit::FnKind::Fn( visit::FnKind::Fn(
_, _,
ident,
_, _,
ast::Fn { ast::Fn {
body: Some(ref b), .. body: Some(ref b), ..
@ -397,7 +397,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
block = b; block = b;
self.rewrite_fn_before_block( self.rewrite_fn_before_block(
indent, indent,
*ident, ident,
&FnSig::from_fn_kind(&fk, fd, defaultness), &FnSig::from_fn_kind(&fk, fd, defaultness),
mk_sp(s.lo(), b.span.lo()), mk_sp(s.lo(), b.span.lo()),
) )
@ -444,7 +444,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let should_visit_node_again = match item.kind { let should_visit_node_again = match item.kind {
// For use/extern crate items, skip rewriting attributes but check for a skip attribute. // For use/extern crate items, skip rewriting attributes but check for a skip attribute.
ast::ItemKind::Use(..) | ast::ItemKind::ExternCrate(_) => { ast::ItemKind::Use(..) | ast::ItemKind::ExternCrate(..) => {
if contains_skip(attrs) { if contains_skip(attrs) {
self.push_skipped_with_span(attrs.as_slice(), item.span(), item.span()); self.push_skipped_with_span(attrs.as_slice(), item.span(), item.span());
false false
@ -497,11 +497,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent)); let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent));
self.push_rewrite(item.span, rw); self.push_rewrite(item.span, rw);
} }
ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => { ast::ItemKind::TraitAlias(ident, ref generics, ref generic_bounds) => {
let shape = Shape::indented(self.block_indent, self.config); let shape = Shape::indented(self.block_indent, self.config);
let rw = format_trait_alias( let rw = format_trait_alias(
&self.get_context(), &self.get_context(),
item.ident, ident,
&item.vis, &item.vis,
generics, generics,
generic_bounds, generic_bounds,
@ -509,7 +509,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
); );
self.push_rewrite(item.span, rw); self.push_rewrite(item.span, rw);
} }
ast::ItemKind::ExternCrate(_) => { ast::ItemKind::ExternCrate(..) => {
let rw = rewrite_extern_crate(&self.get_context(), item, self.shape()); let rw = rewrite_extern_crate(&self.get_context(), item, self.shape());
let span = if attrs.is_empty() { let span = if attrs.is_empty() {
item.span item.span
@ -521,17 +521,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => { ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => {
self.visit_struct(&StructParts::from_item(item)); self.visit_struct(&StructParts::from_item(item));
} }
ast::ItemKind::Enum(ref def, ref generics) => { ast::ItemKind::Enum(ident, ref def, ref generics) => {
self.format_missing_with_indent(source!(self, item.span).lo()); self.format_missing_with_indent(source!(self, item.span).lo());
self.visit_enum(item.ident, &item.vis, def, generics, item.span); self.visit_enum(ident, &item.vis, def, generics, item.span);
self.last_pos = source!(self, item.span).hi(); self.last_pos = source!(self, item.span).hi();
} }
ast::ItemKind::Mod(safety, ref mod_kind) => { ast::ItemKind::Mod(safety, ident, ref mod_kind) => {
self.format_missing_with_indent(source!(self, item.span).lo()); self.format_missing_with_indent(source!(self, item.span).lo());
self.format_mod(mod_kind, safety, &item.vis, item.span, item.ident, attrs); self.format_mod(mod_kind, safety, &item.vis, item.span, ident, attrs);
} }
ast::ItemKind::MacCall(ref mac) => { ast::ItemKind::MacCall(ref mac) => {
self.visit_mac(mac, Some(item.ident), MacroPosition::Item); self.visit_mac(mac, MacroPosition::Item);
} }
ast::ItemKind::ForeignMod(ref foreign_mod) => { ast::ItemKind::ForeignMod(ref foreign_mod) => {
self.format_missing_with_indent(source!(self, item.span).lo()); self.format_missing_with_indent(source!(self, item.span).lo());
@ -544,6 +544,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let ast::Fn { let ast::Fn {
defaultness, defaultness,
ref sig, ref sig,
ident,
ref generics, ref generics,
ref body, ref body,
.. ..
@ -555,7 +556,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
_ => visit::FnCtxt::Foreign, _ => visit::FnCtxt::Foreign,
}; };
self.visit_fn( self.visit_fn(
visit::FnKind::Fn(fn_ctxt, &item.ident, &item.vis, fn_kind), ident,
visit::FnKind::Fn(fn_ctxt, &item.vis, fn_kind),
&sig.decl, &sig.decl,
item.span, item.span,
defaultness, defaultness,
@ -564,28 +566,26 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
} else { } else {
let indent = self.block_indent; let indent = self.block_indent;
let rewrite = self let rewrite = self
.rewrite_required_fn( .rewrite_required_fn(indent, ident, sig, &item.vis, generics, item.span)
indent, item.ident, sig, &item.vis, generics, item.span,
)
.ok(); .ok();
self.push_rewrite(item.span, rewrite); self.push_rewrite(item.span, rewrite);
} }
} }
ast::ItemKind::TyAlias(ref ty_alias) => { ast::ItemKind::TyAlias(ref ty_alias) => {
use ItemVisitorKind::Item; use ItemVisitorKind::Item;
self.visit_ty_alias_kind(ty_alias, &Item(item), item.span); self.visit_ty_alias_kind(ty_alias, &item.vis, Item, item.span);
} }
ast::ItemKind::GlobalAsm(..) => { ast::ItemKind::GlobalAsm(..) => {
let snippet = Some(self.snippet(item.span).to_owned()); let snippet = Some(self.snippet(item.span).to_owned());
self.push_rewrite(item.span, snippet); self.push_rewrite(item.span, snippet);
} }
ast::ItemKind::MacroDef(ref def) => { ast::ItemKind::MacroDef(ident, ref def) => {
let rewrite = rewrite_macro_def( let rewrite = rewrite_macro_def(
&self.get_context(), &self.get_context(),
self.shape(), self.shape(),
self.block_indent, self.block_indent,
def, def,
item.ident, ident,
&item.vis, &item.vis,
item.span, item.span,
) )
@ -605,11 +605,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
fn visit_ty_alias_kind( fn visit_ty_alias_kind(
&mut self, &mut self,
ty_kind: &ast::TyAlias, ty_kind: &ast::TyAlias,
visitor_kind: &ItemVisitorKind<'_>, vis: &ast::Visibility,
visitor_kind: ItemVisitorKind,
span: Span, span: Span,
) { ) {
let rewrite = rewrite_type_alias( let rewrite = rewrite_type_alias(
ty_kind, ty_kind,
vis,
&self.get_context(), &self.get_context(),
self.block_indent, self.block_indent,
visitor_kind, visitor_kind,
@ -619,15 +621,16 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.push_rewrite(span, rewrite); self.push_rewrite(span, rewrite);
} }
fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) { fn visit_assoc_item(&mut self, ai: &ast::AssocItem, visitor_kind: ItemVisitorKind) {
use ItemVisitorKind::*; use ItemVisitorKind::*;
// TODO(calebcartwright): Not sure the skip spans are correct let assoc_ctxt = match visitor_kind {
let (ai, skip_span, assoc_ctxt) = match visitor_kind { AssocTraitItem => visit::AssocCtxt::Trait,
AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
// There is no difference between trait and inherent assoc item formatting // There is no difference between trait and inherent assoc item formatting
AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }), AssocImplItem => visit::AssocCtxt::Impl { of_trait: false },
_ => unreachable!(), _ => unreachable!(),
}; };
// TODO(calebcartwright): Not sure the skip spans are correct
let skip_span = ai.span;
skip_out_of_file_lines_range_visitor!(self, ai.span); skip_out_of_file_lines_range_visitor!(self, ai.span);
if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) { if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) {
@ -637,16 +640,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
// TODO(calebcartwright): consider enabling box_patterns feature gate // TODO(calebcartwright): consider enabling box_patterns feature gate
match (&ai.kind, visitor_kind) { match (&ai.kind, visitor_kind) {
(ast::AssocItemKind::Const(..), AssocTraitItem(_)) => { (ast::AssocItemKind::Const(c), AssocTraitItem) => {
self.visit_static(&StaticParts::from_trait_item(ai)) self.visit_static(&StaticParts::from_trait_item(ai, c.ident))
} }
(ast::AssocItemKind::Const(..), AssocImplItem(_)) => { (ast::AssocItemKind::Const(c), AssocImplItem) => {
self.visit_static(&StaticParts::from_impl_item(ai)) self.visit_static(&StaticParts::from_impl_item(ai, c.ident))
} }
(ast::AssocItemKind::Fn(ref fn_kind), _) => { (ast::AssocItemKind::Fn(ref fn_kind), _) => {
let ast::Fn { let ast::Fn {
defaultness, defaultness,
ref sig, ref sig,
ident,
ref generics, ref generics,
ref body, ref body,
.. ..
@ -655,7 +659,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
let inner_attrs = inner_attributes(&ai.attrs); let inner_attrs = inner_attributes(&ai.attrs);
let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
self.visit_fn( self.visit_fn(
visit::FnKind::Fn(fn_ctxt, &ai.ident, &ai.vis, fn_kind), ident,
visit::FnKind::Fn(fn_ctxt, &ai.vis, fn_kind),
&sig.decl, &sig.decl,
ai.span, ai.span,
defaultness, defaultness,
@ -664,35 +669,35 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
} else { } else {
let indent = self.block_indent; let indent = self.block_indent;
let rewrite = self let rewrite = self
.rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span) .rewrite_required_fn(indent, fn_kind.ident, sig, &ai.vis, generics, ai.span)
.ok(); .ok();
self.push_rewrite(ai.span, rewrite); self.push_rewrite(ai.span, rewrite);
} }
} }
(ast::AssocItemKind::Type(ref ty_alias), _) => { (ast::AssocItemKind::Type(ref ty_alias), _) => {
self.visit_ty_alias_kind(ty_alias, visitor_kind, ai.span); self.visit_ty_alias_kind(ty_alias, &ai.vis, visitor_kind, ai.span);
} }
(ast::AssocItemKind::MacCall(ref mac), _) => { (ast::AssocItemKind::MacCall(ref mac), _) => {
self.visit_mac(mac, Some(ai.ident), MacroPosition::Item); self.visit_mac(mac, MacroPosition::Item);
} }
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) {
self.visit_assoc_item(&ItemVisitorKind::AssocTraitItem(ti)); self.visit_assoc_item(ti, ItemVisitorKind::AssocTraitItem);
} }
pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) { pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) {
self.visit_assoc_item(&ItemVisitorKind::AssocImplItem(ii)); self.visit_assoc_item(ii, ItemVisitorKind::AssocImplItem);
} }
fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option<symbol::Ident>, pos: MacroPosition) { fn visit_mac(&mut self, mac: &ast::MacCall, pos: MacroPosition) {
skip_out_of_file_lines_range_visitor!(self, mac.span()); skip_out_of_file_lines_range_visitor!(self, mac.span());
// 1 = ; // 1 = ;
let shape = self.shape().saturating_sub_width(1); let shape = self.shape().saturating_sub_width(1);
let rewrite = self.with_context(|ctx| rewrite_macro(mac, ident, ctx, shape, pos).ok()); let rewrite = self.with_context(|ctx| rewrite_macro(mac, ctx, shape, pos).ok());
// As of v638 of the rustc-ap-* crates, the associated span no longer includes // As of v638 of the rustc-ap-* crates, the associated span no longer includes
// the trailing semicolon. This determines the correct span to ensure scenarios // the trailing semicolon. This determines the correct span to ensure scenarios
// with whitespace between the delimiters and trailing semi (i.e. `foo!(abc) ;`) // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc) ;`)

View File

@ -25,4 +25,17 @@ impl example_runner::Testable for IsFoo {
const TEST_1: IsFoo = IsFoo("hello"); const TEST_1: IsFoo = IsFoo("hello");
#[test_case] #[test_case]
const TEST_2: IsFoo = IsFoo("foo"); static TEST_2: IsFoo = IsFoo("foo");
// FIXME: `test_case` is currently ignored on anything other than
// fn/const/static. This should be an error. Compare this with `#[test]` and
// #[bench] whose expanders emit "error: expected a non-associated function,
// found […]" if applied to invalid items.
#[test_case]
struct _S;
// FIXME: as above.
#[test_case]
impl _S {
fn _f() {}
}

View File

@ -10,9 +10,9 @@ ast-stats-1 - DocComment 32 ( 0.5%) 1
ast-stats-1 - Normal 32 ( 0.5%) 1 ast-stats-1 - Normal 32 ( 0.5%) 1
ast-stats-1 WherePredicate 72 ( 1.1%) 1 72 ast-stats-1 WherePredicate 72 ( 1.1%) 1 72
ast-stats-1 - BoundPredicate 72 ( 1.1%) 1 ast-stats-1 - BoundPredicate 72 ( 1.1%) 1
ast-stats-1 ForeignItem 80 ( 1.2%) 1 80
ast-stats-1 - Fn 80 ( 1.2%) 1
ast-stats-1 Local 80 ( 1.2%) 1 80 ast-stats-1 Local 80 ( 1.2%) 1 80
ast-stats-1 ForeignItem 88 ( 1.3%) 1 88
ast-stats-1 - Fn 88 ( 1.3%) 1
ast-stats-1 Arm 96 ( 1.4%) 2 48 ast-stats-1 Arm 96 ( 1.4%) 2 48
ast-stats-1 FnDecl 120 ( 1.8%) 5 24 ast-stats-1 FnDecl 120 ( 1.8%) 5 24
ast-stats-1 Param 160 ( 2.4%) 4 40 ast-stats-1 Param 160 ( 2.4%) 4 40
@ -23,37 +23,37 @@ ast-stats-1 - Expr 96 ( 1.4%) 3
ast-stats-1 Block 192 ( 2.9%) 6 32 ast-stats-1 Block 192 ( 2.9%) 6 32
ast-stats-1 FieldDef 208 ( 3.1%) 2 104 ast-stats-1 FieldDef 208 ( 3.1%) 2 104
ast-stats-1 Variant 208 ( 3.1%) 2 104 ast-stats-1 Variant 208 ( 3.1%) 2 104
ast-stats-1 AssocItem 352 ( 5.3%) 4 88 ast-stats-1 AssocItem 320 ( 4.8%) 4 80
ast-stats-1 - Fn 176 ( 2.6%) 2 ast-stats-1 - Fn 160 ( 2.4%) 2
ast-stats-1 - Type 176 ( 2.6%) 2 ast-stats-1 - Type 160 ( 2.4%) 2
ast-stats-1 GenericBound 352 ( 5.3%) 4 88 ast-stats-1 GenericBound 352 ( 5.2%) 4 88
ast-stats-1 - Trait 352 ( 5.3%) 4 ast-stats-1 - Trait 352 ( 5.2%) 4
ast-stats-1 GenericParam 480 ( 7.2%) 5 96 ast-stats-1 GenericParam 480 ( 7.1%) 5 96
ast-stats-1 Pat 504 ( 7.5%) 7 72 ast-stats-1 Pat 504 ( 7.5%) 7 72
ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Wild 72 ( 1.1%) 1 ast-stats-1 - Wild 72 ( 1.1%) 1
ast-stats-1 - Ident 360 ( 5.4%) 5 ast-stats-1 - Ident 360 ( 5.3%) 5
ast-stats-1 Expr 576 ( 8.6%) 8 72 ast-stats-1 Expr 576 ( 8.6%) 8 72
ast-stats-1 - Match 72 ( 1.1%) 1 ast-stats-1 - Match 72 ( 1.1%) 1
ast-stats-1 - Path 72 ( 1.1%) 1 ast-stats-1 - Path 72 ( 1.1%) 1
ast-stats-1 - Struct 72 ( 1.1%) 1 ast-stats-1 - Struct 72 ( 1.1%) 1
ast-stats-1 - Lit 144 ( 2.1%) 2 ast-stats-1 - Lit 144 ( 2.1%) 2
ast-stats-1 - Block 216 ( 3.2%) 3 ast-stats-1 - Block 216 ( 3.2%) 3
ast-stats-1 PathSegment 744 (11.1%) 31 24 ast-stats-1 PathSegment 744 (11.0%) 31 24
ast-stats-1 Ty 896 (13.4%) 14 64 ast-stats-1 Ty 896 (13.3%) 14 64
ast-stats-1 - Ptr 64 ( 1.0%) 1 ast-stats-1 - Ptr 64 ( 1.0%) 1
ast-stats-1 - Ref 64 ( 1.0%) 1 ast-stats-1 - Ref 64 ( 1.0%) 1
ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2 ast-stats-1 - ImplicitSelf 128 ( 1.9%) 2
ast-stats-1 - Path 640 ( 9.5%) 10 ast-stats-1 - Path 640 ( 9.5%) 10
ast-stats-1 Item 1_224 (18.3%) 9 136 ast-stats-1 Item 1_296 (19.2%) 9 144
ast-stats-1 - Enum 136 ( 2.0%) 1 ast-stats-1 - Enum 144 ( 2.1%) 1
ast-stats-1 - ForeignMod 136 ( 2.0%) 1 ast-stats-1 - ForeignMod 144 ( 2.1%) 1
ast-stats-1 - Impl 136 ( 2.0%) 1 ast-stats-1 - Impl 144 ( 2.1%) 1
ast-stats-1 - Trait 136 ( 2.0%) 1 ast-stats-1 - Trait 144 ( 2.1%) 1
ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Fn 288 ( 4.3%) 2
ast-stats-1 - Use 408 ( 6.1%) 3 ast-stats-1 - Use 432 ( 6.4%) 3
ast-stats-1 ---------------------------------------------------------------- ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 6_704 116 ast-stats-1 Total 6_736 116
ast-stats-1 ast-stats-1
ast-stats-2 POST EXPANSION AST STATS ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size ast-stats-2 Name Accumulated Size Count Item Size
@ -61,12 +61,12 @@ ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Crate 40 ( 0.5%) 1 40 ast-stats-2 Crate 40 ( 0.5%) 1 40
ast-stats-2 GenericArgs 40 ( 0.5%) 1 40 ast-stats-2 GenericArgs 40 ( 0.5%) 1 40
ast-stats-2 - AngleBracketed 40 ( 0.5%) 1 ast-stats-2 - AngleBracketed 40 ( 0.5%) 1
ast-stats-2 ExprField 48 ( 0.7%) 1 48 ast-stats-2 ExprField 48 ( 0.6%) 1 48
ast-stats-2 WherePredicate 72 ( 1.0%) 1 72 ast-stats-2 WherePredicate 72 ( 1.0%) 1 72
ast-stats-2 - BoundPredicate 72 ( 1.0%) 1 ast-stats-2 - BoundPredicate 72 ( 1.0%) 1
ast-stats-2 ForeignItem 80 ( 1.1%) 1 80
ast-stats-2 - Fn 80 ( 1.1%) 1
ast-stats-2 Local 80 ( 1.1%) 1 80 ast-stats-2 Local 80 ( 1.1%) 1 80
ast-stats-2 ForeignItem 88 ( 1.2%) 1 88
ast-stats-2 - Fn 88 ( 1.2%) 1
ast-stats-2 Arm 96 ( 1.3%) 2 48 ast-stats-2 Arm 96 ( 1.3%) 2 48
ast-stats-2 FnDecl 120 ( 1.6%) 5 24 ast-stats-2 FnDecl 120 ( 1.6%) 5 24
ast-stats-2 InlineAsm 120 ( 1.6%) 1 120 ast-stats-2 InlineAsm 120 ( 1.6%) 1 120
@ -81,13 +81,13 @@ ast-stats-2 - Expr 96 ( 1.3%) 3
ast-stats-2 Block 192 ( 2.6%) 6 32 ast-stats-2 Block 192 ( 2.6%) 6 32
ast-stats-2 FieldDef 208 ( 2.8%) 2 104 ast-stats-2 FieldDef 208 ( 2.8%) 2 104
ast-stats-2 Variant 208 ( 2.8%) 2 104 ast-stats-2 Variant 208 ( 2.8%) 2 104
ast-stats-2 AssocItem 352 ( 4.8%) 4 88 ast-stats-2 AssocItem 320 ( 4.3%) 4 80
ast-stats-2 - Fn 176 ( 2.4%) 2 ast-stats-2 - Fn 160 ( 2.2%) 2
ast-stats-2 - Type 176 ( 2.4%) 2 ast-stats-2 - Type 160 ( 2.2%) 2
ast-stats-2 GenericBound 352 ( 4.8%) 4 88 ast-stats-2 GenericBound 352 ( 4.8%) 4 88
ast-stats-2 - Trait 352 ( 4.8%) 4 ast-stats-2 - Trait 352 ( 4.8%) 4
ast-stats-2 GenericParam 480 ( 6.5%) 5 96 ast-stats-2 GenericParam 480 ( 6.5%) 5 96
ast-stats-2 Pat 504 ( 6.9%) 7 72 ast-stats-2 Pat 504 ( 6.8%) 7 72
ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - Struct 72 ( 1.0%) 1
ast-stats-2 - Wild 72 ( 1.0%) 1 ast-stats-2 - Wild 72 ( 1.0%) 1
ast-stats-2 - Ident 360 ( 4.9%) 5 ast-stats-2 - Ident 360 ( 4.9%) 5
@ -96,24 +96,24 @@ ast-stats-2 - InlineAsm 72 ( 1.0%) 1
ast-stats-2 - Match 72 ( 1.0%) 1 ast-stats-2 - Match 72 ( 1.0%) 1
ast-stats-2 - Path 72 ( 1.0%) 1 ast-stats-2 - Path 72 ( 1.0%) 1
ast-stats-2 - Struct 72 ( 1.0%) 1 ast-stats-2 - Struct 72 ( 1.0%) 1
ast-stats-2 - Lit 144 ( 2.0%) 2 ast-stats-2 - Lit 144 ( 1.9%) 2
ast-stats-2 - Block 216 ( 2.9%) 3 ast-stats-2 - Block 216 ( 2.9%) 3
ast-stats-2 PathSegment 864 (11.8%) 36 24 ast-stats-2 PathSegment 864 (11.7%) 36 24
ast-stats-2 Ty 896 (12.2%) 14 64 ast-stats-2 Ty 896 (12.1%) 14 64
ast-stats-2 - Ptr 64 ( 0.9%) 1 ast-stats-2 - Ptr 64 ( 0.9%) 1
ast-stats-2 - Ref 64 ( 0.9%) 1 ast-stats-2 - Ref 64 ( 0.9%) 1
ast-stats-2 - ImplicitSelf 128 ( 1.7%) 2 ast-stats-2 - ImplicitSelf 128 ( 1.7%) 2
ast-stats-2 - Path 640 ( 8.7%) 10 ast-stats-2 - Path 640 ( 8.6%) 10
ast-stats-2 Item 1_496 (20.3%) 11 136 ast-stats-2 Item 1_584 (21.4%) 11 144
ast-stats-2 - Enum 136 ( 1.8%) 1 ast-stats-2 - Enum 144 ( 1.9%) 1
ast-stats-2 - ExternCrate 136 ( 1.8%) 1 ast-stats-2 - ExternCrate 144 ( 1.9%) 1
ast-stats-2 - ForeignMod 136 ( 1.8%) 1 ast-stats-2 - ForeignMod 144 ( 1.9%) 1
ast-stats-2 - Impl 136 ( 1.8%) 1 ast-stats-2 - Impl 144 ( 1.9%) 1
ast-stats-2 - Trait 136 ( 1.8%) 1 ast-stats-2 - Trait 144 ( 1.9%) 1
ast-stats-2 - Fn 272 ( 3.7%) 2 ast-stats-2 - Fn 288 ( 3.9%) 2
ast-stats-2 - Use 544 ( 7.4%) 4 ast-stats-2 - Use 576 ( 7.8%) 4
ast-stats-2 ---------------------------------------------------------------- ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 7_352 127 ast-stats-2 Total 7_400 127
ast-stats-2 ast-stats-2
hir-stats HIR STATS hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size hir-stats Name Accumulated Size Count Item Size