diff options
| -rw-r--r-- | src/librustc/lint/levels.rs | 73 | ||||
| -rw-r--r-- | src/test/ui/lint/reasons-erroneous.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/lint/reasons-erroneous.stderr | 24 |
3 files changed, 69 insertions, 36 deletions
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index ee878da0066..d44facedc8b 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -21,6 +21,7 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, use session::Session; use syntax::ast; use syntax::attr; +use syntax::feature_gate; use syntax::source_map::MultiSpan; use syntax::symbol::Symbol; use util::nodemap::FxHashMap; @@ -210,7 +211,7 @@ impl<'a> LintLevelsBuilder<'a> { let meta = unwrap_or!(attr.meta(), continue); attr::mark_used(attr); - let metas = if let Some(metas) = meta.meta_item_list() { + let mut metas = if let Some(metas) = meta.meta_item_list() { metas } else { let mut err = bad_attr(meta.span); @@ -218,44 +219,43 @@ impl<'a> LintLevelsBuilder<'a> { continue }; - // Before processing the lint names, look for a reason (RFC 2383). + // Before processing the lint names, look for a reason (RFC 2383) + // at the end. let mut reason = None; - for li in metas { - if let Some(item) = li.meta_item() { - match item.node { - ast::MetaItemKind::Word => {} // actual lint names handled later - ast::MetaItemKind::NameValue(ref name_value) => { - let gate_reasons = !self.sess.features_untracked().lint_reasons; - let name_ident = item.ident.segments[0].ident; - let name = name_ident.name.as_str(); - - if name == "reason" { - if let ast::LitKind::Str(rationale, _) = name_value.node { - if gate_reasons { - feature_gate::emit_feature_err( - &self.sess.parse_sess, - "lint_reasons", - item.span, - feature_gate::GateIssue::Language, - "lint reasons are experimental" - ); - } else { - reason = Some(rationale); - } + let tail_li = &metas[metas.len()-1]; + if let Some(item) = tail_li.meta_item() { + match item.node { + ast::MetaItemKind::Word => {} // actual lint names handled later + ast::MetaItemKind::NameValue(ref name_value) => { + let gate_reasons = !self.sess.features_untracked().lint_reasons; + if item.ident == "reason" { + // found reason, reslice meta list to exclude it + metas = &metas[0..metas.len()-1]; + if let ast::LitKind::Str(rationale, _) = name_value.node { + if gate_reasons { + feature_gate::emit_feature_err( + &self.sess.parse_sess, + "lint_reasons", + item.span, + feature_gate::GateIssue::Language, + "lint reasons are experimental" + ); } else { - let mut err = bad_attr(name_value.span); - err.help("reason must be a string literal"); - err.emit(); + reason = Some(rationale); } } else { - let mut err = bad_attr(item.span); + let mut err = bad_attr(name_value.span); + err.help("reason must be a string literal"); err.emit(); } - }, - ast::MetaItemKind::List(_) => { + } else { let mut err = bad_attr(item.span); err.emit(); } + }, + ast::MetaItemKind::List(_) => { + let mut err = bad_attr(item.span); + err.emit(); } } } @@ -263,7 +263,18 @@ impl<'a> LintLevelsBuilder<'a> { for li in metas { let word = match li.word() { Some(word) => word, - None => { continue; } + None => { + let mut err = bad_attr(li.span); + if let Some(item) = li.meta_item() { + if let ast::MetaItemKind::NameValue(_) = item.node { + if item.ident == "reason" { + err.help("reason in lint attribute must come last"); + } + } + } + err.emit(); + continue; + } }; let tool_name = if let Some(lint_tool) = word.is_scoped() { if !attr::is_known_lint_tool(lint_tool) { diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs index 90111a9c4e1..e42b329338b 100644 --- a/src/test/ui/lint/reasons-erroneous.rs +++ b/src/test/ui/lint/reasons-erroneous.rs @@ -12,7 +12,13 @@ //~^ ERROR malformed lint attribute #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] //~^ ERROR malformed lint attribute -#![warn(ellipsis_inclusive_range_patterns, reason)] +#![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] +//~^ ERROR malformed lint attribute +//~| HELP reason in lint attribute must come last +#![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] +//~^ ERROR malformed lint attribute +//~| HELP reason in lint attribute must come last +#![warn(missing_copy_implementations, reason)] //~^ WARN unknown lint fn main() {} diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr index f66999e9272..6842686ecba 100644 --- a/src/test/ui/lint/reasons-erroneous.stderr +++ b/src/test/ui/lint/reasons-erroneous.stderr @@ -32,14 +32,30 @@ error[E0452]: malformed lint attribute LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: unknown lint: `reason` +error[E0452]: malformed lint attribute --> $DIR/reasons-erroneous.rs:15:44 | -LL | #![warn(ellipsis_inclusive_range_patterns, reason)] - | ^^^^^^ +LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: reason in lint attribute must come last + +error[E0452]: malformed lint attribute + --> $DIR/reasons-erroneous.rs:18:25 + | +LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: reason in lint attribute must come last + +warning: unknown lint: `reason` + --> $DIR/reasons-erroneous.rs:21:39 + | +LL | #![warn(missing_copy_implementations, reason)] + | ^^^^^^ | = note: #[warn(unknown_lints)] on by default -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0452`. |
