Avoid more unnecessary MetaItem/Attribute conversions.

In `Expander::expand` the code currently uses `mk_attr_outer` to convert
a `MetaItem` to an `Attribute`, and then follows that with
`meta_item_list` which converts back. This commit avoids the unnecessary
conversions.

There was one wrinkle: the existing conversions caused the bogus `<>` on
`Default<>` to be removed. With the conversion gone, we get a second
error message about the `<>`. This is a rare case, so I think it
probably doesn't matter much.
This commit is contained in:
Nicholas Nethercote 2022-11-28 11:17:45 +11:00
parent fc2a8a0c67
commit a709f87be7
3 changed files with 33 additions and 24 deletions

View File

@ -1,7 +1,7 @@
use crate::cfg_eval::cfg_eval; use crate::cfg_eval::cfg_eval;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::{attr, token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_ast::{token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_errors::{struct_span_err, Applicability}; use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate; use rustc_feature::AttributeTemplate;
@ -40,28 +40,29 @@ impl MultiItemModifier for Expander {
sym::derive, sym::derive,
template, template,
); );
let attr =
attr::mk_attr_outer(&sess.parse_sess.attr_id_generator, meta_item.clone());
let mut resolutions: Vec<_> = attr let mut resolutions = match &meta_item.kind {
.meta_item_list() MetaItemKind::List(list) => {
.unwrap_or_default() list.iter()
.into_iter() .filter_map(|nested_meta| match nested_meta {
.filter_map(|nested_meta| match nested_meta { NestedMetaItem::MetaItem(meta) => Some(meta),
NestedMetaItem::MetaItem(meta) => Some(meta), NestedMetaItem::Lit(lit) => {
NestedMetaItem::Lit(lit) => { // Reject `#[derive("Debug")]`.
// Reject `#[derive("Debug")]`. report_unexpected_meta_item_lit(sess, &lit);
report_unexpected_meta_item_lit(sess, &lit); None
None }
} })
}) .map(|meta| {
.map(|meta| { // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths. // paths.
report_path_args(sess, &meta); report_path_args(sess, &meta);
meta.path meta.path.clone()
}) })
.map(|path| (path, dummy_annotatable(), None, self.0)) .map(|path| (path, dummy_annotatable(), None, self.0))
.collect(); .collect()
}
_ => vec![],
};
// Do not configure or clone items unless necessary. // Do not configure or clone items unless necessary.
match &mut resolutions[..] { match &mut resolutions[..] {

View File

@ -9,5 +9,7 @@ macro_rules! foo { () => () }
fn main() { fn main() {
foo::<T>!(); //~ ERROR generic arguments in macro path foo::<T>!(); //~ ERROR generic arguments in macro path
foo::<>!(); //~ ERROR generic arguments in macro path foo::<>!(); //~ ERROR generic arguments in macro path
m!(Default<>); //~ ERROR unexpected generic arguments in path m!(Default<>);
//~^ ERROR unexpected generic arguments in path
//~^^ ERROR generic arguments in macro path
} }

View File

@ -16,5 +16,11 @@ error: unexpected generic arguments in path
LL | m!(Default<>); LL | m!(Default<>);
| ^^ | ^^
error: aborting due to 3 previous errors error: generic arguments in macro path
--> $DIR/macro-ty-params.rs:12:15
|
LL | m!(Default<>);
| ^^
error: aborting due to 4 previous errors