diff options
| author | bors <bors@rust-lang.org> | 2014-04-23 12:01:53 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-04-23 12:01:53 -0700 |
| commit | 6beb376b5c27c6b028092f227f865ba564fea17b (patch) | |
| tree | b52fa55b56bb4c1b21d1753c7d5c2402894d3c9b /src/libsyntax | |
| parent | b5dd3f05fe95168b5569d0f519636149479eb6ac (diff) | |
| parent | 823c7eee6a040862abb5a5309693030394200e62 (diff) | |
| download | rust-6beb376b5c27c6b028092f227f865ba564fea17b.tar.gz rust-6beb376b5c27c6b028092f227f865ba564fea17b.zip | |
auto merge of #13686 : alexcrichton/rust/issue-12224, r=nikomatsakis
This alters the borrow checker's requirements on invoking closures from
requiring an immutable borrow to requiring a unique immutable borrow. This means
that it is illegal to invoke a closure through a `&` pointer because there is no
guarantee that is not aliased. This does not mean that a closure is required to
be in a mutable location, but rather a location which can be proven to be
unique (often through a mutable pointer).
For example, the following code is unsound and is no longer allowed:
type Fn<'a> = ||:'a;
fn call(f: |Fn|) {
f(|| {
f(|| {})
});
}
fn main() {
call(|a| {
a();
});
}
There is no replacement for this pattern. For all closures which are stored in
structures, it was previously allowed to invoke the closure through `&self` but
it now requires invocation through `&mut self`.
The standard library has a good number of violations of this new rule, but the
fixes will be separated into multiple breaking change commits.
Closes #12224
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/deriving/clone.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/eq.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/ord.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totaleq.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totalord.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/default.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/hash.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/primitive.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/show.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/zero.rs | 8 |
14 files changed, 55 insertions, 19 deletions
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 367accb4b19..e0b493cd8d9 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -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) + }), } ) }; diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 975b8885de7..35b7e7c1a66 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -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) + }) } } ); diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 5605c0b6107..afe2d3dae6a 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -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) + }) } } ); diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index 33512b3df5e..d161f966850 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -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) + }) } ) }; diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index a584f8abe05..69c413890e9 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -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) + }), } ) }; diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 35a1eb0bb83..6d6cdc55d40 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -52,7 +52,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) + }), }) }; diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 94675f91e9d..633674eff5c 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -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) diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 806560f6826..acdef8c8645 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -123,7 +123,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) + }), }) }; diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 914451fb402..673745b41e8 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -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, @@ -509,8 +516,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, diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index d22027d203f..9e160b0e35d 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -49,7 +49,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) + }) } ) }; diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index 267a12fdff9..e42a3c67e34 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -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) + }), }) }; diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index e81aa55d10d..09c3abf42b8 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -43,7 +43,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) + }) } ) }; diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 067958e4bde..7098d0dd6ef 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -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) + }) } ) }; diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 10692bd7f93..0aeeabcaeab 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -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) - } + }) } ) }; |
