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 | |
| 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')
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 1 |
3 files changed, 18 insertions, 4 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e5ef9393e7b..08eec0f9117 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -450,6 +450,9 @@ declare_features! ( // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895)), + + // `extern` in paths + (active, extern_in_paths, "1.23.0", Some(44660)), ); declare_features! ( @@ -1790,6 +1793,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if segment.identifier.name == keywords::Crate.name() { gate_feature_post!(&self, crate_in_paths, segment.span, "`crate` in paths is experimental"); + } else if segment.identifier.name == keywords::Extern.name() { + gate_feature_post!(&self, extern_in_paths, segment.span, + "`extern` in paths is experimental"); } } 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, |
