From ae4e1a190be74024997551d2fe8c183866fc1cc5 Mon Sep 17 00:00:00 2001
From: Huon Wilson <dbau.pp+github@gmail.com>
Date: Sun, 25 Jan 2015 10:28:58 +1100
Subject: [PATCH] Tell the compiler to tell us that `deriving` is dead.

I'm beginning to suspect it's impossible to avoid accidentally writing
`#[deriving]` at least once in every program, and it results in
non-intuitive error messages: "Foo doesn't have any method in scope
`clone`" despite there being a `#[deriv...(Clone)]` attribute!

Also, lots of documentation around the internet uses `#[deriving]` so
providing this guidance is very helpful (lots of people ask in #rust
about this error).

Fixes #21166.
---
 src/libsyntax/ext/base.rs                       |  2 ++
 src/libsyntax/ext/deriving/mod.rs               |  8 ++++++++
 src/test/compile-fail/deriving-is-deprecated.rs | 15 +++++++++++++++
 3 files changed, 25 insertions(+)
 create mode 100644 src/test/compile-fail/deriving-is-deprecated.rs

diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 9128bc05f6f..ef8010927dc 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -467,6 +467,8 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
                                     ext::log_syntax::expand_syntax_ext));
     syntax_expanders.insert(intern("derive"),
                             Decorator(box ext::deriving::expand_meta_derive));
+    syntax_expanders.insert(intern("deriving"),
+                            Decorator(box ext::deriving::expand_deprecated_deriving));
 
     if ecfg.enable_quotes {
         // Quasi-quoting expanders
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index e52a2b513ce..ddec517a78e 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -40,6 +40,14 @@ pub mod totalord;
 
 pub mod generic;
 
+pub fn expand_deprecated_deriving(cx: &mut ExtCtxt,
+                                  span: Span,
+                                  _: &MetaItem,
+                                  _: &Item,
+                                  _: Box<FnMut(P<Item>)>) {
+    cx.span_err(span, "`deriving` has been renamed to `derive`");
+}
+
 pub fn expand_meta_derive(cx: &mut ExtCtxt,
                           _span: Span,
                           mitem: &MetaItem,
diff --git a/src/test/compile-fail/deriving-is-deprecated.rs b/src/test/compile-fail/deriving-is-deprecated.rs
new file mode 100644
index 00000000000..060e178eef2
--- /dev/null
+++ b/src/test/compile-fail/deriving-is-deprecated.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+#[deriving(Clone)] //~ ERROR `deriving` has been renamed to `derive`
+struct Foo;
+
+fn main() {}