modify #[deriving(Eq)] to emit #[structural_match]
to careful use of the span from deriving, we can permit it in stable code if it derives from deriving (not-even-a-pun intended)
This commit is contained in:
parent
5bc2868060
commit
99c2a6b335
|
@ -109,6 +109,8 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
|
|||
// to bootstrap fix for #5723.
|
||||
("issue_5723_bootstrap", "1.0.0", None, Accepted),
|
||||
|
||||
("structural_match", "1.8.0", Some(31434), Active),
|
||||
|
||||
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
|
||||
("opt_out_copy", "1.0.0", None, Removed),
|
||||
|
||||
|
@ -304,6 +306,11 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
|
|||
("link_args", Normal, Ungated),
|
||||
("macro_escape", Normal, Ungated),
|
||||
|
||||
// RFC #1445.
|
||||
("structural_match", Whitelisted, Gated("structural_match",
|
||||
"the semantics of constant patterns is \
|
||||
not yet settled")),
|
||||
|
||||
// Not used any more, but we can't feature gate it
|
||||
("no_stack_check", Normal, Ungated),
|
||||
|
||||
|
@ -676,7 +683,7 @@ impl<'a> Context<'a> {
|
|||
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
|
||||
let has_feature = self.has_feature(feature);
|
||||
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
|
||||
if !has_feature {
|
||||
if !has_feature && !self.cm.span_allows_unstable(span) {
|
||||
emit_feature_err(self.span_handler, feature, span, GateIssue::Language, explain);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,10 @@ fn expand_derive(cx: &mut ExtCtxt,
|
|||
mitem: &MetaItem,
|
||||
annotatable: Annotatable)
|
||||
-> Annotatable {
|
||||
annotatable.map_item_or(|item| {
|
||||
debug!("expand_derive: span = {:?}", span);
|
||||
debug!("expand_derive: mitem = {:?}", mitem);
|
||||
debug!("expand_derive: annotatable input = {:?}", annotatable);
|
||||
let annot = annotatable.map_item_or(|item| {
|
||||
item.map(|mut item| {
|
||||
if mitem.value_str().is_some() {
|
||||
cx.span_err(mitem.span, "unexpected value in `derive`");
|
||||
|
@ -107,6 +110,45 @@ fn expand_derive(cx: &mut ExtCtxt,
|
|||
continue;
|
||||
}
|
||||
|
||||
// RFC #1445. `#[derive(Eq)]` adds a (trusted)
|
||||
// `#[structural_match]` attribute.
|
||||
if &tname[..] == "Eq" {
|
||||
// This span is **very** sensitive and crucial to
|
||||
// getting the stability behavior we want. What we
|
||||
// are doing is marking `#[structural_match]` with
|
||||
// the span of the `#[deriving(Eq)]` attribute
|
||||
// (the entire attribute, not just the `Eq` part),
|
||||
// but with the current backtrace. The current
|
||||
// backtrace will contain a topmost entry that IS
|
||||
// this `#[deriving(Eq)]` attribute and with the
|
||||
// "allow-unstable" flag set to true.
|
||||
//
|
||||
// Note that we do NOT use the span of the `Eq`
|
||||
// text itself. You might think this is
|
||||
// equivalent, because the `Eq` appears within the
|
||||
// `#[deriving(Eq)]` attribute, and hence we would
|
||||
// inherit the "allows unstable" from the
|
||||
// backtrace. But in fact this is not always the
|
||||
// case. The actual source text that led to
|
||||
// deriving can be `#[$attr]`, for example, where
|
||||
// `$attr == deriving(Eq)`. In that case, the
|
||||
// "#[structural_match]" would be considered to
|
||||
// originate not from the deriving call but from
|
||||
// text outside the deriving call, and hence would
|
||||
// be forbidden from using unstable
|
||||
// content.
|
||||
//
|
||||
// See tests src/run-pass/rfc1445 for
|
||||
// examples. --nmatsakis
|
||||
let span = Span { expn_id: cx.backtrace(), .. span };
|
||||
assert!(cx.parse_sess.codemap().span_allows_unstable(span));
|
||||
debug!("inserting structural_match with span {:?}", span);
|
||||
let structural_match = intern_and_get_ident("structural_match");
|
||||
item.attrs.push(cx.attribute(span,
|
||||
cx.meta_word(span,
|
||||
structural_match)));
|
||||
}
|
||||
|
||||
// #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar]
|
||||
item.attrs.push(cx.attribute(titem.span, cx.meta_word(titem.span,
|
||||
intern_and_get_ident(&format!("derive_{}", tname)))));
|
||||
|
@ -117,7 +159,9 @@ fn expand_derive(cx: &mut ExtCtxt,
|
|||
}, |a| {
|
||||
cx.span_err(span, "`derive` can only be applied to items");
|
||||
a
|
||||
})
|
||||
});
|
||||
debug!("expand_derive: annotatable output = {:?}", annot);
|
||||
annot
|
||||
}
|
||||
|
||||
macro_rules! derive_traits {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#![feature(str_char)]
|
||||
|
||||
extern crate fmt_macros;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use]
|
||||
extern crate syntax;
|
||||
|
||||
|
|
Loading…
Reference in New Issue