mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
refactor how eii expansion is wrapped fixing 149980
This commit is contained in:
@@ -60,12 +60,18 @@ fn eii_(
|
||||
) -> Vec<Annotatable> {
|
||||
let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span);
|
||||
|
||||
let (item, stmt) = if let Annotatable::Item(item) = item {
|
||||
(item, false)
|
||||
let (item, wrap_item): (_, &dyn Fn(_) -> _) = if let Annotatable::Item(item) = item {
|
||||
(item, &Annotatable::Item)
|
||||
} else if let Annotatable::Stmt(ref stmt) = item
|
||||
&& let StmtKind::Item(ref item) = stmt.kind
|
||||
{
|
||||
(item.clone(), true)
|
||||
(item.clone(), &|item| {
|
||||
Annotatable::Stmt(Box::new(Stmt {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: StmtKind::Item(item),
|
||||
span: eii_attr_span,
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
|
||||
span: eii_attr_span,
|
||||
@@ -74,23 +80,25 @@ fn eii_(
|
||||
return vec![item];
|
||||
};
|
||||
|
||||
let orig_item = item.clone();
|
||||
|
||||
let item = *item;
|
||||
|
||||
let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = item else {
|
||||
let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } =
|
||||
item.as_ref()
|
||||
else {
|
||||
ecx.dcx().emit_err(EiiSharedMacroExpectedFunction {
|
||||
span: eii_attr_span,
|
||||
name: path_to_string(&meta_item.path),
|
||||
});
|
||||
return vec![Annotatable::Item(Box::new(item))];
|
||||
return vec![wrap_item(item)];
|
||||
};
|
||||
// only clone what we need
|
||||
let attrs = attrs.clone();
|
||||
let func = (**func).clone();
|
||||
let vis = vis.clone();
|
||||
|
||||
let attrs_from_decl =
|
||||
filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);
|
||||
|
||||
let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else {
|
||||
return vec![Annotatable::Item(orig_item)];
|
||||
return vec![wrap_item(item)];
|
||||
};
|
||||
|
||||
// span of the declaring item without attributes
|
||||
@@ -115,7 +123,7 @@ fn eii_(
|
||||
ecx,
|
||||
eii_attr_span,
|
||||
item_span,
|
||||
*func,
|
||||
func,
|
||||
vis,
|
||||
&attrs_from_decl,
|
||||
)));
|
||||
@@ -128,20 +136,7 @@ fn eii_(
|
||||
decl_span,
|
||||
)));
|
||||
|
||||
if stmt {
|
||||
return_items
|
||||
.into_iter()
|
||||
.map(|i| {
|
||||
Annotatable::Stmt(Box::new(Stmt {
|
||||
id: DUMMY_NODE_ID,
|
||||
kind: StmtKind::Item(i),
|
||||
span: eii_attr_span,
|
||||
}))
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
return_items.into_iter().map(|i| Annotatable::Item(i)).collect()
|
||||
}
|
||||
return_items.into_iter().map(wrap_item).collect()
|
||||
}
|
||||
|
||||
/// Decide on the name of the macro that can be used to implement the EII.
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
#![feature(extern_item_impls)]
|
||||
// EIIs can, despite not being super useful, be declared in statement position
|
||||
// nested inside items. Items in statement position, when expanded as part of a macro,
|
||||
// need to be wrapped slightly differently (in an `ast::Statement`).
|
||||
// We did this on the happy path (no errors), but when there was an error, we'd
|
||||
// replace it with *just* an `ast::Item` not wrapped in an `ast::Statement`.
|
||||
// This caused an ICE (https://github.com/rust-lang/rust/issues/149980).
|
||||
// this test fails to build, but demonstrates that no ICE is produced.
|
||||
|
||||
fn main() {
|
||||
struct Bar;
|
||||
|
||||
#[eii]
|
||||
//~^ ERROR `#[eii]` is only valid on functions
|
||||
impl Bar {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
error: `#[eii]` is only valid on functions
|
||||
--> $DIR/error_statement_position.rs:13:5
|
||||
|
|
||||
LL | #[eii]
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Reference in New Issue
Block a user