about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-03-25 18:51:32 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-04-06 11:52:16 +0300
commit145868427989655f286a3dda0cd46435bcdf42ac (patch)
tree3358cca353af66fe1cc840275485453b7a8e1f2d /src/libsyntax
parent3a30bad6de92fd00f24b8ba9547798cb1afa1ba3 (diff)
downloadrust-145868427989655f286a3dda0cd46435bcdf42ac.tar.gz
rust-145868427989655f286a3dda0cd46435bcdf42ac.zip
Fix feature gating for crate/extern in paths
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/feature_gate.rs12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 24bfb5d9088..e1f1d95b8ab 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1766,11 +1766,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
     fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) {
         for segment in &path.segments {
+            // Identifiers we are going to check could come from a legacy macro (e.g. `#[test]`).
+            // For such macros identifiers must have empty context, because this context is
+            // used during name resolution and produced names must be unhygienic for compatibility.
+            // On the other hand, we need the actual non-empty context for feature gate checking
+            // because it's hygienic even for legacy macros. As previously stated, such context
+            // cannot be kept in identifiers, so it's kept in paths instead and we take it from
+            // there while keeping location info from the ident span.
+            let span = segment.ident.span.with_ctxt(path.span.ctxt());
             if segment.ident.name == keywords::Crate.name() {
-                gate_feature_post!(&self, crate_in_paths, segment.ident.span,
+                gate_feature_post!(&self, crate_in_paths, span,
                                    "`crate` in paths is experimental");
             } else if segment.ident.name == keywords::Extern.name() {
-                gate_feature_post!(&self, extern_in_paths, segment.ident.span,
+                gate_feature_post!(&self, extern_in_paths, span,
                                    "`extern` in paths is experimental");
             }
         }