@@ -1766,11 +1766,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
1766
1766
1767
1767
fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) {
1768
1768
for segment in &path.segments {
1769
+ // Identifiers we are going to check could come from a legacy macro (e.g. `#[test]`).
1770
+ // For such macros identifiers must have empty context, because this context is
1771
+ // used during name resolution and produced names must be unhygienic for compatibility.
1772
+ // On the other hand, we need the actual non-empty context for feature gate checking
1773
+ // because it's hygienic even for legacy macros. As previously stated, such context
1774
+ // cannot be kept in identifiers, so it's kept in paths instead and we take it from
1775
+ // there while keeping location info from the ident span.
1776
+ let span = segment.ident.span.with_ctxt(path.span.ctxt());
1769
1777
if segment.ident.name == keywords::Crate.name() {
1770
- gate_feature_post!(&self, crate_in_paths, segment.ident. span,
1778
+ gate_feature_post!(&self, crate_in_paths, span,
1771
1779
"`crate` in paths is experimental");
1772
1780
} else if segment.ident.name == keywords::Extern.name() {
1773
- gate_feature_post!(&self, extern_in_paths, segment.ident. span,
1781
+ gate_feature_post!(&self, extern_in_paths, span,
1774
1782
"`extern` in paths is experimental");
1775
1783
}
1776
1784
}
0 commit comments