diff options
| author | bors <bors@rust-lang.org> | 2016-03-26 01:13:31 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-03-26 01:13:31 -0700 |
| commit | d322f990b04e3b598afd6a47c09a0277f73031aa (patch) | |
| tree | aa4db313962bedd35e235ad3913408133d0e0848 /src/libsyntax_ext | |
| parent | 8d2d2be6c61c17da8027a72da91f87a0e2487f74 (diff) | |
| parent | 6c10866b0241b6f37f1f5e30eaed3ac316b63ea4 (diff) | |
| download | rust-d322f990b04e3b598afd6a47c09a0277f73031aa.tar.gz rust-d322f990b04e3b598afd6a47c09a0277f73031aa.zip | |
Auto merge of #32496 - Manishearth:rollup, r=Manishearth
Rollup of 11 pull requests - Successful merges: #32131, #32199, #32257, #32325, #32435, #32447, #32448, #32456, #32469, #32476, #32482 - Failed merges: #32240
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/mod.rs | 57 | ||||
| -rw-r--r-- | src/libsyntax_ext/lib.rs | 1 |
3 files changed, 57 insertions, 2 deletions
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index e137815cd32..671f3e4a7e3 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -10,4 +10,5 @@ crate-type = ["dylib"] [dependencies] fmt_macros = { path = "../libfmt_macros" } +log = { path = "../liblog" } syntax = { path = "../libsyntax" } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 75de5c56ea1..1774167e830 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -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`"); @@ -89,6 +92,9 @@ fn expand_derive(cx: &mut ExtCtxt, cx.span_warn(mitem.span, "empty trait list in `derive`"); } + let mut found_partial_eq = false; + let mut found_eq = false; + for titem in traits.iter().rev() { let tname = match titem.node { MetaItemKind::Word(ref tname) => tname, @@ -107,17 +113,64 @@ fn expand_derive(cx: &mut ExtCtxt, continue; } + if &tname[..] == "Eq" { + found_eq = true; + } else if &tname[..] == "PartialEq" { + found_partial_eq = true; + } + // #[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))))); } + // RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted) + // `#[structural_match]` attribute. + if found_partial_eq && found_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(...)]` attribute (the + // entire attribute, not just the `PartialEq` or `Eq` + // part), but with the current backtrace. The current + // backtrace will contain a topmost entry that IS this + // `#[deriving(...)]` 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))); + } + item }) }, |a| { cx.span_err(span, "`derive` can only be applied to items"); a - }) + }); + debug!("expand_derive: annotatable output = {:?}", annot); + annot } macro_rules! derive_traits { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 97531d4279d..f214ecdc336 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -24,6 +24,7 @@ #![feature(str_char)] extern crate fmt_macros; +#[macro_use] extern crate log; #[macro_use] extern crate syntax; |
