From b079ebeb8da4198112831af05c88b48974268337 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 27 Jan 2014 15:25:37 +1100 Subject: [PATCH] syntax: improve the spans of some #[deriving] traits. This makes error messages about (e.g.) `#[deriving(Clone)] struct Foo { x: Type }` point at `x: Type` rather than `Clone` in the header (while still referring to the `#[deriving(Clone)]` in the expansion info). --- src/libsyntax/ext/deriving/clone.rs | 32 +++++++------- src/libsyntax/ext/deriving/decodable.rs | 53 ++++++++++++------------ src/libsyntax/ext/deriving/default.rs | 14 +++---- src/libsyntax/ext/deriving/encodable.rs | 44 ++++++++++---------- src/libsyntax/ext/deriving/generic.rs | 9 ++-- src/libsyntax/ext/deriving/iter_bytes.rs | 23 +++++----- src/libsyntax/ext/deriving/primitive.rs | 36 +++++++++------- src/libsyntax/ext/deriving/rand.rs | 52 +++++++++++------------ src/libsyntax/ext/deriving/zero.rs | 12 +++--- 9 files changed, 138 insertions(+), 137 deletions(-) diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index aa8dcc3981b9..567b89d3453f 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -74,13 +74,13 @@ pub fn expand_deriving_deep_clone(cx: &ExtCtxt, fn cs_clone( name: &str, - cx: &ExtCtxt, span: Span, + cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let clone_ident = substr.method_ident; let ctor_ident; let all_fields; - let subcall = |field| - cx.expr_method_call(span, field, clone_ident, ~[]); + let subcall = |field: &FieldInfo| + cx.expr_method_call(field.span, field.self_, clone_ident, ~[]); match *substr.fields { Struct(ref af) => { @@ -91,37 +91,37 @@ fn cs_clone( ctor_ident = variant.node.name; all_fields = af; }, - EnumNonMatching(..) => cx.span_bug(span, - format!("Non-matching enum variants in `deriving({})`", - name)), - StaticEnum(..) | StaticStruct(..) => cx.span_bug(span, - format!("Static method in `deriving({})`", - name)) + EnumNonMatching(..) => cx.span_bug(trait_span, + format!("Non-matching enum variants in `deriving({})`", + name)), + StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, + format!("Static method in `deriving({})`", + name)) } match *all_fields { [FieldInfo { name: None, .. }, ..] => { // enum-like - let subcalls = all_fields.map(|field| subcall(field.self_)); - cx.expr_call_ident(span, ctor_ident, subcalls) + let subcalls = all_fields.map(subcall); + cx.expr_call_ident(trait_span, ctor_ident, subcalls) }, _ => { // struct-like let fields = all_fields.map(|field| { let ident = match field.name { Some(i) => i, - None => cx.span_bug(span, + None => cx.span_bug(trait_span, format!("unnamed field in normal struct in `deriving({})`", - name)) + name)) }; - cx.field_imm(span, ident, subcall(field.self_)) + cx.field_imm(field.span, ident, subcall(field)) }); if fields.is_empty() { // no fields, so construct like `None` - cx.expr_ident(span, ctor_ident) + cx.expr_ident(trait_span, ctor_ident) } else { - cx.expr_struct_ident(span, ctor_ident, fields) + cx.expr_struct_ident(trait_span, ctor_ident, fields) } } } diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 9272152e8d57..a9268d85c915 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -51,7 +51,7 @@ pub fn expand_deriving_decodable(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn decodable_substructure(cx: &ExtCtxt, span: Span, +fn decodable_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let decoder = substr.nonself_args[0]; let recurse = ~[cx.ident_of("extra"), @@ -60,9 +60,9 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, cx.ident_of("decode")]; // throw an underscore in front to suppress unused variable warnings let blkarg = cx.ident_of("_d"); - let blkdecoder = cx.expr_ident(span, blkarg); - let calldecode = cx.expr_call_global(span, recurse, ~[blkdecoder]); - let lambdadecode = cx.lambda_expr_1(span, calldecode, blkarg); + let blkdecoder = cx.expr_ident(trait_span, blkarg); + let calldecode = cx.expr_call_global(trait_span, recurse, ~[blkdecoder]); + let lambdadecode = cx.lambda_expr_1(trait_span, calldecode, blkarg); return match *substr.fields { StaticStruct(_, ref summary) => { @@ -73,7 +73,7 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, let read_struct_field = cx.ident_of("read_struct_field"); let result = decode_static_fields(cx, - span, + trait_span, substr.type_ident, summary, |span, name, field| { @@ -82,10 +82,10 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, cx.expr_uint(span, field), lambdadecode]) }); - cx.expr_method_call(span, decoder, cx.ident_of("read_struct"), - ~[cx.expr_str(span, cx.str_of(substr.type_ident)), - cx.expr_uint(span, nfields), - cx.lambda_expr_1(span, result, blkarg)]) + cx.expr_method_call(trait_span, decoder, cx.ident_of("read_struct"), + ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)), + cx.expr_uint(trait_span, nfields), + cx.lambda_expr_1(trait_span, result, blkarg)]) } StaticEnum(_, ref fields) => { let variant = cx.ident_of("i"); @@ -94,12 +94,11 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, let mut variants = ~[]; let rvariant_arg = cx.ident_of("read_enum_variant_arg"); - for (i, f) in fields.iter().enumerate() { - let (name, parts) = match *f { (i, ref p) => (i, p) }; - variants.push(cx.expr_str(span, cx.str_of(name))); + for (i, &(name, v_span, ref parts)) in fields.iter().enumerate() { + variants.push(cx.expr_str(v_span, cx.str_of(name))); let decoded = decode_static_fields(cx, - span, + v_span, name, parts, |span, _, field| { @@ -108,22 +107,22 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, lambdadecode]) }); - arms.push(cx.arm(span, - ~[cx.pat_lit(span, cx.expr_uint(span, i))], + arms.push(cx.arm(v_span, + ~[cx.pat_lit(v_span, cx.expr_uint(v_span, i))], decoded)); } - arms.push(cx.arm_unreachable(span)); + arms.push(cx.arm_unreachable(trait_span)); - let result = cx.expr_match(span, cx.expr_ident(span, variant), arms); - let lambda = cx.lambda_expr(span, ~[blkarg, variant], result); - let variant_vec = cx.expr_vec(span, variants); - let result = cx.expr_method_call(span, blkdecoder, + let result = cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms); + let lambda = cx.lambda_expr(trait_span, ~[blkarg, variant], result); + let variant_vec = cx.expr_vec(trait_span, variants); + let result = cx.expr_method_call(trait_span, blkdecoder, cx.ident_of("read_enum_variant"), ~[variant_vec, lambda]); - cx.expr_method_call(span, decoder, cx.ident_of("read_enum"), - ~[cx.expr_str(span, cx.str_of(substr.type_ident)), - cx.lambda_expr_1(span, result, blkarg)]) + cx.expr_method_call(trait_span, decoder, cx.ident_of("read_enum"), + ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)), + cx.lambda_expr_1(trait_span, result, blkarg)]) } _ => cx.bug("expected StaticEnum or StaticStruct in deriving(Decodable)") }; @@ -133,7 +132,7 @@ fn decodable_substructure(cx: &ExtCtxt, span: Span, /// - `outer_pat_ident` is the name of this enum variant/struct /// - `getarg` should retrieve the `uint`-th field with name `@str`. fn decode_static_fields(cx: &ExtCtxt, - outer_span: Span, + trait_span: Span, outer_pat_ident: Ident, fields: &StaticFields, getarg: |Span, @str, uint| -> @Expr) @@ -141,13 +140,13 @@ fn decode_static_fields(cx: &ExtCtxt, match *fields { Unnamed(ref fields) => { if fields.is_empty() { - cx.expr_ident(outer_span, outer_pat_ident) + cx.expr_ident(trait_span, outer_pat_ident) } else { let fields = fields.iter().enumerate().map(|(i, &span)| { getarg(span, format!("_field{}", i).to_managed(), i) }).collect(); - cx.expr_call_ident(outer_span, outer_pat_ident, fields) + cx.expr_call_ident(trait_span, outer_pat_ident, fields) } } Named(ref fields) => { @@ -155,7 +154,7 @@ fn decode_static_fields(cx: &ExtCtxt, let fields = fields.iter().enumerate().map(|(i, &(name, span))| { cx.field_imm(span, name, getarg(span, cx.str_of(name), i)) }).collect(); - cx.expr_struct_ident(outer_span, outer_pat_ident, fields) + cx.expr_struct_ident(trait_span, outer_pat_ident, fields) } } } diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 088a221c965e..22f850d56090 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -41,7 +41,7 @@ pub fn expand_deriving_default(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn default_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn default_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let default_ident = ~[ cx.ident_of("std"), cx.ident_of("default"), @@ -55,25 +55,25 @@ fn default_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Exp match *summary { Unnamed(ref fields) => { if fields.is_empty() { - cx.expr_ident(span, substr.type_ident) + cx.expr_ident(trait_span, substr.type_ident) } else { let exprs = fields.map(|sp| default_call(*sp)); - cx.expr_call_ident(span, substr.type_ident, exprs) + cx.expr_call_ident(trait_span, substr.type_ident, exprs) } } Named(ref fields) => { let default_fields = fields.map(|&(ident, span)| { cx.field_imm(span, ident, default_call(span)) }); - cx.expr_struct_ident(span, substr.type_ident, default_fields) + cx.expr_struct_ident(trait_span, substr.type_ident, default_fields) } } } StaticEnum(..) => { - cx.span_err(span, "`Default` cannot be derived for enums, only structs"); + cx.span_err(trait_span, "`Default` cannot be derived for enums, only structs"); // let compilation continue - cx.expr_uint(span, 0) + cx.expr_uint(trait_span, 0) } - _ => cx.bug("Non-static method in `deriving(Default)`") + _ => cx.span_bug(trait_span, "Non-static method in `deriving(Default)`") }; } diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 285bf86916e3..9a8861f2e70e 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -113,24 +113,24 @@ pub fn expand_deriving_encodable(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn encodable_substructure(cx: &ExtCtxt, span: Span, +fn encodable_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let encoder = substr.nonself_args[0]; // throw an underscore in front to suppress unused variable warnings let blkarg = cx.ident_of("_e"); - let blkencoder = cx.expr_ident(span, blkarg); + let blkencoder = cx.expr_ident(trait_span, blkarg); let encode = cx.ident_of("encode"); return match *substr.fields { Struct(ref fields) => { let emit_struct_field = cx.ident_of("emit_struct_field"); let mut stmts = ~[]; - for (i, f) in fields.iter().enumerate() { - let name = match f.name { + for (i, &FieldInfo { name, self_, span, .. }) in fields.iter().enumerate() { + let name = match name { Some(id) => cx.str_of(id), None => format!("_field{}", i).to_managed() }; - let enc = cx.expr_method_call(span, f.self_, encode, ~[blkencoder]); + let enc = cx.expr_method_call(span, self_, encode, ~[blkencoder]); let lambda = cx.lambda_expr_1(span, enc, blkarg); let call = cx.expr_method_call(span, blkencoder, emit_struct_field, @@ -140,10 +140,10 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span, stmts.push(cx.stmt_expr(call)); } - let blk = cx.lambda_stmts_1(span, stmts, blkarg); - cx.expr_method_call(span, encoder, cx.ident_of("emit_struct"), - ~[cx.expr_str(span, cx.str_of(substr.type_ident)), - cx.expr_uint(span, fields.len()), + let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg); + cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_struct"), + ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)), + cx.expr_uint(trait_span, fields.len()), blk]) } @@ -152,12 +152,12 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span, // so we need to generate a unique local variable to take the // mutable loan out on, otherwise we get conflicts which don't // actually exist. - let me = cx.stmt_let(span, false, blkarg, encoder); - let encoder = cx.expr_ident(span, blkarg); + let me = cx.stmt_let(trait_span, false, blkarg, encoder); + let encoder = cx.expr_ident(trait_span, blkarg); let emit_variant_arg = cx.ident_of("emit_enum_variant_arg"); let mut stmts = ~[]; - for (i, f) in fields.iter().enumerate() { - let enc = cx.expr_method_call(span, f.self_, encode, ~[blkencoder]); + for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() { + let enc = cx.expr_method_call(span, self_, encode, ~[blkencoder]); let lambda = cx.lambda_expr_1(span, enc, blkarg); let call = cx.expr_method_call(span, blkencoder, emit_variant_arg, @@ -166,21 +166,21 @@ fn encodable_substructure(cx: &ExtCtxt, span: Span, stmts.push(cx.stmt_expr(call)); } - let blk = cx.lambda_stmts_1(span, stmts, blkarg); - let name = cx.expr_str(span, cx.str_of(variant.node.name)); - let call = cx.expr_method_call(span, blkencoder, + let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg); + let name = cx.expr_str(trait_span, cx.str_of(variant.node.name)); + let call = cx.expr_method_call(trait_span, blkencoder, cx.ident_of("emit_enum_variant"), ~[name, - cx.expr_uint(span, idx), - cx.expr_uint(span, fields.len()), + cx.expr_uint(trait_span, idx), + cx.expr_uint(trait_span, fields.len()), blk]); - let blk = cx.lambda_expr_1(span, call, blkarg); - let ret = cx.expr_method_call(span, encoder, + let blk = cx.lambda_expr_1(trait_span, call, blkarg); + let ret = cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_enum"), - ~[cx.expr_str(span, + ~[cx.expr_str(trait_span, cx.str_of(substr.type_ident)), blk]); - cx.expr_block(cx.block(span, ~[me], Some(ret))) + cx.expr_block(cx.block(trait_span, ~[me], Some(ret))) } _ => cx.bug("expected Struct or EnumMatching in deriving(Encodable)") diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 5845e684e243..1f778779fbd4 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -169,8 +169,9 @@ StaticStruct(, Named(~[(, )])) StaticStruct(, Unnamed(~[])) -StaticEnum(, ~[(, Unnamed(~[])), - (, Named(~[(, )]))]) +StaticEnum(, ~[(, , Unnamed(~[])), + (, , + Named(~[(, )]))]) ~~~ */ @@ -291,7 +292,7 @@ pub enum SubstructureFields<'a> { /// A static method where Self is a struct. StaticStruct(&'a ast::StructDef, StaticFields), /// A static method where Self is an enum. - StaticEnum(&'a ast::EnumDef, ~[(Ident, StaticFields)]) + StaticEnum(&'a ast::EnumDef, ~[(Ident, Span, StaticFields)]) } @@ -905,7 +906,7 @@ impl<'a> MethodDef<'a> { trait_.summarise_struct(struct_def) } }; - (ident, summary) + (ident, v.span, summary) }); self.call_substructure_method(trait_, type_ident, self_args, nonself_args, diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 2bf69e346749..d82e1ef18426 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -45,19 +45,20 @@ pub fn expand_deriving_iter_bytes(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn iter_bytes_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn iter_bytes_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let (lsb0, f)= match substr.nonself_args { [l, f] => (l, f), - _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`") + _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(IterBytes)`") }; // Build the "explicitly borrowed" stack closure, "|_buf| f(_buf)". let blk_arg = cx.ident_of("_buf"); let borrowed_f = - cx.lambda_expr_1(span, cx.expr_call(span, f, ~[cx.expr_ident(span, blk_arg)]), + cx.lambda_expr_1(trait_span, + cx.expr_call(trait_span, f, ~[cx.expr_ident(trait_span, blk_arg)]), blk_arg); let iter_bytes_ident = substr.method_ident; - let call_iterbytes = |thing_expr| { + let call_iterbytes = |span, thing_expr| { cx.expr_method_call(span, thing_expr, iter_bytes_ident, @@ -74,25 +75,25 @@ fn iter_bytes_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @ // iteration function. let discriminant = match variant.node.disr_expr { Some(d)=> d, - None => cx.expr_uint(span, index) + None => cx.expr_uint(trait_span, index) }; - exprs.push(call_iterbytes(discriminant)); + exprs.push(call_iterbytes(trait_span, discriminant)); fields = fs; } - _ => cx.span_bug(span, "Impossible substructure in `deriving(IterBytes)`") + _ => cx.span_bug(trait_span, "Impossible substructure in `deriving(IterBytes)`") } - for &FieldInfo { self_, .. } in fields.iter() { - exprs.push(call_iterbytes(self_)); + for &FieldInfo { self_, span, .. } in fields.iter() { + exprs.push(call_iterbytes(span, self_)); } if exprs.len() == 0 { - cx.span_bug(span, "#[deriving(IterBytes)] needs at least one field"); + cx.span_bug(trait_span, "#[deriving(IterBytes)] needs at least one field"); } exprs.slice(1, exprs.len()).iter().fold(exprs[0], |prev, me| { - cx.expr_binary(span, BiAnd, prev, *me) + cx.expr_binary(trait_span, BiAnd, prev, *me) }) } diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index f621ad854aa2..a4e606f53c0c 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -64,21 +64,22 @@ pub fn expand_deriving_from_primitive(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn cs_from(name: &str, cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let n = match substr.nonself_args { [n] => n, - _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(FromPrimitive)`") + _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(FromPrimitive)`") }; match *substr.fields { StaticStruct(..) => { - cx.span_err(span, "`FromPrimitive` cannot be derived for structs"); - return cx.expr_fail(span, @""); + cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs"); + return cx.expr_fail(trait_span, @""); } StaticEnum(enum_def, _) => { if enum_def.variants.is_empty() { - cx.span_err(span, "`FromPrimitive` cannot be derived for enums with no variants"); - return cx.expr_fail(span, @""); + cx.span_err(trait_span, + "`FromPrimitive` cannot be derived for enums with no variants"); + return cx.expr_fail(trait_span, @""); } let mut arms = ~[]; @@ -87,10 +88,12 @@ fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr match variant.node.kind { ast::TupleVariantKind(ref args) => { if !args.is_empty() { - cx.span_err(span, "`FromPrimitive` cannot be derived for \ - enum variants with arguments"); - return cx.expr_fail(span, @""); + cx.span_err(trait_span, + "`FromPrimitive` cannot be derived for \ + enum variants with arguments"); + return cx.expr_fail(trait_span, @""); } + let span = variant.span; // expr for `$n == $variant as $name` let variant = cx.expr_ident(span, variant.node.name); @@ -111,23 +114,24 @@ fn cs_from(name: &str, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr arms.push(arm); } ast::StructVariantKind(_) => { - cx.span_err(span, "`FromPrimitive` cannot be derived for enums \ - with struct variants"); - return cx.expr_fail(span, @""); + cx.span_err(trait_span, + "`FromPrimitive` cannot be derived for enums \ + with struct variants"); + return cx.expr_fail(trait_span, @""); } } } // arm for `_ => None` let arm = ast::Arm { - pats: ~[cx.pat_wild(span)], + pats: ~[cx.pat_wild(trait_span)], guard: None, - body: cx.block_expr(cx.expr_none(span)), + body: cx.block_expr(cx.expr_none(trait_span)), }; arms.push(arm); - cx.expr_match(span, n, arms) + cx.expr_match(trait_span, n, arms) } - _ => cx.bug("expected StaticEnum in deriving(FromPrimitive)") + _ => cx.span_bug(trait_span, "expected StaticEnum in deriving(FromPrimitive)") } } diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 29023dea6211..a22822c2ddcc 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -50,7 +50,7 @@ pub fn expand_deriving_rand(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let rng = match substr.nonself_args { [rng] => ~[ rng ], _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") @@ -69,18 +69,18 @@ fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { return match *substr.fields { StaticStruct(_, ref summary) => { - rand_thing(cx, span, substr.type_ident, summary, rand_call) + rand_thing(cx, trait_span, substr.type_ident, summary, rand_call) } StaticEnum(_, ref variants) => { if variants.is_empty() { - cx.span_err(span, "`Rand` cannot be derived for enums with no variants"); + cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants"); // let compilation continue - return cx.expr_uint(span, 0); + return cx.expr_uint(trait_span, 0); } - let variant_count = cx.expr_uint(span, variants.len()); + let variant_count = cx.expr_uint(trait_span, variants.len()); - let rand_name = cx.path_all(span, + let rand_name = cx.path_all(trait_span, true, rand_ident.clone(), opt_vec::Empty, @@ -88,52 +88,48 @@ fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { let rand_name = cx.expr_path(rand_name); // ::std::rand::Rand::rand(rng) - let rv_call = cx.expr_call(span, + let rv_call = cx.expr_call(trait_span, rand_name, ~[ rng[0] ]); // need to specify the uint-ness of the random number - let uint_ty = cx.ty_ident(span, cx.ident_of("uint")); + let uint_ty = cx.ty_ident(trait_span, cx.ident_of("uint")); let value_ident = cx.ident_of("__value"); - let let_statement = cx.stmt_let_typed(span, + let let_statement = cx.stmt_let_typed(trait_span, false, value_ident, uint_ty, rv_call); // rand() % variants.len() - let value_ref = cx.expr_ident(span, value_ident); - let rand_variant = cx.expr_binary(span, + let value_ref = cx.expr_ident(trait_span, value_ident); + let rand_variant = cx.expr_binary(trait_span, ast::BiRem, value_ref, variant_count); - let mut arms = variants.iter().enumerate().map(|(i, id_sum)| { - let i_expr = cx.expr_uint(span, i); - let pat = cx.pat_lit(span, i_expr); + let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| { + let i_expr = cx.expr_uint(v_span, i); + let pat = cx.pat_lit(v_span, i_expr); - match *id_sum { - (ident, ref summary) => { - cx.arm(span, - ~[ pat ], - rand_thing(cx, span, ident, summary, |sp| rand_call(sp))) - } - } + cx.arm(v_span, + ~[ pat ], + rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp))) }).collect::<~[ast::Arm]>(); // _ => {} at the end. Should never occur - arms.push(cx.arm_unreachable(span)); + arms.push(cx.arm_unreachable(trait_span)); - let match_expr = cx.expr_match(span, rand_variant, arms); + let match_expr = cx.expr_match(trait_span, rand_variant, arms); - let block = cx.block(span, ~[ let_statement ], Some(match_expr)); + let block = cx.block(trait_span, ~[ let_statement ], Some(match_expr)); cx.expr_block(block) } _ => cx.bug("Non-static method in `deriving(Rand)`") }; fn rand_thing(cx: &ExtCtxt, - span: Span, + trait_span: Span, ctor_ident: Ident, summary: &StaticFields, rand_call: |Span| -> @Expr) @@ -141,17 +137,17 @@ fn rand_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { match *summary { Unnamed(ref fields) => { if fields.is_empty() { - cx.expr_ident(span, ctor_ident) + cx.expr_ident(trait_span, ctor_ident) } else { let exprs = fields.map(|span| rand_call(*span)); - cx.expr_call_ident(span, ctor_ident, exprs) + cx.expr_call_ident(trait_span, ctor_ident, exprs) } } Named(ref fields) => { let rand_fields = fields.map(|&(ident, span)| { cx.field_imm(span, ident, rand_call(span)) }); - cx.expr_struct_ident(span, ctor_ident, rand_fields) + cx.expr_struct_ident(trait_span, ctor_ident, rand_fields) } } } diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 31020b4a5622..dd99e8216200 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -57,7 +57,7 @@ pub fn expand_deriving_zero(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn zero_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn zero_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let zero_ident = ~[ cx.ident_of("std"), cx.ident_of("num"), @@ -71,24 +71,24 @@ fn zero_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { match *summary { Unnamed(ref fields) => { if fields.is_empty() { - cx.expr_ident(span, substr.type_ident) + cx.expr_ident(trait_span, substr.type_ident) } else { let exprs = fields.map(|sp| zero_call(*sp)); - cx.expr_call_ident(span, substr.type_ident, exprs) + cx.expr_call_ident(trait_span, substr.type_ident, exprs) } } Named(ref fields) => { let zero_fields = fields.map(|&(ident, span)| { cx.field_imm(span, ident, zero_call(span)) }); - cx.expr_struct_ident(span, substr.type_ident, zero_fields) + cx.expr_struct_ident(trait_span, substr.type_ident, zero_fields) } } } StaticEnum(..) => { - cx.span_err(span, "`Zero` cannot be derived for enums, only structs"); + cx.span_err(trait_span, "`Zero` cannot be derived for enums, only structs"); // let compilation continue - cx.expr_uint(span, 0) + cx.expr_uint(trait_span, 0) } _ => cx.bug("Non-static method in `deriving(Zero)`") };