diff options
| author | bors <bors@rust-lang.org> | 2019-07-28 01:03:16 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-07-28 01:03:16 +0000 |
| commit | 9a239ef4ded03d155c72b68b5a2dd7aff013e141 (patch) | |
| tree | ddecacf7cf04b32211999b7d65dae0bbf2012102 /src/libsyntax/parse | |
| parent | c798dffac9dc8c82374db48f5b474690cc6e9686 (diff) | |
| parent | 34c0f4698bda7e06d66ee9040a2923250b0c12d0 (diff) | |
| download | rust-9a239ef4ded03d155c72b68b5a2dd7aff013e141.tar.gz rust-9a239ef4ded03d155c72b68b5a2dd7aff013e141.zip | |
Auto merge of #63057 - Centril:rollup-z3a3c6v, r=Centril
Rollup of 8 pull requests Successful merges: - #61207 (Allow lifetime elision in `Pin<&(mut) Self>`) - #62074 (squash of all commits for nth_back on ChunksMut) - #62771 (Break dependencies between `syntax_ext` and other crates) - #62883 (Refactoring use common code between option, result and accum) - #62949 (Re-enable assertions in PPC dist builder) - #62996 (tidy: Add a check for inline unit tests) - #63038 (Make more informative error on outer attribute after inner) - #63050 (ci: download awscli from our mirror) Failed merges: r? @ghost
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 61 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 5 |
3 files changed, 51 insertions, 18 deletions
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 1758d0b0bb9..af484c886ab 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -4,6 +4,7 @@ use crate::parse::{SeqSep, PResult}; use crate::parse::token::{self, Nonterminal, DelimToken}; use crate::parse::parser::{Parser, TokenType, PathStyle}; use crate::tokenstream::{TokenStream, TokenTree}; +use crate::source_map::Span; use log::debug; use smallvec::smallvec; @@ -11,7 +12,7 @@ use smallvec::smallvec; #[derive(Debug)] enum InnerAttributeParsePolicy<'a> { Permitted, - NotPermitted { reason: &'a str }, + NotPermitted { reason: &'a str, saw_doc_comment: bool, prev_attr_sp: Option<Span> }, } const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \ @@ -42,7 +43,11 @@ impl<'a> Parser<'a> { DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG }; let inner_parse_policy = - InnerAttributeParsePolicy::NotPermitted { reason: inner_error_reason }; + InnerAttributeParsePolicy::NotPermitted { + reason: inner_error_reason, + saw_doc_comment: just_parsed_doc_comment, + prev_attr_sp: attrs.last().and_then(|a| Some(a.span)) + }; let attr = self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?; attrs.push(attr); just_parsed_doc_comment = false; @@ -76,8 +81,11 @@ impl<'a> Parser<'a> { let inner_parse_policy = if permit_inner { InnerAttributeParsePolicy::Permitted } else { - InnerAttributeParsePolicy::NotPermitted - { reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG } + InnerAttributeParsePolicy::NotPermitted { + reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG, + saw_doc_comment: false, + prev_attr_sp: None + } }; self.parse_attribute_with_inner_parse_policy(inner_parse_policy) } @@ -98,19 +106,9 @@ impl<'a> Parser<'a> { if let InnerAttributeParsePolicy::Permitted = inner_parse_policy { self.expected_tokens.push(TokenType::Token(token::Not)); } + let style = if self.token == token::Not { self.bump(); - if let InnerAttributeParsePolicy::NotPermitted { reason } = inner_parse_policy - { - let span = self.token.span; - self.diagnostic() - .struct_span_err(span, reason) - .note("inner attributes, like `#![no_std]`, annotate the item \ - enclosing them, and are usually found at the beginning of \ - source files. Outer attributes, like `#[test]`, annotate the \ - item following them.") - .emit() - } ast::AttrStyle::Inner } else { ast::AttrStyle::Outer @@ -121,7 +119,38 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Bracket))?; let hi = self.prev_span; - (lo.to(hi), path, tokens, style) + let attr_sp = lo.to(hi); + + // Emit error if inner attribute is encountered and not permitted + if style == ast::AttrStyle::Inner { + if let InnerAttributeParsePolicy::NotPermitted { reason, + saw_doc_comment, prev_attr_sp } = inner_parse_policy { + let prev_attr_note = if saw_doc_comment { + "previous doc comment" + } else { + "previous outer attribute" + }; + + let mut diagnostic = self + .diagnostic() + .struct_span_err(attr_sp, reason); + + if let Some(prev_attr_sp) = prev_attr_sp { + diagnostic + .span_label(attr_sp, "not permitted following an outer attibute") + .span_label(prev_attr_sp, prev_attr_note); + } + + diagnostic + .note("inner attributes, like `#![no_std]`, annotate the item \ + enclosing them, and are usually found at the beginning of \ + source files. Outer attributes, like `#[test]`, annotate the \ + item following them.") + .emit() + } + } + + (attr_sp, path, tokens, style) } _ => { let token_str = self.this_token_to_string(); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 52f65e1b474..3cd5464f357 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -794,7 +794,7 @@ mod tests { use std::path::PathBuf; use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; - use rustc_data_structures::sync::Lock; + use rustc_data_structures::sync::{Lock, Once}; fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess { let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), @@ -817,6 +817,7 @@ mod tests { param_attr_spans: Lock::new(Vec::new()), let_chains_spans: Lock::new(Vec::new()), async_closure_spans: Lock::new(Vec::new()), + injected_crate_name: Once::new(), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 225065c1cf1..1aac8bbb7aa 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -10,9 +10,10 @@ use crate::parse::token::TokenKind; use crate::tokenstream::{TokenStream, TokenTree}; use crate::diagnostics::plugin::ErrorMap; use crate::print::pprust; +use crate::symbol::Symbol; use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; -use rustc_data_structures::sync::{Lrc, Lock}; +use rustc_data_structures::sync::{Lrc, Lock, Once}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; use syntax_pos::edition::Edition; @@ -58,6 +59,7 @@ pub struct ParseSess { pub let_chains_spans: Lock<Vec<Span>>, // Places where `async || ..` exprs were used and should be feature gated. pub async_closure_spans: Lock<Vec<Span>>, + pub injected_crate_name: Once<Symbol>, } impl ParseSess { @@ -86,6 +88,7 @@ impl ParseSess { param_attr_spans: Lock::new(Vec::new()), let_chains_spans: Lock::new(Vec::new()), async_closure_spans: Lock::new(Vec::new()), + injected_crate_name: Once::new(), } } |
