-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auto merge of #7142 : alexcrichton/rust/deriving-zero, r=pcwalton
This allows mass-initialization of large structs without having to specify all the fields. I'm a bit hesitant, but I wanted to get this out there. I don't really like using the `Zero` trait, because it doesn't really make sense for a type like `HashMap` to use `Zero` as the 'blank allocation' trait. In theory there'd be a new trait, but then that's adding cruft to the language which may not necessarily need to be there. I do think that this can be useful, but I only implemented `Zero` on the basic types where I thought it made sense, so it may not be all that usable yet. (opinions?)
- Loading branch information
Showing
9 changed files
with
201 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright 2012-2013 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. | ||
|
||
use core::prelude::*; | ||
|
||
use ast::{meta_item, item, expr}; | ||
use codemap::span; | ||
use ext::base::ExtCtxt; | ||
use ext::build::AstBuilder; | ||
use ext::deriving::generic::*; | ||
|
||
use core::vec; | ||
|
||
pub fn expand_deriving_zero(cx: @ExtCtxt, | ||
span: span, | ||
mitem: @meta_item, | ||
in_items: ~[@item]) | ||
-> ~[@item] { | ||
let trait_def = TraitDef { | ||
path: Path::new(~["std", "num", "Zero"]), | ||
additional_bounds: ~[], | ||
generics: LifetimeBounds::empty(), | ||
methods: ~[ | ||
MethodDef { | ||
name: "zero", | ||
generics: LifetimeBounds::empty(), | ||
explicit_self: None, | ||
args: ~[], | ||
ret_ty: Self, | ||
const_nonmatching: false, | ||
combine_substructure: zero_substructure | ||
}, | ||
MethodDef { | ||
name: "is_zero", | ||
generics: LifetimeBounds::empty(), | ||
explicit_self: borrowed_explicit_self(), | ||
args: ~[], | ||
ret_ty: Literal(Path::new(~["bool"])), | ||
const_nonmatching: false, | ||
combine_substructure: |cx, span, substr| { | ||
cs_and(|cx, span, _, _| cx.span_bug(span, | ||
"Non-matching enum \ | ||
variant in \ | ||
deriving(Zero)"), | ||
cx, span, substr) | ||
} | ||
} | ||
] | ||
}; | ||
trait_def.expand(cx, span, mitem, in_items) | ||
} | ||
|
||
fn zero_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { | ||
let zero_ident = ~[ | ||
cx.ident_of("std"), | ||
cx.ident_of("num"), | ||
cx.ident_of("Zero"), | ||
cx.ident_of("zero") | ||
]; | ||
let zero_call = || { | ||
cx.expr_call_global(span, copy zero_ident, ~[]) | ||
}; | ||
|
||
return match *substr.fields { | ||
StaticStruct(_, ref summary) => { | ||
match *summary { | ||
Left(count) => { | ||
if count == 0 { | ||
cx.expr_ident(span, substr.type_ident) | ||
} else { | ||
let exprs = vec::from_fn(count, |_| zero_call()); | ||
cx.expr_call_ident(span, substr.type_ident, exprs) | ||
} | ||
} | ||
Right(ref fields) => { | ||
let zero_fields = do fields.map |ident| { | ||
cx.field_imm(span, *ident, zero_call()) | ||
}; | ||
cx.expr_struct_ident(span, substr.type_ident, zero_fields) | ||
} | ||
} | ||
} | ||
StaticEnum(*) => { | ||
cx.span_fatal(span, "`Zero` cannot be derived for enums, \ | ||
only structs") | ||
} | ||
_ => cx.bug("Non-static method in `deriving(Zero)`") | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2012-2013 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. | ||
|
||
use std::util; | ||
use std::num::Zero; | ||
|
||
#[deriving(Zero)] | ||
struct A; | ||
#[deriving(Zero)] | ||
struct B(int); | ||
#[deriving(Zero)] | ||
struct C(int, int); | ||
#[deriving(Zero)] | ||
struct D { a: int } | ||
#[deriving(Zero)] | ||
struct E { a: int, b: int } | ||
|
||
#[deriving(Zero)] | ||
struct Lots { | ||
a: ~str, | ||
b: @str, | ||
c: Option<util::NonCopyable>, | ||
d: u8, | ||
e: char, | ||
f: float, | ||
g: (f32, char), | ||
h: ~[util::NonCopyable], | ||
i: @mut (int, int), | ||
} | ||
|
||
fn main() { | ||
assert!(Zero::zero::<Lots>().is_zero()); | ||
} |