diff options
| author | bors <bors@rust-lang.org> | 2018-01-07 00:51:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-01-07 00:51:42 +0000 |
| commit | a704583d43dda19c2542845d8efd61bd4e1d82f1 (patch) | |
| tree | 7f934100750e46fe9662f968413c5a99afd181a6 /src/libsyntax/parse | |
| parent | 6828cf90146c7fefc4ba4f16dffe75f763f2d910 (diff) | |
| parent | ef2b131144bc0d3d7814c9967e47a8d4e834caa5 (diff) | |
| download | rust-a704583d43dda19c2542845d8efd61bd4e1d82f1.tar.gz rust-a704583d43dda19c2542845d8efd61bd4e1d82f1.zip | |
Auto merge of #47156 - petrochenkov:extpath, r=nikomatsakis
Support `extern` in paths Implement the primary alternative to https://github.com/rust-lang/rust/pull/46613 + https://github.com/rust-lang/rust/pull/45771, achieving the same effect without requiring changes to other imports. Both need to be experimentally evaluated before making further progress. The PR also adds docs for all these related features into the unstable book. cc https://github.com/rust-lang/rust/issues/44660 r? @nikomatsakis
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 1 |
2 files changed, 12 insertions, 4 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 812e3c4967a..e7c648d5e37 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1387,7 +1387,7 @@ impl<'a> Parser<'a> { None }; (ident, TraitItemKind::Const(ty, default), ast::Generics::default()) - } else if self.token.is_path_start() { + } else if self.token.is_path_start() && !self.is_extern_non_path() { // trait item macro. // code copied from parse_macro_use_or_failure... abstraction! let prev_span = self.prev_span; @@ -4037,6 +4037,10 @@ impl<'a> Parser<'a> { self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep) } + fn is_extern_non_path(&self) -> bool { + self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep) + } + fn eat_auto_trait(&mut self) -> bool { if self.token.is_keyword(keywords::Auto) && self.look_ahead(1, |t| t.is_keyword(keywords::Trait)) @@ -4152,10 +4156,12 @@ impl<'a> Parser<'a> { // like a path (1 token), but it fact not a path. // `union::b::c` - path, `union U { ... }` - not a path. // `crate::b::c` - path, `crate struct S;` - not a path. + // `extern::b::c` - path, `extern crate c;` - not a path. } else if self.token.is_path_start() && !self.token.is_qpath_start() && !self.is_union_item() && - !self.is_crate_vis() { + !self.is_crate_vis() && + !self.is_extern_non_path() { let pth = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { @@ -5236,7 +5242,7 @@ impl<'a> Parser<'a> { -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics, ast::ImplItemKind)> { // code copied from parse_macro_use_or_failure... abstraction! - if self.token.is_path_start() { + if self.token.is_path_start() && !self.is_extern_non_path() { // Method macro. let prev_span = self.prev_span; @@ -6238,7 +6244,8 @@ impl<'a> Parser<'a> { return Ok(Some(item)); } - if self.eat_keyword(keywords::Extern) { + if self.check_keyword(keywords::Extern) && self.is_extern_non_path() { + self.bump(); // `extern` if self.eat_keyword(keywords::Crate) { return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?)); } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index bd4f7f9853d..2be93c07d5a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -359,6 +359,7 @@ impl Token { Some(id) => id.name == keywords::Super.name() || id.name == keywords::SelfValue.name() || id.name == keywords::SelfType.name() || + id.name == keywords::Extern.name() || id.name == keywords::Crate.name() || id.name == keywords::DollarCrate.name(), None => false, |
