about summary refs log tree commit diff
path: root/src/libsyntax/ext/deriving/default.rs
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2013-11-07 18:49:01 +1100
committerHuon Wilson <dbau.pp+github@gmail.com>2013-11-08 20:57:34 +1100
commit812ea9e169d6edcc138e334e7e2b2cb5f7ba66b3 (patch)
treebc573c50474ccf53fc5dfbb21c8217beee36d604 /src/libsyntax/ext/deriving/default.rs
parent57d1ed819b9e32a8e915ced9b5e130c299a46bca (diff)
downloadrust-812ea9e169d6edcc138e334e7e2b2cb5f7ba66b3.tar.gz
rust-812ea9e169d6edcc138e334e7e2b2cb5f7ba66b3.zip
syntax::ext: Make type errors in deriving point to the field itself.
This rearranges the deriving code so that #[deriving] a trait on a field
that doesn't implement that trait will point to the field in question,
e.g.

    struct NotEq; // doesn't implement Eq

    #[deriving(Eq)]
    struct Foo {
        ok: int,
        also_ok: ~str,
        bad: NotEq // error points here.
    }

Unfortunately, this means the error is disconnected from the `deriving`
itself but there's no current way to pass that information through to
rustc except via the spans, at the moment.

Fixes #7724.
Diffstat (limited to 'src/libsyntax/ext/deriving/default.rs')
-rw-r--r--src/libsyntax/ext/deriving/default.rs16
1 files changed, 7 insertions, 9 deletions
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index d8c78842808..6bc2b06806b 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -14,8 +14,6 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec;
-
 pub fn expand_deriving_default(cx: @ExtCtxt,
                             span: Span,
                             mitem: @MetaItem,
@@ -47,22 +45,22 @@ fn default_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Exp
         cx.ident_of("Default"),
         cx.ident_of("default")
     ];
-    let default_call = cx.expr_call_global(span, default_ident.clone(), ~[]);
+    let default_call = |span| cx.expr_call_global(span, default_ident.clone(), ~[]);
 
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
             match *summary {
-                Left(count) => {
-                    if count == 0 {
+                Unnamed(ref fields) => {
+                    if fields.is_empty() {
                         cx.expr_ident(span, substr.type_ident)
                     } else {
-                        let exprs = vec::from_elem(count, default_call);
+                        let exprs = fields.map(|sp| default_call(*sp));
                         cx.expr_call_ident(span, substr.type_ident, exprs)
                     }
                 }
-                Right(ref fields) => {
-                    let default_fields = do fields.map |ident| {
-                        cx.field_imm(span, *ident, default_call)
+                Named(ref fields) => {
+                    let default_fields = do fields.map |&(ident, span)| {
+                        cx.field_imm(span, ident, default_call(span))
                     };
                     cx.expr_struct_ident(span, substr.type_ident, default_fields)
                 }