@@ -45,7 +45,7 @@ use syntax::symbol::{kw, sym};
45
45
use syntax:: source_map:: Spanned ;
46
46
use syntax:: visit:: { self , Visitor } ;
47
47
use syntax_expand:: base:: SyntaxExtension ;
48
- use syntax_pos:: hygiene:: { MacroKind , ExpnId , Transparency , SyntaxContext } ;
48
+ use syntax_pos:: hygiene:: { MacroKind , ExpnId , ExpnKind , Transparency , SyntaxContext } ;
49
49
use syntax_pos:: { Span , DUMMY_SP } ;
50
50
use errors:: { Applicability , DiagnosticBuilder } ;
51
51
@@ -97,6 +97,7 @@ impl Determinacy {
97
97
/// but not for late resolution yet.
98
98
#[ derive( Clone , Copy ) ]
99
99
enum Scope < ' a > {
100
+ DeriveHelpers ( ExpnId ) ,
100
101
DeriveHelpersCompat ,
101
102
MacroRules ( LegacyScope < ' a > ) ,
102
103
CrateRoot ,
@@ -942,6 +943,8 @@ pub struct Resolver<'a> {
942
943
/// Legacy scopes *produced* by expanding the macro invocations,
943
944
/// include all the `macro_rules` items and other invocations generated by them.
944
945
output_legacy_scopes : FxHashMap < ExpnId , LegacyScope < ' a > > ,
946
+ /// Helper attributes that are in scope for the given expansion.
947
+ helper_attrs : FxHashMap < ExpnId , Vec < Ident > > ,
945
948
946
949
/// Avoid duplicated errors for "name already defined".
947
950
name_already_seen : FxHashMap < Name , Span > ,
@@ -1219,6 +1222,7 @@ impl<'a> Resolver<'a> {
1219
1222
non_macro_attrs : [ non_macro_attr ( false ) , non_macro_attr ( true ) ] ,
1220
1223
invocation_parent_scopes,
1221
1224
output_legacy_scopes : Default :: default ( ) ,
1225
+ helper_attrs : Default :: default ( ) ,
1222
1226
macro_defs,
1223
1227
local_macro_def_scopes : FxHashMap :: default ( ) ,
1224
1228
name_already_seen : FxHashMap :: default ( ) ,
@@ -1467,23 +1471,26 @@ impl<'a> Resolver<'a> {
1467
1471
// in prelude, not sure where exactly (creates ambiguities with any other prelude names).
1468
1472
1469
1473
let rust_2015 = ident. span . rust_2015 ( ) ;
1470
- let ( ns, is_absolute_path) = match scope_set {
1471
- ScopeSet :: All ( ns, _) => ( ns, false ) ,
1472
- ScopeSet :: AbsolutePath ( ns) => ( ns, true ) ,
1473
- ScopeSet :: Macro ( _ ) => ( MacroNS , false ) ,
1474
+ let ( ns, macro_kind , is_absolute_path) = match scope_set {
1475
+ ScopeSet :: All ( ns, _) => ( ns, None , false ) ,
1476
+ ScopeSet :: AbsolutePath ( ns) => ( ns, None , true ) ,
1477
+ ScopeSet :: Macro ( macro_kind ) => ( MacroNS , Some ( macro_kind ) , false ) ,
1474
1478
} ;
1475
1479
// Jump out of trait or enum modules, they do not act as scopes.
1476
1480
let module = parent_scope. module . nearest_item_scope ( ) ;
1477
1481
let mut scope = match ns {
1478
1482
_ if is_absolute_path => Scope :: CrateRoot ,
1479
1483
TypeNS | ValueNS => Scope :: Module ( module) ,
1480
- MacroNS => Scope :: DeriveHelpersCompat ,
1484
+ MacroNS => Scope :: DeriveHelpers ( parent_scope . expansion ) ,
1481
1485
} ;
1482
1486
let mut ident = ident. modern ( ) ;
1483
1487
let mut use_prelude = !module. no_implicit_prelude ;
1484
1488
1485
1489
loop {
1486
1490
let visit = match scope {
1491
+ // Derive helpers are not in scope when resolving derives in the same container.
1492
+ Scope :: DeriveHelpers ( expn_id) =>
1493
+ !( expn_id == parent_scope. expansion && macro_kind == Some ( MacroKind :: Derive ) ) ,
1487
1494
Scope :: DeriveHelpersCompat => true ,
1488
1495
Scope :: MacroRules ( ..) => true ,
1489
1496
Scope :: CrateRoot => true ,
@@ -1505,6 +1512,17 @@ impl<'a> Resolver<'a> {
1505
1512
}
1506
1513
1507
1514
scope = match scope {
1515
+ Scope :: DeriveHelpers ( expn_id) if expn_id != ExpnId :: root ( ) => {
1516
+ // Derive helpers are not visible to code generated by bang or derive macros.
1517
+ let expn_data = expn_id. expn_data ( ) ;
1518
+ match expn_data. kind {
1519
+ ExpnKind :: Root |
1520
+ ExpnKind :: Macro ( MacroKind :: Bang , _) |
1521
+ ExpnKind :: Macro ( MacroKind :: Derive , _) => Scope :: DeriveHelpersCompat ,
1522
+ _ => Scope :: DeriveHelpers ( expn_data. parent ) ,
1523
+ }
1524
+ }
1525
+ Scope :: DeriveHelpers ( ..) => Scope :: DeriveHelpersCompat ,
1508
1526
Scope :: DeriveHelpersCompat =>
1509
1527
Scope :: MacroRules ( parent_scope. legacy ) ,
1510
1528
Scope :: MacroRules ( legacy_scope) => match legacy_scope {
0 commit comments