Move ast::Item::ident
into ast::ItemKind
.
`ast::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, `Trait`, `TraitAlias`, `MacroDef`, `Delegation`. - It's always empty for these item kinds: `Use`, `ForeignMod`, `GlobalAsm`, `Impl`, `MacCall`, `DelegationMac`. There is a similar story for `AssocItemKind` and `ForeignItemKind`. Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. The commit is large but it's mostly obvious plumbing work. Some notable things. - `ast::Item` got 8 bytes bigger. This could be avoided by boxing the fields within some of the `ast::ItemKind` variants (specifically: `Struct`, `Union`, `Enum`). I might do that in a follow-up; this commit is big enough already. - For the visitors: `FnKind` no longer needs an `ident` field because the `Fn` within how has one. - In the parser, the `ItemInfo` typedef is no longer needed. It was used in various places to return an `Ident` alongside an `ItemKind`, but now the `Ident` (if present) is within the `ItemKind`. - In a few places I renamed identifier variables called `name` (or `foo_name`) as `ident` (or `foo_ident`), to better match the type, and because `name` is normally used for `Symbol`s. It's confusing to see something like `foo_name.name`.
This commit is contained in:
parent
43018eacb6
commit
df247968f2
54 changed files with 1072 additions and 864 deletions
|
@ -21,15 +21,15 @@ pub(crate) fn expand(
|
|||
|
||||
// Allow using `#[alloc_error_handler]` on an item statement
|
||||
// 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
|
||||
{
|
||||
(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
|
||||
&& let StmtKind::Item(item) = &stmt.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 {
|
||||
ecx.dcx().emit_err(errors::AllocErrorMustBeFn { span: item.span() });
|
||||
return vec![orig_item];
|
||||
|
@ -39,7 +39,7 @@ pub(crate) fn expand(
|
|||
let span = ecx.with_def_site_ctxt(item.span);
|
||||
|
||||
// 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.
|
||||
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 {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
sig,
|
||||
ident: Ident::from_str_and_span("__rg_oom", span),
|
||||
generics: Generics::default(),
|
||||
contract: None,
|
||||
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 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)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use rustc_index::bit_set::GrowableBitSet;
|
|||
use rustc_parse::exp;
|
||||
use rustc_parse::parser::{ExpKeywordPair, Parser};
|
||||
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 smallvec::smallvec;
|
||||
use {rustc_ast as ast, rustc_parse_format as parse};
|
||||
|
@ -888,7 +888,6 @@ pub(super) fn expand_global_asm<'cx>(
|
|||
};
|
||||
match mac {
|
||||
Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
|
||||
ident: Ident::empty(),
|
||||
attrs: ast::AttrVec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
|
||||
|
|
|
@ -112,7 +112,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
self.span,
|
||||
self.cx.item(
|
||||
self.span,
|
||||
Ident::empty(),
|
||||
thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)],
|
||||
ItemKind::Use(UseTree {
|
||||
prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),
|
||||
|
|
|
@ -146,26 +146,26 @@ mod llvm_enzyme {
|
|||
}
|
||||
let dcx = ecx.sess.dcx();
|
||||
// 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) => {
|
||||
let sig = match &iitem.kind {
|
||||
ItemKind::Fn(box ast::Fn { sig, .. }) => sig,
|
||||
let (ident, sig) = match &iitem.kind {
|
||||
ItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
|
||||
_ => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
return vec![item];
|
||||
}
|
||||
};
|
||||
(sig.clone(), false)
|
||||
(*ident, sig.clone(), false)
|
||||
}
|
||||
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
|
||||
let sig = match &assoc_item.kind {
|
||||
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
|
||||
let (ident, sig) = match &assoc_item.kind {
|
||||
ast::AssocItemKind::Fn(box ast::Fn { ident, sig, .. }) => (ident, sig),
|
||||
_ => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
return vec![item];
|
||||
}
|
||||
};
|
||||
(sig.clone(), true)
|
||||
(*ident, sig.clone(), true)
|
||||
}
|
||||
_ => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
|
@ -184,11 +184,9 @@ mod llvm_enzyme {
|
|||
let has_ret = has_ret(&sig.decl.output);
|
||||
let sig_span = ecx.with_call_site_ctxt(sig.span);
|
||||
|
||||
let (vis, primal) = match &item {
|
||||
Annotatable::Item(iitem) => (iitem.vis.clone(), iitem.ident.clone()),
|
||||
Annotatable::AssocItem(assoc_item, _) => {
|
||||
(assoc_item.vis.clone(), assoc_item.ident.clone())
|
||||
}
|
||||
let vis = match &item {
|
||||
Annotatable::Item(iitem) => iitem.vis.clone(),
|
||||
Annotatable::AssocItem(assoc_item, _) => assoc_item.vis.clone(),
|
||||
_ => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
return vec![item];
|
||||
|
@ -237,12 +235,12 @@ mod llvm_enzyme {
|
|||
let d_body = gen_enzyme_body(
|
||||
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
|
||||
let asdf = Box::new(ast::Fn {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
sig: d_sig,
|
||||
ident: first_ident(&meta_item_vec[0]),
|
||||
generics: Generics::default(),
|
||||
contract: None,
|
||||
body: Some(d_body),
|
||||
|
@ -323,14 +321,12 @@ mod llvm_enzyme {
|
|||
id: ast::DUMMY_NODE_ID,
|
||||
span,
|
||||
vis,
|
||||
ident: d_ident,
|
||||
kind: assoc_item,
|
||||
tokens: None,
|
||||
});
|
||||
Annotatable::AssocItem(d_fn, Impl { of_trait: false })
|
||||
} else {
|
||||
let mut d_fn =
|
||||
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
|
||||
let mut d_fn = ecx.item(span, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
|
||||
d_fn.vis = vis;
|
||||
Annotatable::Item(d_fn)
|
||||
};
|
||||
|
|
|
@ -34,8 +34,8 @@ pub(crate) fn expand_deriving_clone(
|
|||
let is_simple;
|
||||
match item {
|
||||
Annotatable::Item(annitem) => match &annitem.kind {
|
||||
ItemKind::Struct(_, Generics { params, .. })
|
||||
| ItemKind::Enum(_, Generics { params, .. }) => {
|
||||
ItemKind::Struct(_, _, Generics { params, .. })
|
||||
| ItemKind::Enum(_, _, Generics { params, .. }) => {
|
||||
let container_id = cx.current_expansion.id.expn_data().parent.expect_local();
|
||||
let has_derive_copy = cx.resolver.has_derive_copy(container_id);
|
||||
if has_derive_copy
|
||||
|
|
|
@ -21,7 +21,7 @@ pub(crate) fn expand_deriving_partial_ord(
|
|||
|
||||
// Order in which to perform matching
|
||||
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();
|
||||
match dataful.iter().filter(|&&b| b).count() {
|
||||
|
|
|
@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
item.visit_with(&mut DetectNonGenericPointeeAttr { cx });
|
||||
|
||||
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!(
|
||||
struct_data,
|
||||
|
@ -40,7 +40,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
cx.dcx().emit_err(RequireOneField { span });
|
||||
return;
|
||||
}
|
||||
(aitem.ident, g)
|
||||
(*ident, g)
|
||||
} else {
|
||||
cx.dcx().emit_err(RequireTransparent { span });
|
||||
return;
|
||||
|
@ -108,7 +108,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
push(Annotatable::Item(
|
||||
cx.item(
|
||||
span,
|
||||
Ident::empty(),
|
||||
attrs.clone(),
|
||||
ast::ItemKind::Impl(Box::new(ast::Impl {
|
||||
safety: ast::Safety::Default,
|
||||
|
@ -153,7 +152,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
|
|||
let trait_ref = cx.trait_ref(trait_path);
|
||||
let item = cx.item(
|
||||
span,
|
||||
Ident::empty(),
|
||||
attrs.clone(),
|
||||
ast::ItemKind::Impl(Box::new(ast::Impl {
|
||||
safety: ast::Safety::Default,
|
||||
|
|
|
@ -487,28 +487,28 @@ impl<'a> TraitDef<'a> {
|
|||
);
|
||||
|
||||
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,
|
||||
struct_def,
|
||||
item.ident,
|
||||
*ident,
|
||||
generics,
|
||||
from_scratch,
|
||||
is_packed,
|
||||
),
|
||||
ast::ItemKind::Enum(enum_def, generics) => {
|
||||
ast::ItemKind::Enum(ident, enum_def, generics) => {
|
||||
// We ignore `is_packed` here, because `repr(packed)`
|
||||
// enums cause an error later on.
|
||||
//
|
||||
// This can only cause further compilation errors
|
||||
// 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 {
|
||||
self.expand_struct_def(
|
||||
cx,
|
||||
struct_def,
|
||||
item.ident,
|
||||
*ident,
|
||||
generics,
|
||||
from_scratch,
|
||||
is_packed,
|
||||
|
@ -596,7 +596,6 @@ impl<'a> TraitDef<'a> {
|
|||
P(ast::AssocItem {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
ident,
|
||||
vis: ast::Visibility {
|
||||
span: self.span.shrink_to_lo(),
|
||||
kind: ast::VisibilityKind::Inherited,
|
||||
|
@ -605,6 +604,7 @@ impl<'a> TraitDef<'a> {
|
|||
attrs: ast::AttrVec::new(),
|
||||
kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
ident,
|
||||
generics: Generics::default(),
|
||||
where_clauses: ast::TyAliasWhereClauses::default(),
|
||||
bounds: Vec::new(),
|
||||
|
@ -789,7 +789,6 @@ impl<'a> TraitDef<'a> {
|
|||
|
||||
cx.item(
|
||||
self.span,
|
||||
Ident::empty(),
|
||||
attrs,
|
||||
ast::ItemKind::Impl(Box::new(ast::Impl {
|
||||
safety: ast::Safety::Default,
|
||||
|
@ -1033,10 +1032,10 @@ impl<'a> MethodDef<'a> {
|
|||
kind: ast::VisibilityKind::Inherited,
|
||||
tokens: None,
|
||||
},
|
||||
ident: method_ident,
|
||||
kind: ast::AssocItemKind::Fn(Box::new(ast::Fn {
|
||||
defaultness,
|
||||
sig,
|
||||
ident: method_ident,
|
||||
generics: fn_generics,
|
||||
contract: None,
|
||||
body: Some(body_block),
|
||||
|
|
|
@ -25,15 +25,15 @@ pub(crate) fn expand(
|
|||
|
||||
// Allow using `#[global_allocator]` on an item statement
|
||||
// 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 ItemKind::Static(box ast::StaticItem { ty, .. }) = &item.kind
|
||||
let (item, ident, is_stmt, ty_span) = if let Annotatable::Item(item) = &item
|
||||
&& 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
|
||||
&& 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 {
|
||||
ecx.dcx().emit_err(errors::AllocMustStatics { span: item.span() });
|
||||
return vec![orig_item];
|
||||
|
@ -41,7 +41,7 @@ pub(crate) fn expand(
|
|||
|
||||
// Generate a bunch of new items using the AllocFnFactory
|
||||
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.
|
||||
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 {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
sig,
|
||||
ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span),
|
||||
generics: Generics::default(),
|
||||
contract: None,
|
||||
body,
|
||||
define_opaque: None,
|
||||
}));
|
||||
let item = self.cx.item(
|
||||
self.span,
|
||||
Ident::from_str_and_span(&global_fn_name(method.name), self.span),
|
||||
self.attrs(),
|
||||
kind,
|
||||
);
|
||||
let item = self.cx.item(self.span, self.attrs(), kind);
|
||||
self.cx.stmt_item(self.ty_span, item)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) =
|
||||
parse_macro_name_and_helper_attrs(self.dcx, attr, "derive")
|
||||
else {
|
||||
|
@ -104,7 +109,7 @@ impl<'a> CollectProcMacros<'a> {
|
|||
id: item.id,
|
||||
span: item.span,
|
||||
trait_name,
|
||||
function_name: item.ident,
|
||||
function_name,
|
||||
attrs: proc_attrs,
|
||||
}));
|
||||
} 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() {
|
||||
self.macros.push(ProcMacro::Attr(ProcMacroDef {
|
||||
id: item.id,
|
||||
span: item.span,
|
||||
function_name: item.ident,
|
||||
function_name,
|
||||
}));
|
||||
} else {
|
||||
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() {
|
||||
self.macros.push(ProcMacro::Bang(ProcMacroDef {
|
||||
id: item.id,
|
||||
span: item.span,
|
||||
function_name: item.ident,
|
||||
function_name,
|
||||
}));
|
||||
} else {
|
||||
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;
|
||||
|
||||
for attr in &item.attrs {
|
||||
|
@ -214,7 +213,13 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
return;
|
||||
};
|
||||
|
||||
if !is_fn {
|
||||
// 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 fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
|
||||
fn_.ident
|
||||
} else {
|
||||
self.dcx
|
||||
.create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
|
||||
span: attr.span,
|
||||
|
@ -222,7 +227,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
})
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if self.is_test_crate {
|
||||
return;
|
||||
|
@ -239,11 +244,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|||
}
|
||||
|
||||
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) {
|
||||
self.collect_attr_proc_macro(item);
|
||||
self.collect_attr_proc_macro(item, fn_ident);
|
||||
} 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);
|
||||
|
@ -278,7 +283,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 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 client = Ident::new(sym::client, span);
|
||||
|
|
|
@ -43,9 +43,8 @@ pub fn inject(
|
|||
|
||||
let item = cx.item(
|
||||
span,
|
||||
Ident::new(name, ident_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);
|
||||
|
@ -68,7 +67,6 @@ pub fn inject(
|
|||
// Inject the relevant crate's prelude.
|
||||
let use_item = cx.item(
|
||||
span,
|
||||
Ident::empty(),
|
||||
thin_vec![cx.attr_word(sym::prelude_import, span)],
|
||||
ast::ItemKind::Use(ast::UseTree {
|
||||
prefix: cx.path(span, import_path),
|
||||
|
|
|
@ -55,12 +55,14 @@ pub(crate) fn expand_test_case(
|
|||
// `#[test_case]` is valid on functions, consts, and statics. Only modify
|
||||
// the item in those cases.
|
||||
match &mut item.kind {
|
||||
ast::ItemKind::Fn(_) | ast::ItemKind::Const(_) | ast::ItemKind::Static(_) => {
|
||||
item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
|
||||
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(
|
||||
// skip the name of the root module
|
||||
&ecx.current_expansion.module.mod_path[1..],
|
||||
&item.ident,
|
||||
ident,
|
||||
));
|
||||
item.vis = ast::Visibility {
|
||||
span: item.vis.span,
|
||||
|
@ -228,7 +230,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
// super::$test_fn(b)
|
||||
cx.expr_call(
|
||||
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)],
|
||||
),
|
||||
],
|
||||
|
@ -254,7 +256,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
// $test_fn()
|
||||
cx.expr_call(
|
||||
ret_ty_sp,
|
||||
cx.expr_path(cx.path(sp, vec![item.ident])),
|
||||
cx.expr_path(cx.path(sp, vec![fn_.ident])),
|
||||
ThinVec::new(),
|
||||
), // )
|
||||
],
|
||||
|
@ -267,15 +269,14 @@ pub(crate) fn expand_test_or_bench(
|
|||
let test_path_symbol = Symbol::intern(&item_path(
|
||||
// skip the name of the root module
|
||||
&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 =
|
||||
cx.item(
|
||||
sp,
|
||||
Ident::new(item.ident.name, sp),
|
||||
thin_vec![
|
||||
// #[cfg(test)]
|
||||
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
|
||||
|
@ -288,6 +289,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
ast::ItemKind::Const(
|
||||
ast::ConstItem {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
ident: Ident::new(fn_.ident.name, sp),
|
||||
generics: ast::Generics::default(),
|
||||
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
define_opaque: None,
|
||||
|
@ -386,7 +388,7 @@ pub(crate) fn expand_test_or_bench(
|
|||
|
||||
// extern crate test
|
||||
let test_extern =
|
||||
cx.item(sp, test_ident, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
|
||||
cx.item(sp, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, test_ident));
|
||||
|
||||
debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
|
||||
|
||||
|
@ -440,8 +442,8 @@ fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>)
|
|||
.emit();
|
||||
}
|
||||
|
||||
fn get_location_info(cx: &ExtCtxt<'_>, item: &ast::Item) -> (Symbol, usize, usize, usize, usize) {
|
||||
let span = item.ident.span;
|
||||
fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, usize, usize) {
|
||||
let span = fn_.ident.span;
|
||||
let (source_file, lo_line, lo_col, hi_line, hi_col) =
|
||||
cx.sess.source_map().span_to_location_info(span);
|
||||
|
||||
|
|
|
@ -134,27 +134,21 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
|||
if let Some(name) = get_test_name(&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);
|
||||
}
|
||||
|
||||
// We don't want to recurse into anything other than mods, since
|
||||
// mods or tests inside of functions will break things
|
||||
if let ast::ItemKind::Mod(
|
||||
_,
|
||||
_,
|
||||
ModKind::Loaded(.., ast::ModSpans { inner_span: span, .. }, _),
|
||||
) = item.kind
|
||||
{
|
||||
let prev_tests = mem::take(&mut self.tests);
|
||||
walk_item_kind(
|
||||
&mut item.kind,
|
||||
item.span,
|
||||
item.id,
|
||||
&mut item.ident,
|
||||
&mut item.vis,
|
||||
(),
|
||||
self,
|
||||
);
|
||||
walk_item_kind(&mut item.kind, item.span, item.id, &mut item.vis, (), self);
|
||||
self.add_test_cases(item.id, span, prev_tests);
|
||||
} else {
|
||||
// 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 {
|
||||
match item.kind {
|
||||
ast::ItemKind::Fn(..) => {
|
||||
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(item.ident.name))
|
||||
match &item.kind {
|
||||
ast::ItemKind::Fn(fn_) => {
|
||||
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name))
|
||||
}
|
||||
_ => EntryPointType::None,
|
||||
}
|
||||
|
@ -295,7 +289,7 @@ fn generate_test_harness(
|
|||
fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
||||
let sp = cx.def_site;
|
||||
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 {
|
||||
PanicStrategy::Unwind => "test_main_static",
|
||||
|
@ -303,10 +297,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
|||
};
|
||||
|
||||
// test::test_main_static(...)
|
||||
let mut test_runner = cx
|
||||
.test_runner
|
||||
.clone()
|
||||
.unwrap_or_else(|| ecx.path(sp, vec![test_id, Ident::from_str_and_span(runner_name, sp)]));
|
||||
let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
|
||||
ecx.path(sp, vec![test_ident, Ident::from_str_and_span(runner_name, sp)])
|
||||
});
|
||||
|
||||
test_runner.span = sp;
|
||||
|
||||
|
@ -317,7 +310,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
|||
// extern crate test
|
||||
let test_extern_stmt = ecx.stmt_item(
|
||||
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]
|
||||
|
@ -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 sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
|
||||
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 {
|
||||
defaultness,
|
||||
sig,
|
||||
ident: main_ident,
|
||||
generics: ast::Generics::default(),
|
||||
contract: None,
|
||||
body: Some(main_body),
|
||||
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 {
|
||||
ident: main_id,
|
||||
attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr],
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: main,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue