Skip to content

Commit 074f4c2

Browse files
committed
Fix spans of generated #[derive_*] attributes
1 parent f89c0c2 commit 074f4c2

File tree

2 files changed

+44
-45
lines changed

2 files changed

+44
-45
lines changed

src/libsyntax_ext/deriving/generic/mod.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ use syntax::codemap::{self, respan, DUMMY_SP};
201201
use syntax::codemap::Span;
202202
use syntax::errors::Handler;
203203
use syntax::util::move_map::MoveMap;
204-
use syntax::parse::token::{intern, keywords, InternedString};
204+
use syntax::parse::token::{keywords, InternedString};
205205
use syntax::ptr::P;
206206

207207
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
@@ -1421,20 +1421,9 @@ impl<'a> MethodDef<'a> {
14211421
// general helper methods.
14221422
impl<'a> TraitDef<'a> {
14231423
fn set_expn_info(&self,
1424-
cx: &mut ExtCtxt,
1424+
_cx: &mut ExtCtxt,
14251425
mut to_set: Span) -> Span {
1426-
let trait_name = match self.path.path.last() {
1427-
None => cx.span_bug(self.span, "trait with empty path in generic `derive`"),
1428-
Some(name) => *name
1429-
};
1430-
to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
1431-
call_site: to_set,
1432-
callee: codemap::NameAndSpan {
1433-
format: codemap::MacroAttribute(intern(&format!("derive({})", trait_name))),
1434-
span: Some(self.span),
1435-
allow_internal_unstable: false,
1436-
}
1437-
});
1426+
to_set.expn_id = self.span.expn_id;
14381427
to_set
14391428
}
14401429

src/libsyntax_ext/deriving/mod.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use syntax::ext::base::{ExtCtxt, SyntaxEnv, Annotatable};
1616
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
1717
use syntax::ext::build::AstBuilder;
1818
use syntax::feature_gate;
19-
use syntax::codemap::Span;
19+
use syntax::codemap::{self, Span};
2020
use syntax::parse::token::{intern, intern_and_get_ident};
2121
use syntax::ptr::P;
2222

@@ -96,36 +96,6 @@ fn expand_derive(cx: &mut ExtCtxt,
9696
let mut found_partial_eq = false;
9797
let mut found_eq = false;
9898

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-
12999
for titem in traits.iter().rev() {
130100
let tname = match titem.node {
131101
MetaItemKind::Word(ref tname) => tname,
@@ -150,6 +120,17 @@ fn expand_derive(cx: &mut ExtCtxt,
150120
found_partial_eq = true;
151121
}
152122

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+
153134
// #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar]
154135
item.attrs.push(cx.attribute(span, cx.meta_word(titem.span,
155136
intern_and_get_ident(&format!("derive_{}", tname)))));
@@ -158,6 +139,35 @@ fn expand_derive(cx: &mut ExtCtxt,
158139
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
159140
// `#[structural_match]` attribute.
160141
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));
161171
debug!("inserting structural_match with span {:?}", span);
162172
let structural_match = intern_and_get_ident("structural_match");
163173
item.attrs.push(cx.attribute(span,

0 commit comments

Comments
 (0)