diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2013-11-07 18:49:01 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2013-11-08 20:57:34 +1100 |
| commit | 812ea9e169d6edcc138e334e7e2b2cb5f7ba66b3 (patch) | |
| tree | bc573c50474ccf53fc5dfbb21c8217beee36d604 /src/libsyntax/ext/deriving/default.rs | |
| parent | 57d1ed819b9e32a8e915ced9b5e130c299a46bca (diff) | |
| download | rust-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.rs | 16 |
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) } |
