diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-04-19 00:42:18 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-04-24 20:59:44 +0300 |
| commit | 6c44bea64435fd3859439a6ecab7758855a13f07 (patch) | |
| tree | 8035ecf05376fd4cb0723d1dbce3da49e28fcc49 /src/libsyntax/parse | |
| parent | b32d7b592306a2784585e842193db1546a2f9587 (diff) | |
| download | rust-6c44bea64435fd3859439a6ecab7758855a13f07.tar.gz rust-6c44bea64435fd3859439a6ecab7758855a13f07.zip | |
syntax: Check paths in visibilities for type parameters
syntax: Merge PathParsingMode::NoTypesAllowed and PathParsingMode::ImportPrefix syntax: Rename PathParsingMode and its variants to better express their purpose syntax: Remove obsolete error message about 'self lifetime syntax: Remove ALLOW_MODULE_PATHS workaround syntax/resolve: Adjust some error messages resolve: Compare unhygienic (not renamed) names with keywords::Invalid, invalid identifiers may appear to be valid after renaming
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 121 |
2 files changed, 61 insertions, 74 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 265a432ae82..2eda13adcb5 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -13,8 +13,7 @@ use codemap::{BytePos, CharPos, CodeMap, Pos, Span}; use codemap; use errors::{FatalError, Handler, DiagnosticBuilder}; use ext::tt::transcribe::tt_next_token; -use parse::token::str_to_ident; -use parse::token; +use parse::token::{self, keywords, str_to_ident}; use str::char_at; use rustc_unicode::property::Pattern_White_Space; @@ -1229,14 +1228,9 @@ impl<'a> StringReader<'a> { }); let keyword_checking_token = &token::Ident(keyword_checking_ident); let last_bpos = self.last_pos; - if keyword_checking_token.is_keyword(token::keywords::SelfValue) { - self.err_span_(start, - last_bpos, - "invalid lifetime name: 'self is no longer a special \ - lifetime"); - } else if keyword_checking_token.is_any_keyword() && - !keyword_checking_token.is_keyword(token::keywords::Static) { - self.err_span_(start, last_bpos, "invalid lifetime name"); + if keyword_checking_token.is_any_keyword() && + !keyword_checking_token.is_keyword(keywords::Static) { + self.err_span_(start, last_bpos, "lifetimes cannot use keyword names"); } return token::Lifetime(ident); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3eec497c331..a4d2c5b6110 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::PathParsingMode::*; - use abi::{self, Abi}; use ast::BareFnTy; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; @@ -51,7 +49,7 @@ use parse::common::SeqSep; use parse::lexer::{Reader, TokenAndSpan}; use parse::obsolete::{ParserObsoleteMethods, ObsoleteSyntax}; use parse::token::{self, intern, MatchNt, SubstNt, SpecialVarNt, InternedString}; -use parse::token::{keywords, special_idents, SpecialMacroVar}; +use parse::token::{keywords, SpecialMacroVar}; use parse::{new_sub_parser_from_file, ParseSess}; use util::parser::{AssocOp, Fixity}; use print::pprust; @@ -69,26 +67,24 @@ bitflags! { const RESTRICTION_STMT_EXPR = 1 << 0, const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1, const NO_NONINLINE_MOD = 1 << 2, - const ALLOW_MODULE_PATHS = 1 << 3, } } type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute> >); -/// How to parse a path. There are four different kinds of paths, all of which +/// How to parse a path. There are three different kinds of paths, all of which /// are parsed somewhat differently. #[derive(Copy, Clone, PartialEq)] -pub enum PathParsingMode { - /// A path with no type parameters; e.g. `foo::bar::Baz` - NoTypesAllowed, - /// Same as `NoTypesAllowed`, but may end with `::{` or `::*`, which are left unparsed - ImportPrefix, +pub enum PathStyle { + /// A path with no type parameters, e.g. `foo::bar::Baz`, used in imports or visibilities. + Mod, /// A path with a lifetime and type parameters, with no double colons - /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>` - LifetimeAndTypesWithoutColons, + /// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`, used in types. + /// Paths using this style can be passed into macros expecting `path` nonterminals. + Type, /// A path with a lifetime and type parameters with double colons before - /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>` - LifetimeAndTypesWithColons, + /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`, used in expressions or patterns. + Expr, } /// How to parse a bound, whether to allow bound modifiers such as `?`. @@ -292,7 +288,7 @@ impl TokenType { match *self { TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)), TokenType::Operator => "an operator".to_string(), - TokenType::Keyword(kw) => format!("`{}`", kw.ident.name), + TokenType::Keyword(kw) => format!("`{}`", kw.name()), } } } @@ -562,7 +558,7 @@ impl<'a> Parser<'a> { } pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - self.check_used_keywords(); + self.check_strict_keywords(); self.check_reserved_keywords(); match self.token { token::Ident(i) => { @@ -661,8 +657,8 @@ impl<'a> Parser<'a> { } /// Signal an error if the given string is a strict keyword - pub fn check_used_keywords(&mut self) { - if self.token.is_used_keyword() { + pub fn check_strict_keywords(&mut self) { + if self.token.is_strict_keyword() { let token_str = self.this_token_to_string(); let span = self.span; self.span_err(span, @@ -1164,7 +1160,7 @@ impl<'a> Parser<'a> { } pub fn parse_ty_path(&mut self) -> PResult<'a, TyKind> { - Ok(TyKind::Path(None, self.parse_path(LifetimeAndTypesWithoutColons)?)) + Ok(TyKind::Path(None, self.parse_path(PathStyle::Type)?)) } /// parse a TyKind::BareFn type: @@ -1467,11 +1463,11 @@ impl<'a> Parser<'a> { } else if self.eat_lt() { let (qself, path) = - self.parse_qualified_path(LifetimeAndTypesWithoutColons)?; + self.parse_qualified_path(PathStyle::Type)?; TyKind::Path(Some(qself), path) } else if self.is_path_start() { - let path = self.parse_path(LifetimeAndTypesWithoutColons)?; + let path = self.parse_path(PathStyle::Type)?; if self.check(&token::Not) { // MACRO INVOCATION self.bump(); @@ -1556,7 +1552,7 @@ impl<'a> Parser<'a> { } else { debug!("parse_arg_general ident_to_pat"); let sp = self.last_span; - let spanned = Spanned { span: sp, node: special_idents::Invalid }; + let spanned = Spanned { span: sp, node: keywords::Invalid.ident() }; P(Pat { id: ast::DUMMY_NODE_ID, node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), @@ -1724,12 +1720,12 @@ impl<'a> Parser<'a> { /// /// `<T as U>::a` /// `<T as U>::F::a::<S>` - pub fn parse_qualified_path(&mut self, mode: PathParsingMode) + pub fn parse_qualified_path(&mut self, mode: PathStyle) -> PResult<'a, (QSelf, ast::Path)> { let span = self.last_span; let self_type = self.parse_ty_sum()?; let mut path = if self.eat_keyword(keywords::As) { - self.parse_path(LifetimeAndTypesWithoutColons)? + self.parse_path(PathStyle::Type)? } else { ast::Path { span: span, @@ -1747,14 +1743,14 @@ impl<'a> Parser<'a> { self.expect(&token::ModSep)?; let segments = match mode { - LifetimeAndTypesWithoutColons => { + PathStyle::Type => { self.parse_path_segments_without_colons()? } - LifetimeAndTypesWithColons => { + PathStyle::Expr => { self.parse_path_segments_with_colons()? } - NoTypesAllowed | ImportPrefix => { - self.parse_path_segments_without_types(mode == ImportPrefix)? + PathStyle::Mod => { + self.parse_path_segments_without_types()? } }; path.segments.extend(segments); @@ -1768,7 +1764,7 @@ impl<'a> Parser<'a> { /// mode. The `mode` parameter determines whether lifetimes, types, and/or /// bounds are permitted and whether `::` must precede type parameter /// groups. - pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<'a, ast::Path> { + pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> { // Check for a whole path... let found = match self.token { token::Interpolated(token::NtPath(_)) => Some(self.bump_and_get()), @@ -1785,14 +1781,14 @@ impl<'a> Parser<'a> { // identifier followed by an optional lifetime and a set of types. // A bound set is a set of type parameter bounds. let segments = match mode { - LifetimeAndTypesWithoutColons => { + PathStyle::Type => { self.parse_path_segments_without_colons()? } - LifetimeAndTypesWithColons => { + PathStyle::Expr => { self.parse_path_segments_with_colons()? } - NoTypesAllowed | ImportPrefix => { - self.parse_path_segments_without_types(mode == ImportPrefix)? + PathStyle::Mod => { + self.parse_path_segments_without_types()? } }; @@ -1907,10 +1903,9 @@ impl<'a> Parser<'a> { } } - /// Examples: /// - `a::b::c` - pub fn parse_path_segments_without_types(&mut self, import_prefix: bool) + pub fn parse_path_segments_without_types(&mut self) -> PResult<'a, Vec<ast::PathSegment>> { let mut segments = Vec::new(); loop { @@ -1924,7 +1919,7 @@ impl<'a> Parser<'a> { }); // If we do not see a `::` or see `::{`/`::*`, stop. - if !self.check(&token::ModSep) || import_prefix && self.is_import_coupler() { + if !self.check(&token::ModSep) || self.is_import_coupler() { return Ok(segments); } else { self.bump(); @@ -2256,7 +2251,7 @@ impl<'a> Parser<'a> { _ => { if self.eat_lt() { let (qself, path) = - self.parse_qualified_path(LifetimeAndTypesWithColons)?; + self.parse_qualified_path(PathStyle::Expr)?; hi = path.span.hi; return Ok(self.mk_expr(lo, hi, ExprKind::Path(Some(qself), path), attrs)); } @@ -2338,13 +2333,13 @@ impl<'a> Parser<'a> { } hi = self.last_span.hi; } else if self.token.is_keyword(keywords::Let) { - // Catch this syntax error here, instead of in `check_used_keywords`, so + // Catch this syntax error here, instead of in `check_strict_keywords`, so // that we can explicitly mention that let is not to be used as an expression let mut db = self.fatal("expected expression, found statement (`let`)"); db.note("variable declaration using `let` is a statement"); return Err(db); } else if self.is_path_start() { - let pth = self.parse_path(LifetimeAndTypesWithColons)?; + let pth = self.parse_path(PathStyle::Expr)?; // `!`, as an operator, is prefix, so we know this isn't that if self.check(&token::Not) { @@ -2621,7 +2616,7 @@ impl<'a> Parser<'a> { self.span_err(self.span, &format!("unexpected token: `{}`", actual)); let dot_pos = self.last_span.hi; - e = self.parse_dot_suffix(special_idents::Invalid, + e = self.parse_dot_suffix(keywords::Invalid.ident(), mk_sp(dot_pos, dot_pos), e, lo)?; } @@ -2698,9 +2693,8 @@ impl<'a> Parser<'a> { _ => unreachable!() }; // continue by trying to parse the `:ident` after `$name` - if self.token == token::Colon && self.look_ahead(1, |t| t.is_ident() && - !t.is_used_keyword() && - !t.is_reserved_keyword()) { + if self.token == token::Colon && + self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) { self.bump(); sp = mk_sp(sp.lo, self.span.hi); let nt_kind = self.parse_ident()?; @@ -3578,11 +3572,11 @@ impl<'a> Parser<'a> { let (qself, path) = if self.eat_lt() { // Parse a qualified path let (qself, path) = - self.parse_qualified_path(LifetimeAndTypesWithColons)?; + self.parse_qualified_path(PathStyle::Expr)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(LifetimeAndTypesWithColons)?) + (None, self.parse_path(PathStyle::Expr)?) }; let hi = self.last_span.hi; Ok(self.mk_expr(lo, hi, ExprKind::Path(qself, path), None)) @@ -3676,11 +3670,11 @@ impl<'a> Parser<'a> { let (qself, path) = if self.eat_lt() { // Parse a qualified path let (qself, path) = - self.parse_qualified_path(LifetimeAndTypesWithColons)?; + self.parse_qualified_path(PathStyle::Expr)?; (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(LifetimeAndTypesWithColons)?) + (None, self.parse_path(PathStyle::Expr)?) }; match self.token { token::DotDotDot => { @@ -3943,7 +3937,7 @@ impl<'a> Parser<'a> { self.bump(); let id = match self.token { - token::OpenDelim(_) => token::special_idents::Invalid, // no special identifier + token::OpenDelim(_) => keywords::Invalid.ident(), // no special identifier _ => self.parse_ident()?, }; @@ -3955,7 +3949,7 @@ impl<'a> Parser<'a> { _ => { // we only expect an ident if we didn't parse one // above. - let ident_str = if id.name == token::special_idents::Invalid.name { + let ident_str = if id.name == keywords::Invalid.name() { "identifier, " } else { "" @@ -3981,7 +3975,7 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == token::special_idents::Invalid.name { + if id.name == keywords::Invalid.name() { let mac = P(spanned(lo, hi, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })); let stmt = StmtKind::Mac(mac, style, attrs.into_thin_attrs()); spanned(lo, hi, stmt) @@ -4611,10 +4605,10 @@ impl<'a> Parser<'a> { fn expect_self_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(id) if id.name == keywords::SelfValue.ident.name => { + token::Ident(id) if id.name == keywords::SelfValue.name() => { self.bump(); // The hygiene context of `id` needs to be preserved here, - // so we can't just return `SelfValue.ident`. + // so we can't just return `SelfValue.ident()`. Ok(id) }, _ => { @@ -4699,7 +4693,7 @@ impl<'a> Parser<'a> { self.bump(); } // error case, making bogus self ident: - SelfKind::Value(keywords::SelfValue.ident) + SelfKind::Value(keywords::SelfValue.ident()) } token::Ident(..) => { if self.token.is_keyword(keywords::SelfValue) { @@ -4974,7 +4968,7 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi)? } - Ok((token::special_idents::Invalid, vec![], ast::ImplItemKind::Macro(m))) + Ok((keywords::Invalid.ident(), vec![], ast::ImplItemKind::Macro(m))) } else { let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; @@ -5069,7 +5063,7 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::CloseDelim(token::Brace))?; - Ok((special_idents::Invalid, + Ok((keywords::Invalid.ident(), ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None)) } else { if opt_trait.is_some() { @@ -5085,7 +5079,7 @@ impl<'a> Parser<'a> { impl_items.push(self.parse_impl_item()?); } - Ok((special_idents::Invalid, + Ok((keywords::Invalid.ident(), ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items), Some(attrs))) } @@ -5094,7 +5088,7 @@ impl<'a> Parser<'a> { /// Parse a::B<String,i32> fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> { Ok(ast::TraitRef { - path: self.parse_path(LifetimeAndTypesWithoutColons)?, + path: self.parse_path(PathStyle::Type)?, ref_id: ast::DUMMY_NODE_ID, }) } @@ -5254,8 +5248,7 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; Ok(Visibility::Crate(span)) } else { - let path = self.with_res(Restrictions::ALLOW_MODULE_PATHS, - |this| this.parse_path(NoTypesAllowed))?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::CloseDelim(token::Paren))?; Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }) } @@ -5263,7 +5256,7 @@ impl<'a> Parser<'a> { /// Parse defaultness: DEFAULT or nothing fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> { - if self.eat_contextual_keyword(special_idents::Default) { + if self.eat_contextual_keyword(keywords::Default.ident()) { Ok(Defaultness::Default) } else { Ok(Defaultness::Final) @@ -5591,7 +5584,7 @@ impl<'a> Parser<'a> { }; Ok(self.mk_item(lo, last_span.hi, - special_idents::Invalid, + keywords::Invalid.ident(), ItemKind::ForeignMod(m), visibility, attrs)) @@ -5730,7 +5723,7 @@ impl<'a> Parser<'a> { let last_span = self.last_span; let item = self.mk_item(lo, last_span.hi, - token::special_idents::Invalid, + keywords::Invalid.ident(), item_, visibility, attrs); @@ -6021,7 +6014,7 @@ impl<'a> Parser<'a> { let id = if self.token.is_ident() { self.parse_ident()? } else { - token::special_idents::Invalid // no special identifier + keywords::Invalid.ident() // no special identifier }; // eat a matched-delimiter token tree: let delim = self.expect_open_delim()?; @@ -6118,7 +6111,7 @@ impl<'a> Parser<'a> { let items = self.parse_path_list_items()?; Ok(P(spanned(lo, self.span.hi, ViewPathList(prefix, items)))) } else { - let prefix = self.parse_path(ImportPrefix)?; + let prefix = self.parse_path(PathStyle::Mod)?; if self.is_import_coupler() { // `foo::bar::{a, b}` or `foo::bar::*` self.bump(); |
