@@ -16,7 +16,7 @@ use syntax::ext::base::{ExtCtxt, SyntaxEnv, Annotatable};
16
16
use syntax:: ext:: base:: { MultiDecorator , MultiItemDecorator , MultiModifier } ;
17
17
use syntax:: ext:: build:: AstBuilder ;
18
18
use syntax:: feature_gate;
19
- use syntax:: codemap:: Span ;
19
+ use syntax:: codemap:: { self , Span } ;
20
20
use syntax:: parse:: token:: { intern, intern_and_get_ident} ;
21
21
use syntax:: ptr:: P ;
22
22
@@ -96,36 +96,6 @@ fn expand_derive(cx: &mut ExtCtxt,
96
96
let mut found_partial_eq = false ;
97
97
let mut found_eq = false ;
98
98
99
- // This span is **very** sensitive and crucial to
100
- // getting the stability behavior we want. What we are
101
- // doing is marking the generated `#[derive_*]` with the
102
- // span of the `#[deriving(...)]` attribute (the
103
- // entire attribute, not just the `PartialEq` or `Eq`
104
- // part), but with the current backtrace. The current
105
- // backtrace will contain a topmost entry that IS this
106
- // `#[deriving(...)]` attribute and with the
107
- // "allow-unstable" flag set to true.
108
- //
109
- // Note that we do NOT use the span of the `Eq`
110
- // text itself. You might think this is
111
- // equivalent, because the `Eq` appears within the
112
- // `#[deriving(Eq)]` attribute, and hence we would
113
- // inherit the "allows unstable" from the
114
- // backtrace. But in fact this is not always the
115
- // case. The actual source text that led to
116
- // deriving can be `#[$attr]`, for example, where
117
- // `$attr == deriving(Eq)`. In that case, the
118
- // "#[derive_*]" would be considered to
119
- // originate not from the deriving call but from
120
- // text outside the deriving call, and hence would
121
- // be forbidden from using unstable
122
- // content.
123
- //
124
- // See tests src/run-pass/rfc1445 for
125
- // examples. --nmatsakis
126
- let span = Span { expn_id : cx. backtrace ( ) , .. span } ;
127
- assert ! ( cx. parse_sess. codemap( ) . span_allows_unstable( span) ) ;
128
-
129
99
for titem in traits. iter ( ) . rev ( ) {
130
100
let tname = match titem. node {
131
101
MetaItemKind :: Word ( ref tname) => tname,
@@ -150,6 +120,17 @@ fn expand_derive(cx: &mut ExtCtxt,
150
120
found_partial_eq = true ;
151
121
}
152
122
123
+ let span = Span {
124
+ expn_id : cx. codemap ( ) . record_expansion ( codemap:: ExpnInfo {
125
+ call_site : titem. span ,
126
+ callee : codemap:: NameAndSpan {
127
+ format : codemap:: MacroAttribute ( intern ( & format ! ( "derive({})" , tname) ) ) ,
128
+ span : Some ( titem. span ) ,
129
+ allow_internal_unstable : true ,
130
+ } ,
131
+ } ) , ..titem. span
132
+ } ;
133
+
153
134
// #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar]
154
135
item. attrs . push ( cx. attribute ( span, cx. meta_word ( titem. span ,
155
136
intern_and_get_ident ( & format ! ( "derive_{}" , tname) ) ) ) ) ;
@@ -158,6 +139,35 @@ fn expand_derive(cx: &mut ExtCtxt,
158
139
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
159
140
// `#[structural_match]` attribute.
160
141
if found_partial_eq && found_eq {
142
+ // This span is **very** sensitive and crucial to
143
+ // getting the stability behavior we want. What we are
144
+ // doing is marking `#[structural_match]` with the
145
+ // span of the `#[deriving(...)]` attribute (the
146
+ // entire attribute, not just the `PartialEq` or `Eq`
147
+ // part), but with the current backtrace. The current
148
+ // backtrace will contain a topmost entry that IS this
149
+ // `#[deriving(...)]` attribute and with the
150
+ // "allow-unstable" flag set to true.
151
+ //
152
+ // Note that we do NOT use the span of the `Eq`
153
+ // text itself. You might think this is
154
+ // equivalent, because the `Eq` appears within the
155
+ // `#[deriving(Eq)]` attribute, and hence we would
156
+ // inherit the "allows unstable" from the
157
+ // backtrace. But in fact this is not always the
158
+ // case. The actual source text that led to
159
+ // deriving can be `#[$attr]`, for example, where
160
+ // `$attr == deriving(Eq)`. In that case, the
161
+ // "#[structural_match]" would be considered to
162
+ // originate not from the deriving call but from
163
+ // text outside the deriving call, and hence would
164
+ // be forbidden from using unstable
165
+ // content.
166
+ //
167
+ // See tests src/run-pass/rfc1445 for
168
+ // examples. --nmatsakis
169
+ let span = Span { expn_id : cx. backtrace ( ) , .. span } ;
170
+ assert ! ( cx. parse_sess. codemap( ) . span_allows_unstable( span) ) ;
161
171
debug ! ( "inserting structural_match with span {:?}" , span) ;
162
172
let structural_match = intern_and_get_ident ( "structural_match" ) ;
163
173
item. attrs . push ( cx. attribute ( span,
0 commit comments