Fix other bugs with new closure borrowing

This fixes various issues throughout the standard distribution and tests.
This commit is contained in:
Alex Crichton 2014-04-21 23:25:18 -07:00
parent b4ecbe9340
commit 823c7eee6a
29 changed files with 147 additions and 100 deletions

View file

@ -672,7 +672,7 @@ impl ToStrRadix for BigUint {
s.push_str("0".repeat(l - ss.len()));
s.push_str(ss);
}
s.as_slice().trim_left_chars(&'0').to_owned()
s.as_slice().trim_left_chars('0').to_owned()
}
}
}

View file

@ -47,7 +47,7 @@ pub fn strip_items(krate: ast::Crate,
ctxt.fold_crate(krate)
}
fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
-> Option<&'r ast::ViewItem> {
if view_item_in_cfg(cx, view_item) {
Some(view_item)
@ -72,7 +72,7 @@ fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
}
}
fn filter_foreign_item(cx: &Context, item: @ast::ForeignItem)
fn filter_foreign_item(cx: &mut Context, item: @ast::ForeignItem)
-> Option<@ast::ForeignItem> {
if foreign_item_in_cfg(cx, item) {
Some(item)
@ -144,7 +144,7 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
fold::noop_fold_item_underscore(&item, cx)
}
fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> @ast::StructDef {
let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
(cx.in_cfg)(m.node.attrs.as_slice())
});
@ -156,7 +156,7 @@ fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
}
}
fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
fn retain_stmt(cx: &mut Context, stmt: @ast::Stmt) -> bool {
match stmt.node {
ast::StmtDecl(decl, _) => {
match decl.node {
@ -189,23 +189,23 @@ fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
})
}
fn item_in_cfg(cx: &Context, item: &ast::Item) -> bool {
fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
return (cx.in_cfg)(item.attrs.as_slice());
}
fn foreign_item_in_cfg(cx: &Context, item: &ast::ForeignItem) -> bool {
fn foreign_item_in_cfg(cx: &mut Context, item: &ast::ForeignItem) -> bool {
return (cx.in_cfg)(item.attrs.as_slice());
}
fn view_item_in_cfg(cx: &Context, item: &ast::ViewItem) -> bool {
fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
return (cx.in_cfg)(item.attrs.as_slice());
}
fn method_in_cfg(cx: &Context, meth: &ast::Method) -> bool {
fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
return (cx.in_cfg)(meth.attrs.as_slice());
}
fn trait_method_in_cfg(cx: &Context, meth: &ast::TraitMethod) -> bool {
fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
match *meth {
ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())

View file

@ -84,7 +84,7 @@ pub struct EncodeContext<'a> {
pub non_inlineable_statics: &'a RefCell<NodeSet>,
pub link_meta: &'a LinkMeta,
pub cstore: &'a cstore::CStore,
pub encode_inlined_item: EncodeInlinedItem<'a>,
pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
pub type_abbrevs: tyencode::abbrev_map,
}
@ -765,8 +765,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
if num_params > 0u ||
is_default_impl ||
should_inline(ast_method.attrs.as_slice()) {
(ecx.encode_inlined_item)(
ecx, ebml_w, IIMethodRef(local_def(parent_id), false, ast_method));
encode_inlined_item(ecx, ebml_w,
IIMethodRef(local_def(parent_id), false, ast_method));
} else {
encode_symbol(ecx, ebml_w, m.def_id.node);
}
@ -775,6 +775,14 @@ fn encode_info_for_method(ecx: &EncodeContext,
ebml_w.end_tag();
}
fn encode_inlined_item(ecx: &EncodeContext,
ebml_w: &mut Encoder,
ii: InlinedItemRef) {
let mut eii = ecx.encode_inlined_item.borrow_mut();
let eii: &mut EncodeInlinedItem = &mut *eii;
(*eii)(ecx, ebml_w, ii)
}
fn style_fn_family(s: FnStyle) -> char {
match s {
UnsafeFn => 'u',
@ -870,7 +878,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
let inlineable = !ecx.non_inlineable_statics.borrow().contains(&item.id);
if inlineable {
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
encode_inlined_item(ecx, ebml_w, IIItemRef(item));
}
encode_visibility(ebml_w, vis);
ebml_w.end_tag();
@ -886,7 +894,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_path(ebml_w, path);
encode_attributes(ebml_w, item.attrs.as_slice());
if tps_len > 0u || should_inline(item.attrs.as_slice()) {
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
encode_inlined_item(ecx, ebml_w, IIItemRef(item));
} else {
encode_symbol(ecx, ebml_w, item.id);
}
@ -944,7 +952,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
for v in (*enum_definition).variants.iter() {
encode_variant_id(ebml_w, local_def(v.node.id));
}
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
encode_inlined_item(ecx, ebml_w, IIItemRef(item));
encode_path(ebml_w, path);
// Encode inherent implementations for this enumeration.
@ -992,7 +1000,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
needs to know*/
encode_struct_fields(ebml_w, fields.as_slice(), def_id);
(ecx.encode_inlined_item)(ecx, ebml_w, IIItemRef(item));
encode_inlined_item(ecx, ebml_w, IIItemRef(item));
// Encode inherent implementations for this structure.
encode_inherent_implementations(ecx, ebml_w, def_id);
@ -1162,8 +1170,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_bounds_and_type(ebml_w, ecx, &tpt);
}
encode_method_sort(ebml_w, 'p');
(ecx.encode_inlined_item)(
ecx, ebml_w, IIMethodRef(def_id, true, m));
encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, m));
}
}
@ -1199,7 +1207,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
&lookup_item_type(ecx.tcx,local_def(nitem.id)));
encode_name(ebml_w, nitem.ident.name);
if abi == abi::RustIntrinsic {
(ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem));
encode_inlined_item(ecx, ebml_w, IIForeignRef(nitem));
} else {
encode_symbol(ecx, ebml_w, nitem.id);
}
@ -1531,12 +1539,12 @@ fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) {
}
}
struct MacroDefVisitor<'a, 'b> {
ecx: &'a EncodeContext<'a>,
ebml_w: &'a mut Encoder<'b>
struct MacroDefVisitor<'a, 'b, 'c> {
ecx: &'a EncodeContext<'b>,
ebml_w: &'a mut Encoder<'c>
}
impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
fn visit_item(&mut self, item: &Item, _: ()) {
match item.node {
ItemMac(..) => {
@ -1552,9 +1560,9 @@ impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
}
}
fn encode_macro_defs(ecx: &EncodeContext,
krate: &Crate,
ebml_w: &mut Encoder) {
fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
krate: &Crate,
ebml_w: &'a mut Encoder) {
ebml_w.start_tag(tag_exported_macros);
{
let mut visitor = MacroDefVisitor {
@ -1566,12 +1574,12 @@ fn encode_macro_defs(ecx: &EncodeContext,
ebml_w.end_tag();
}
struct ImplVisitor<'a,'b> {
ecx: &'a EncodeContext<'a>,
ebml_w: &'a mut Encoder<'b>,
struct ImplVisitor<'a,'b,'c> {
ecx: &'a EncodeContext<'b>,
ebml_w: &'a mut Encoder<'c>,
}
impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> {
impl<'a,'b,'c> Visitor<()> for ImplVisitor<'a,'b,'c> {
fn visit_item(&mut self, item: &Item, _: ()) {
match item.node {
ItemImpl(_, Some(ref trait_ref), _, _) => {
@ -1604,9 +1612,9 @@ impl<'a,'b> Visitor<()> for ImplVisitor<'a,'b> {
/// * Destructors (implementations of the Drop trait).
///
/// * Implementations of traits not defined in this crate.
fn encode_impls(ecx: &EncodeContext,
krate: &Crate,
ebml_w: &mut Encoder) {
fn encode_impls<'a>(ecx: &'a EncodeContext,
krate: &Crate,
ebml_w: &'a mut Encoder) {
ebml_w.start_tag(tag_impls);
{
@ -1731,7 +1739,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
non_inlineable_statics: non_inlineable_statics,
link_meta: link_meta,
cstore: cstore,
encode_inlined_item: encode_inlined_item,
encode_inlined_item: RefCell::new(encode_inlined_item),
type_abbrevs: RefCell::new(HashMap::new()),
};

View file

@ -92,9 +92,9 @@ impl<'a> FileSearch<'a> {
match fs::readdir(lib_search_path) {
Ok(files) => {
let mut rslt = FileDoesntMatch;
let is_rlib = |p: & &Path| {
fn is_rlib(p: & &Path) -> bool {
p.extension_str() == Some("rlib")
};
}
// Reading metadata out of rlibs is faster, and if we find both
// an rlib and a dylib we only read one of the files of
// metadata, so in the name of speed, bring all rlib files to

View file

@ -1164,7 +1164,7 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::Item) {
fn is_camel_case(ident: ast::Ident) -> bool {
let ident = token::get_ident(ident);
assert!(!ident.get().is_empty());
let ident = ident.get().trim_chars(&'_');
let ident = ident.get().trim_chars('_');
// start with a non-lowercase letter rather than non-uppercase
// ones (some scripts don't have a concept of upper/lowercase)

View file

@ -1104,34 +1104,34 @@ impl<'a> SanePrivacyVisitor<'a> {
/// control over anything so this forbids any mention of any visibility
fn check_all_inherited(&self, item: &ast::Item) {
let tcx = self.tcx;
let check_inherited = |sp: Span, vis: ast::Visibility| {
fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
if vis != ast::Inherited {
tcx.sess.span_err(sp, "visibility has no effect inside functions");
}
};
}
let check_struct = |def: &@ast::StructDef| {
for f in def.fields.iter() {
match f.node.kind {
ast::NamedField(_, p) => check_inherited(f.span, p),
ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
ast::UnnamedField(..) => {}
}
}
};
check_inherited(item.span, item.vis);
check_inherited(tcx, item.span, item.vis);
match item.node {
ast::ItemImpl(_, _, _, ref methods) => {
for m in methods.iter() {
check_inherited(m.span, m.vis);
check_inherited(tcx, m.span, m.vis);
}
}
ast::ItemForeignMod(ref fm) => {
for i in fm.items.iter() {
check_inherited(i.span, i.vis);
check_inherited(tcx, i.span, i.vis);
}
}
ast::ItemEnum(ref def, _) => {
for v in def.variants.iter() {
check_inherited(v.span, v.node.vis);
check_inherited(tcx, v.span, v.node.vis);
match v.node.kind {
ast::StructVariantKind(ref s) => check_struct(s),
@ -1146,7 +1146,8 @@ impl<'a> SanePrivacyVisitor<'a> {
for m in methods.iter() {
match *m {
ast::Required(..) => {}
ast::Provided(ref m) => check_inherited(m.span, m.vis),
ast::Provided(ref m) => check_inherited(tcx, m.span,
m.vis),
}
}
}

View file

@ -107,9 +107,9 @@ impl<'a> Parser<'a> {
}
// Return result of first successful parser
fn read_or<T>(&mut self, parsers: &[|&mut Parser| -> Option<T>])
fn read_or<T>(&mut self, parsers: &mut [|&mut Parser| -> Option<T>])
-> Option<T> {
for pf in parsers.iter() {
for pf in parsers.mut_iter() {
match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
Some(r) => return Some(r),
None => {}
@ -305,7 +305,7 @@ impl<'a> Parser<'a> {
fn read_ip_addr(&mut self) -> Option<IpAddr> {
let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
self.read_or([ipv4_addr, ipv6_addr])
self.read_or(&mut [ipv4_addr, ipv6_addr])
}
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
@ -318,7 +318,7 @@ impl<'a> Parser<'a> {
p.read_seq_3::<char, IpAddr, char>(open_br, ip_addr, clos_br)
.map(|t| match t { (_, ip, _) => ip })
};
p.read_or([ipv4_p, ipv6_p])
p.read_or(&mut [ipv4_p, ipv6_p])
};
let colon = |p: &mut Parser| p.read_given_char(':');
let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);

View file

@ -1241,7 +1241,7 @@ pub struct Map<'a, A, B, T> {
impl<'a, A, B, T> Map<'a, A, B, T> {
#[inline]
fn do_map(&self, elt: Option<A>) -> Option<B> {
fn do_map(&mut self, elt: Option<A>) -> Option<B> {
match elt {
Some(a) => Some((self.f)(a)),
_ => None
@ -1824,7 +1824,7 @@ pub struct Inspect<'a, A, T> {
impl<'a, A, T> Inspect<'a, A, T> {
#[inline]
fn do_inspect(&self, elt: Option<A>) -> Option<A> {
fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
match elt {
Some(ref a) => (self.f)(a),
None => ()
@ -2910,7 +2910,7 @@ mod tests {
let xs = [1, 2, 3, 4, 5];
// test .map and .inspect that don't implement Clone
let it = xs.iter().inspect(|_| {});
let mut it = xs.iter().inspect(|_| {});
assert_eq!(xs.len(), it.indexable());
for (i, elt) in xs.iter().enumerate() {
assert_eq!(Some(elt), it.idx(i));
@ -2922,7 +2922,7 @@ mod tests {
fn test_random_access_map() {
let xs = [1, 2, 3, 4, 5];
let it = xs.iter().map(|x| *x);
let mut it = xs.iter().map(|x| *x);
assert_eq!(xs.len(), it.indexable());
for (i, elt) in xs.iter().enumerate() {
assert_eq!(Some(*elt), it.idx(i));

View file

@ -873,9 +873,9 @@ mod tests {
assert_eq!(v, None);
// test that it does not take more elements than it needs
let functions = [|| Some(()), || None, || fail!()];
let mut functions = [|| Some(()), || None, || fail!()];
let v: Option<~[()]> = collect(functions.iter().map(|f| (*f)()));
let v: Option<~[()]> = collect(functions.mut_iter().map(|f| (*f)()));
assert_eq!(v, None);
}

View file

@ -695,9 +695,9 @@ mod tests {
assert_eq!(v, Err(2));
// test that it does not take more elements than it needs
let functions = [|| Ok(()), || Err(1), || fail!()];
let mut functions = [|| Ok(()), || Err(1), || fail!()];
let v: Result<~[()], int> = collect(functions.iter().map(|f| (*f)()));
let v: Result<~[()], int> = collect(functions.mut_iter().map(|f| (*f)()));
assert_eq!(v, Err(1));
}
@ -715,9 +715,9 @@ mod tests {
Err(2));
// test that it does not take more elements than it needs
let functions = [|| Ok(()), || Err(1), || fail!()];
let mut functions = [|| Ok(()), || Err(1), || fail!()];
assert_eq!(fold_(functions.iter()
assert_eq!(fold_(functions.mut_iter()
.map(|f| (*f)())),
Err(1));
}

View file

@ -212,8 +212,7 @@ impl<'a, T> Iterator<&'a [T]> for RevSplits<'a, T> {
return Some(self.v);
}
let pred = &mut self.pred;
match self.v.iter().rposition(|x| (*pred)(x)) {
match self.v.iter().rposition(|x| (self.pred)(x)) {
None => {
self.finished = true;
Some(self.v)
@ -2132,7 +2131,8 @@ impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
fn next(&mut self) -> Option<&'a mut [T]> {
if self.finished { return None; }
match self.v.iter().position(|x| (self.pred)(x)) {
let pred = &mut self.pred;
match self.v.iter().position(|x| (*pred)(x)) {
None => {
self.finished = true;
let tmp = mem::replace(&mut self.v, &mut []);
@ -2167,7 +2167,8 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
fn next_back(&mut self) -> Option<&'a mut [T]> {
if self.finished { return None; }
match self.v.iter().rposition(|x| (self.pred)(x)) {
let pred = &mut self.pred;
match self.v.iter().rposition(|x| (*pred)(x)) {
None => {
self.finished = true;
let tmp = mem::replace(&mut self.v, &mut []);
@ -3340,7 +3341,7 @@ mod tests {
assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
let it = v.chunks(2);
let mut it = v.chunks(2);
assert_eq!(it.indexable(), 3);
assert_eq!(it.idx(0).unwrap(), &[1,2]);
assert_eq!(it.idx(1).unwrap(), &[3,4]);

View file

@ -145,7 +145,7 @@ fn test_fail() {
#[test]
fn test_retval() {
let closure: || -> int = || 10;
let mut closure: || -> int = || 10;
let i = closure.finally(|| { });
assert_eq!(i, 10);
}
@ -154,6 +154,6 @@ fn test_retval() {
fn test_compact() {
fn do_some_fallible_work() {}
fn but_always_run_this_function() { }
do_some_fallible_work.finally(
but_always_run_this_function);
let mut f = do_some_fallible_work;
f.finally(but_always_run_this_function);
}

View file

@ -34,7 +34,9 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
ret_ty: Self,
inline: true,
const_nonmatching: false,
combine_substructure: |c, s, sub| cs_clone("Clone", c, s, sub)
combine_substructure: combine_substructure(|c, s, sub| {
cs_clone("Clone", c, s, sub)
}),
}
)
};

View file

@ -40,7 +40,9 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
ret_ty: Literal(Path::new(vec!("bool"))),
inline: true,
const_nonmatching: true,
combine_substructure: $f
combine_substructure: combine_substructure(|a, b, c| {
$f(a, b, c)
})
}
}
);

View file

@ -30,7 +30,9 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
ret_ty: Literal(Path::new(vec!("bool"))),
inline: true,
const_nonmatching: false,
combine_substructure: |cx, span, substr| cs_op($op, $equal, cx, span, substr)
combine_substructure: combine_substructure(|cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
})
}
}
);

View file

@ -48,7 +48,9 @@ pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
ret_ty: nil_ty(),
inline: true,
const_nonmatching: true,
combine_substructure: cs_total_eq_assert
combine_substructure: combine_substructure(|a, b, c| {
cs_total_eq_assert(a, b, c)
})
}
)
};

View file

@ -37,7 +37,9 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
inline: true,
const_nonmatching: false,
combine_substructure: cs_cmp
combine_substructure: combine_substructure(|a, b, c| {
cs_cmp(a, b, c)
}),
}
)
};

View file

@ -51,7 +51,9 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
vec!(~Self, ~Literal(Path::new_local("__E"))), true)),
inline: false,
const_nonmatching: true,
combine_substructure: decodable_substructure,
combine_substructure: combine_substructure(|a, b, c| {
decodable_substructure(a, b, c)
}),
})
};

View file

@ -34,7 +34,9 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
ret_ty: Self,
inline: true,
const_nonmatching: false,
combine_substructure: default_substructure
combine_substructure: combine_substructure(|a, b, c| {
default_substructure(a, b, c)
})
})
};
trait_def.expand(cx, mitem, item, push)

View file

@ -122,7 +122,9 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
true)),
inline: false,
const_nonmatching: true,
combine_substructure: encodable_substructure,
combine_substructure: combine_substructure(|a, b, c| {
encodable_substructure(a, b, c)
}),
})
};

View file

@ -177,6 +177,8 @@ StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span
*/
use std::cell::RefCell;
use ast;
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
use ast_util;
@ -234,7 +236,7 @@ pub struct MethodDef<'a> {
/// actual enum variants, i.e. can use _ => .. match.
pub const_nonmatching: bool,
pub combine_substructure: CombineSubstructureFunc<'a>,
pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
}
/// All the data about the data structure/method being derived upon.
@ -317,6 +319,11 @@ pub type EnumNonMatchFunc<'a> =
&[@Expr]|: 'a
-> @Expr;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-> RefCell<CombineSubstructureFunc<'a>> {
RefCell::new(f)
}
impl<'a> TraitDef<'a> {
pub fn expand(&self,
@ -505,8 +512,9 @@ impl<'a> MethodDef<'a> {
nonself_args: nonself_args,
fields: fields
};
(self.combine_substructure)(cx, trait_.span,
&substructure)
let mut f = self.combine_substructure.borrow_mut();
let f: &mut CombineSubstructureFunc = &mut *f;
(*f)(cx, trait_.span, &substructure)
}
fn get_ret_ty(&self,

View file

@ -48,7 +48,9 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
ret_ty: nil_ty(),
inline: true,
const_nonmatching: false,
combine_substructure: hash_substructure
combine_substructure: combine_substructure(|a, b, c| {
hash_substructure(a, b, c)
})
}
)
};

View file

@ -41,7 +41,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
// liable to cause code-bloat
inline: true,
const_nonmatching: false,
combine_substructure: |c, s, sub| cs_from("i64", c, s, sub),
combine_substructure: combine_substructure(|c, s, sub| {
cs_from("i64", c, s, sub)
}),
},
MethodDef {
name: "from_u64",
@ -56,7 +58,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
// liable to cause code-bloat
inline: true,
const_nonmatching: false,
combine_substructure: |c, s, sub| cs_from("u64", c, s, sub),
combine_substructure: combine_substructure(|c, s, sub| {
cs_from("u64", c, s, sub)
}),
})
};

View file

@ -42,7 +42,9 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
ret_ty: Self,
inline: false,
const_nonmatching: false,
combine_substructure: rand_substructure
combine_substructure: combine_substructure(|a, b, c| {
rand_substructure(a, b, c)
})
}
)
};

View file

@ -44,7 +44,9 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
inline: false,
const_nonmatching: false,
combine_substructure: show_substructure
combine_substructure: combine_substructure(|a, b, c| {
show_substructure(a, b, c)
})
}
)
};

View file

@ -34,7 +34,9 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
ret_ty: Self,
inline: true,
const_nonmatching: false,
combine_substructure: zero_substructure
combine_substructure: combine_substructure(|a, b, c| {
zero_substructure(a, b, c)
})
},
MethodDef {
name: "is_zero",
@ -44,13 +46,13 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
ret_ty: Literal(Path::new(vec!("bool"))),
inline: true,
const_nonmatching: false,
combine_substructure: |cx, span, substr| {
combine_substructure: combine_substructure(|cx, span, substr| {
cs_and(|cx, span, _, _| cx.span_bug(span,
"Non-matching enum \
variant in \
deriving(Zero)"),
cx, span, substr)
}
})
}
)
};

View file

@ -16,7 +16,7 @@ struct R<'a> {
// This struct is needed to create the
// otherwise infinite type of a fn that
// accepts itself as argument:
c: |&R, bool|: 'a
c: |&mut R, bool|: 'a
}
fn innocent_looking_victim() {
@ -28,6 +28,7 @@ fn innocent_looking_victim() {
match x {
Some(ref msg) => {
(f.c)(f, true);
//~^ ERROR: cannot borrow `*f` as mutable because
println!("{:?}", msg);
},
None => fail!("oops"),
@ -36,9 +37,9 @@ fn innocent_looking_victim() {
})
}
fn conspirator(f: |&R, bool|) {
let r = R {c: f};
f(&r, false) //~ ERROR use of moved value
fn conspirator(f: |&mut R, bool|) {
let mut r = R {c: f};
f(&mut r, false) //~ ERROR use of moved value
}
fn main() { innocent_looking_victim() }

View file

@ -18,13 +18,13 @@
fn f() { }
static bare_fns: &'static [fn()] = &[f, f];
struct S<'a>(||:'a);
static mut closures: &'static [S<'static>] = &[S(f), S(f)];
static mut closures: &'static mut [S<'static>] = &mut [S(f), S(f)];
pub fn main() {
unsafe {
for &bare_fn in bare_fns.iter() { bare_fn() }
for closure in closures.iter() {
let S(ref closure) = *closure;
for closure in closures.mut_iter() {
let S(ref mut closure) = *closure;
(*closure)()
}
}

View file

@ -8,23 +8,23 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub trait OpInt<'a> { fn call<'a>(&'a self, int, int) -> int; }
pub trait OpInt<'a> { fn call<'a>(&'a mut self, int, int) -> int; }
impl<'a> OpInt<'a> for |int, int|: 'a -> int {
fn call(&self, a:int, b:int) -> int {
fn call(&mut self, a:int, b:int) -> int {
(*self)(a, b)
}
}
fn squarei<'a>(x: int, op: &'a OpInt) -> int { op.call(x, x) }
fn squarei<'a>(x: int, op: &'a mut OpInt) -> int { op.call(x, x) }
fn muli(x:int, y:int) -> int { x * y }
pub fn main() {
let f = |x,y| muli(x,y);
let mut f = |x,y| muli(x,y);
{
let g = &f;
let h = g as &OpInt;
let g = &mut f;
let h = g as &mut OpInt;
squarei(3, h);
}
}