diff options
| author | bors <bors@rust-lang.org> | 2019-03-16 20:48:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-16 20:48:40 +0000 |
| commit | 7cf074a1e655ac07d04d045667278fa1a9970b93 (patch) | |
| tree | d2509e198c34af3e41cce2dbde186635384a418a /src/libsyntax/attr | |
| parent | 2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff (diff) | |
| parent | 2fd4cbb3f283b903f55444bb585d38a2539f4e8d (diff) | |
| download | rust-7cf074a1e655ac07d04d045667278fa1a9970b93.tar.gz rust-7cf074a1e655ac07d04d045667278fa1a9970b93.zip | |
Auto merge of #58899 - petrochenkov:derval2, r=estebank
Do not accidentally treat multi-segment meta-items as single-segment Fixes https://github.com/rust-lang/rust/issues/55168 and many other regressions from https://github.com/rust-lang/rust/pull/50030 Basically, attributes like `#[any::prefix::foo]` were commonly interpreted as `#[foo]` due to `name()` successfully returning the last segment (this applies to nested things as well `#[attr(any::prefix::foo)]`).
Diffstat (limited to 'src/libsyntax/attr')
| -rw-r--r-- | src/libsyntax/attr/builtin.rs | 152 | ||||
| -rw-r--r-- | src/libsyntax/attr/mod.rs | 154 |
2 files changed, 143 insertions, 163 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index f7a000935ca..cdfb83c6e56 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -1,6 +1,6 @@ //! Parsing and validation of builtin attributes -use crate::ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind}; +use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; @@ -10,8 +10,8 @@ use syntax_pos::{symbol::Symbol, Span}; use super::{mark_used, MetaItemKind}; enum AttrError { - MultipleItem(Name), - UnknownMetaItem(Name, &'static [&'static str]), + MultipleItem(String), + UnknownMetaItem(String, &'static [&'static str]), MissingSince, MissingFeature, MultipleStabilityLevels, @@ -155,10 +155,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { attrs.iter().any(|item| { item.check_name("feature") && item.meta_item_list().map(|list| { - list.iter().any(|mi| { - mi.word().map(|w| w.name() == feature_name) - .unwrap_or(false) - }) + list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name)) }).unwrap_or(false) }) } @@ -206,7 +203,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let meta = meta.as_ref().unwrap(); let get = |meta: &MetaItem, item: &mut Option<Symbol>| { if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + handle_errors(sess, meta.span, AttrError::MultipleItem(meta.path.to_string())); return false } if let Some(v) = meta.value_str() { @@ -225,9 +222,9 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, )+ for meta in metas { if let Some(mi) = meta.meta_item() { - match &*mi.name().as_str() { + match mi.ident_str() { $( - stringify!($name) + Some(stringify!($name)) => if !get(mi, &mut $name) { continue 'outer }, )+ _ => { @@ -235,7 +232,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, handle_errors( sess, mi.span, - AttrError::UnknownMetaItem(mi.name(), expected), + AttrError::UnknownMetaItem(mi.path.to_string(), expected), ); continue 'outer } @@ -243,7 +240,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } else { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnsupportedLiteral( "unsupported literal", false, @@ -255,7 +252,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } } - match &*meta.name().as_str() { + match meta.ident_str().expect("not a stability level") { "rustc_deprecated" => { if rustc_depr.is_some() { span_err!(diagnostic, item_sp, E0540, @@ -274,11 +271,11 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _) => { - handle_errors(sess, attr.span(), AttrError::MissingSince); + handle_errors(sess, attr.span, AttrError::MissingSince); continue } _ => { - span_err!(diagnostic, attr.span(), E0543, "missing 'reason'"); + span_err!(diagnostic, attr.span, E0543, "missing 'reason'"); continue } } @@ -294,13 +291,13 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, if let Some(feature) = feature { rustc_const_unstable = Some(feature); } else { - span_err!(diagnostic, attr.span(), E0629, "missing 'feature'"); + span_err!(diagnostic, attr.span, E0629, "missing 'feature'"); continue } } "unstable" => { if stab.is_some() { - handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels); + handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break } @@ -309,16 +306,16 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut issue = None; for meta in metas { if let Some(mi) = meta.meta_item() { - match &*mi.name().as_str() { - "feature" => if !get(mi, &mut feature) { continue 'outer }, - "reason" => if !get(mi, &mut reason) { continue 'outer }, - "issue" => if !get(mi, &mut issue) { continue 'outer }, + match mi.ident_str() { + Some("feature") => if !get(mi, &mut feature) { continue 'outer }, + Some("reason") => if !get(mi, &mut reason) { continue 'outer }, + Some("issue") => if !get(mi, &mut issue) { continue 'outer }, _ => { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnknownMetaItem( - mi.name(), + mi.path.to_string(), &["feature", "reason", "issue"] ), ); @@ -328,7 +325,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } else { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnsupportedLiteral( "unsupported literal", false, @@ -347,7 +344,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, if let Ok(issue) = issue.as_str().parse() { issue } else { - span_err!(diagnostic, attr.span(), E0545, + span_err!(diagnostic, attr.span, E0545, "incorrect 'issue'"); continue } @@ -360,42 +357,44 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _, _) => { - handle_errors(sess, attr.span(), AttrError::MissingFeature); + handle_errors(sess, attr.span, AttrError::MissingFeature); continue } _ => { - span_err!(diagnostic, attr.span(), E0547, "missing 'issue'"); + span_err!(diagnostic, attr.span, E0547, "missing 'issue'"); continue } } } "stable" => { if stab.is_some() { - handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels); + handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break } let mut feature = None; let mut since = None; for meta in metas { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "feature" => if !get(mi, &mut feature) { continue 'outer }, - "since" => if !get(mi, &mut since) { continue 'outer }, + match meta { + NestedMetaItem::MetaItem(mi) => { + match mi.ident_str() { + Some("feature") => + if !get(mi, &mut feature) { continue 'outer }, + Some("since") => + if !get(mi, &mut since) { continue 'outer }, _ => { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnknownMetaItem( - mi.name(), &["since", "note"], + mi.path.to_string(), &["since", "note"], ), ); continue 'outer } } }, - NestedMetaItemKind::Literal(lit) => { + NestedMetaItem::Literal(lit) => { handle_errors( sess, lit.span, @@ -422,11 +421,11 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _) => { - handle_errors(sess, attr.span(), AttrError::MissingFeature); + handle_errors(sess, attr.span, AttrError::MissingFeature); continue } _ => { - handle_errors(sess, attr.span(), AttrError::MissingSince); + handle_errors(sess, attr.span, AttrError::MissingSince); continue } } @@ -483,8 +482,8 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat gated_cfg.check_and_emit(sess, feats); } let error = |span, msg| { sess.span_diagnostic.span_err(span, msg); true }; - if cfg.ident.segments.len() != 1 { - return error(cfg.ident.span, "`cfg` predicate key must be an identifier"); + if cfg.path.segments.len() != 1 { + return error(cfg.path.span, "`cfg` predicate key must be an identifier"); } match &cfg.node { MetaItemKind::List(..) => { @@ -502,7 +501,8 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat true } MetaItemKind::NameValue(..) | MetaItemKind::Word => { - sess.config.contains(&(cfg.name(), cfg.value_str())) + let ident = cfg.ident().expect("multi-segment cfg predicate"); + sess.config.contains(&(ident.name, cfg.value_str())) } } }) @@ -520,7 +520,7 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) if !mi.is_meta_item() { handle_errors( sess, - mi.span, + mi.span(), AttrError::UnsupportedLiteral( "unsupported literal", false @@ -532,14 +532,14 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) // The unwraps below may look dangerous, but we've already asserted // that they won't fail with the loop above. - match &*cfg.name().as_str() { - "any" => mis.iter().any(|mi| { + match cfg.ident_str() { + Some("any") => mis.iter().any(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "all" => mis.iter().all(|mi| { + Some("all") => mis.iter().all(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "not" => { + Some("not") => { if mis.len() != 1 { span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern"); return false; @@ -547,8 +547,9 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) !eval_condition(mis[0].meta_item().unwrap(), sess, eval) }, - p => { - span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p); + _ => { + span_err!(sess.span_diagnostic, cfg.span, E0537, + "invalid predicate `{}`", cfg.path); false } } @@ -602,7 +603,9 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, MetaItemKind::List(list) => { let get = |meta: &MetaItem, item: &mut Option<Symbol>| { if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + handle_errors( + sess, meta.span, AttrError::MultipleItem(meta.path.to_string()) + ); return false } if let Some(v) = meta.value_str() { @@ -630,22 +633,23 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, let mut since = None; let mut note = None; for meta in list { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "note" => if !get(mi, &mut note) { continue 'outer }, + match meta { + NestedMetaItem::MetaItem(mi) => { + match mi.ident_str() { + Some("since") => if !get(mi, &mut since) { continue 'outer }, + Some("note") => if !get(mi, &mut note) { continue 'outer }, _ => { handle_errors( sess, - meta.span, - AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), + meta.span(), + AttrError::UnknownMetaItem(mi.path.to_string(), + &["since", "note"]), ); continue 'outer } } } - NestedMetaItemKind::Literal(lit) => { + NestedMetaItem::Literal(lit) => { handle_errors( sess, lit.span, @@ -714,7 +718,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { if !item.is_meta_item() { handle_errors( sess, - item.span, + item.span(), AttrError::UnsupportedLiteral( "meta item in `repr` must be an identifier", false, @@ -724,19 +728,13 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { } let mut recognised = false; - if let Some(mi) = item.word() { - let word = &*mi.name().as_str(); - let hint = match word { - "C" => Some(ReprC), - "packed" => Some(ReprPacked(1)), - "simd" => Some(ReprSimd), - "transparent" => Some(ReprTransparent), - _ => match int_type_of_word(word) { - Some(ity) => Some(ReprInt(ity)), - None => { - None - } - } + if item.is_word() { + let hint = match item.ident_str() { + Some("C") => Some(ReprC), + Some("packed") => Some(ReprPacked(1)), + Some("simd") => Some(ReprSimd), + Some("transparent") => Some(ReprTransparent), + name => name.and_then(|name| int_type_of_word(name)).map(ReprInt), }; if let Some(h) = hint { @@ -777,20 +775,20 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { }; } if let Some(literal_error) = literal_error { - span_err!(diagnostic, item.span, E0589, + span_err!(diagnostic, item.span(), E0589, "invalid `repr(align)` attribute: {}", literal_error); } } else { if let Some(meta_item) = item.meta_item() { - if meta_item.name() == "align" { + if meta_item.check_name("align") { if let MetaItemKind::NameValue(ref value) = meta_item.node { recognised = true; - let mut err = struct_span_err!(diagnostic, item.span, E0693, + let mut err = struct_span_err!(diagnostic, item.span(), E0693, "incorrect `repr(align)` attribute format"); match value.node { ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { err.span_suggestion( - item.span, + item.span(), "use parentheses instead", format!("align({})", int), Applicability::MachineApplicable @@ -798,7 +796,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { } ast::LitKind::Str(s, _) => { err.span_suggestion( - item.span, + item.span(), "use parentheses instead", format!("align({})", s), Applicability::MachineApplicable @@ -813,7 +811,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> { } if !recognised { // Not a word we recognize - span_err!(diagnostic, item.span, E0552, + span_err!(diagnostic, item.span(), E0552, "unrecognized representation hint"); } } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index b5fc8507314..1a8faa43fff 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -13,7 +13,7 @@ pub use StabilityLevel::*; use crate::ast; use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; -use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; +use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; use crate::source_map::{BytePos, Spanned, respan, dummy_spanned}; @@ -64,36 +64,33 @@ pub fn is_known_lint_tool(m_item: Ident) -> bool { } impl NestedMetaItem { - /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem. + /// Returns the MetaItem if self is a NestedMetaItem::MetaItem. pub fn meta_item(&self) -> Option<&MetaItem> { - match self.node { - NestedMetaItemKind::MetaItem(ref item) => Some(item), + match *self { + NestedMetaItem::MetaItem(ref item) => Some(item), _ => None } } - /// Returns the Lit if self is a NestedMetaItemKind::Literal. + /// Returns the Lit if self is a NestedMetaItem::Literal. pub fn literal(&self) -> Option<&Lit> { - match self.node { - NestedMetaItemKind::Literal(ref lit) => Some(lit), + match *self { + NestedMetaItem::Literal(ref lit) => Some(lit), _ => None } } - /// Returns the Span for `self`. - pub fn span(&self) -> Span { - self.span - } - /// Returns `true` if this list item is a MetaItem with a name of `name`. pub fn check_name(&self, name: &str) -> bool { self.meta_item().map_or(false, |meta_item| meta_item.check_name(name)) } - /// Returns the name of the meta item, e.g., `foo` in `#[foo]`, - /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem - pub fn name(&self) -> Option<Name> { - self.meta_item().and_then(|meta_item| Some(meta_item.name())) + /// For a single-segment meta-item returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option<Ident> { + self.meta_item().and_then(|meta_item| meta_item.ident()) + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } /// Gets the string value if self is a MetaItem and the MetaItem is a @@ -108,25 +105,14 @@ impl NestedMetaItem { |meta_item| meta_item.meta_item_list().and_then( |meta_item_list| { if meta_item_list.len() == 1 { - let nested_item = &meta_item_list[0]; - if nested_item.is_literal() { - Some((meta_item.name(), nested_item.literal().unwrap())) - } else { - None + if let Some(ident) = meta_item.ident() { + if let Some(lit) = meta_item_list[0].literal() { + return Some((ident.name, lit)); + } } } - else { - None - }})) - } - - /// Returns a MetaItem if self is a MetaItem with Kind Word. - pub fn word(&self) -> Option<&MetaItem> { - self.meta_item().and_then(|meta_item| if meta_item.is_word() { - Some(meta_item) - } else { - None - }) + None + })) } /// Gets a list of inner meta items from a list MetaItem type. @@ -146,7 +132,7 @@ impl NestedMetaItem { /// Returns `true` if self is a MetaItem and the meta item is a word. pub fn is_word(&self) -> bool { - self.word().is_some() + self.meta_item().map_or(false, |meta_item| meta_item.is_word()) } /// Returns `true` if self is a MetaItem and the meta item is a ValueString. @@ -160,10 +146,6 @@ impl NestedMetaItem { } } -fn name_from_path(path: &Path) -> Name { - path.segments.last().expect("empty path in attribute").ident.name -} - impl Attribute { /// Returns `true` if the attribute's path matches the argument. If it matches, then the /// attribute is marked as used. @@ -177,10 +159,16 @@ impl Attribute { matches } - /// Returns the **last** segment of the name of this attribute. - /// e.g., `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`. - pub fn name(&self) -> Name { - name_from_path(&self.path) + /// For a single-segment attribute returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option<Ident> { + if self.path.segments.len() == 1 { + Some(self.path.segments[0].ident) + } else { + None + } + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } pub fn value_str(&self) -> Option<Symbol> { @@ -195,11 +183,7 @@ impl Attribute { } pub fn is_word(&self) -> bool { - self.path.segments.len() == 1 && self.tokens.is_empty() - } - - pub fn span(&self) -> Span { - self.span + self.tokens.is_empty() } pub fn is_meta_item_list(&self) -> bool { @@ -213,8 +197,16 @@ impl Attribute { } impl MetaItem { - pub fn name(&self) -> Name { - name_from_path(&self.ident) + /// For a single-segment meta-item returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option<Ident> { + if self.path.segments.len() == 1 { + Some(self.path.segments[0].ident) + } else { + None + } + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } // #[attribute(name = "value")] @@ -252,10 +244,8 @@ impl MetaItem { } } - pub fn span(&self) -> Span { self.span } - pub fn check_name(&self, name: &str) -> bool { - self.name() == name + self.path == name } pub fn is_value_str(&self) -> bool { @@ -265,14 +255,6 @@ impl MetaItem { pub fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } - - pub fn is_scoped(&self) -> Option<Ident> { - if self.ident.segments.len() > 1 { - Some(self.ident.segments[0].ident) - } else { - None - } - } } impl Attribute { @@ -280,7 +262,7 @@ impl Attribute { pub fn meta(&self) -> Option<MetaItem> { let mut tokens = self.tokens.trees().peekable(); Some(MetaItem { - ident: self.path.clone(), + path: self.path.clone(), node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) { if tokens.peek().is_some() { return None; @@ -326,7 +308,7 @@ impl Attribute { pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> { Ok(MetaItem { - ident: self.path.clone(), + path: self.path.clone(), node: self.parse(sess, |parser| parser.parse_meta_item_kind())?, span: self.span, }) @@ -364,19 +346,19 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem } pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } + MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } } pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) } + MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) } } pub fn mk_word_item(ident: Ident) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word } + MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word } } pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { - respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident))) + NestedMetaItem::MetaItem(mk_word_item(ident)) } pub fn mk_attr_id() -> AttrId { @@ -400,7 +382,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute Attribute { id, style: ast::AttrStyle::Inner, - path: item.ident, + path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, span: sp, @@ -417,7 +399,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute Attribute { id, style: ast::AttrStyle::Outer, - path: item.ident, + path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, span: sp, @@ -468,7 +450,7 @@ impl MetaItem { fn tokens(&self) -> TokenStream { let mut idents = vec![]; let mut last_pos = BytePos(0 as u32); - for (i, segment) in self.ident.segments.iter().enumerate() { + for (i, segment) in self.path.segments.iter().enumerate() { let is_first = i == 0; if !is_first { let mod_sep_span = Span::new(last_pos, @@ -488,7 +470,7 @@ impl MetaItem { where I: Iterator<Item = TokenTree>, { // FIXME: Share code with `parse_path`. - let ident = match tokens.next() { + let path = match tokens.next() { Some(TokenTree::Token(span, token @ Token::Ident(..))) | Some(TokenTree::Token(span, token @ Token::ModSep)) => 'arm: { let mut segments = if let Token::Ident(ident, _) = token { @@ -529,11 +511,11 @@ impl MetaItem { let node = MetaItemKind::from_tokens(tokens)?; let hi = match node { MetaItemKind::NameValue(ref lit) => lit.span.hi(), - MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()), - _ => ident.span.hi(), + MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), + _ => path.span.hi(), }; - let span = ident.span.with_hi(hi); - Some(MetaItem { ident, node, span }) + let span = path.span.with_hi(hi); + Some(MetaItem { path, node, span }) } } @@ -552,7 +534,7 @@ impl MetaItemKind { if i > 0 { tokens.push(TokenTree::Token(span, Token::Comma).into()); } - item.node.tokens().append_to_tree_and_joint_vec(&mut tokens); + item.tokens().append_to_tree_and_joint_vec(&mut tokens); } TokenTree::Delimited( DelimSpan::from_single(span), @@ -586,8 +568,8 @@ impl MetaItemKind { let mut tokens = delimited.into_trees().peekable(); let mut result = Vec::new(); while let Some(..) = tokens.peek() { - let item = NestedMetaItemKind::from_tokens(&mut tokens)?; - result.push(respan(item.span(), item)); + let item = NestedMetaItem::from_tokens(&mut tokens)?; + result.push(item); match tokens.next() { None | Some(TokenTree::Token(_, Token::Comma)) => {} _ => return None, @@ -597,32 +579,32 @@ impl MetaItemKind { } } -impl NestedMetaItemKind { - fn span(&self) -> Span { +impl NestedMetaItem { + pub fn span(&self) -> Span { match *self { - NestedMetaItemKind::MetaItem(ref item) => item.span, - NestedMetaItemKind::Literal(ref lit) => lit.span, + NestedMetaItem::MetaItem(ref item) => item.span, + NestedMetaItem::Literal(ref lit) => lit.span, } } fn tokens(&self) -> TokenStream { match *self { - NestedMetaItemKind::MetaItem(ref item) => item.tokens(), - NestedMetaItemKind::Literal(ref lit) => lit.tokens(), + NestedMetaItem::MetaItem(ref item) => item.tokens(), + NestedMetaItem::Literal(ref lit) => lit.tokens(), } } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItemKind> + fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem> where I: Iterator<Item = TokenTree>, { if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() { if let Some(node) = LitKind::from_token(token) { tokens.next(); - return Some(NestedMetaItemKind::Literal(respan(span, node))); + return Some(NestedMetaItem::Literal(respan(span, node))); } } - MetaItem::from_tokens(tokens).map(NestedMetaItemKind::MetaItem) + MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem) } } |
