about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-26 01:13:31 -0700
committerbors <bors@rust-lang.org>2016-03-26 01:13:31 -0700
commitd322f990b04e3b598afd6a47c09a0277f73031aa (patch)
treeaa4db313962bedd35e235ad3913408133d0e0848 /src/libsyntax_ext
parent8d2d2be6c61c17da8027a72da91f87a0e2487f74 (diff)
parent6c10866b0241b6f37f1f5e30eaed3ac316b63ea4 (diff)
downloadrust-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.toml1
-rw-r--r--src/libsyntax_ext/deriving/mod.rs57
-rw-r--r--src/libsyntax_ext/lib.rs1
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;