diff options
| author | bors <bors@rust-lang.org> | 2014-11-25 15:48:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-11-25 15:48:05 +0000 |
| commit | 0e06f71747749e33ca590c334658bddde97a7e54 (patch) | |
| tree | 57a3fc9cca2562ea6595e95c54233915ce5b4c95 /src/test | |
| parent | 48ca6d1840818e4a8977d00ed62cf0e8e0e5d193 (diff) | |
| parent | 5fbe0cac7c568774082755ecc098caba98352a1e (diff) | |
| download | rust-0e06f71747749e33ca590c334658bddde97a7e54.tar.gz rust-0e06f71747749e33ca590c334658bddde97a7e54.zip | |
auto merge of #18234 : pnkfelix/rust/fsk-type-fragments-for-needsdrop-2, r=nikomatsakis
Code to fragment paths into pieces based on subparts being moved around, e.g. moving `x.1` out of a tuple `(A,B,C)` leaves behind the fragments `x.0: A` and `x.2: C`. Further discussion in borrowck/doc.rs. Includes differentiation between assigned_fragments and moved_fragments, support for all-but-one array fragments, and instrumentation to print out the moved/assigned/unmmoved/parents for each function, factored out into a separate submodule. These fragments can then be used by `trans` to inject stack-local dynamic drop flags. (They also can be hooked up with dataflow to reduce the expected number of injected flags.)
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/compile-fail/move-fragments-1.rs | 58 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-2.rs | 85 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-3.rs | 47 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-4.rs | 39 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-5.rs | 92 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-6.rs | 59 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-7.rs | 46 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-8.rs | 39 | ||||
| -rw-r--r-- | src/test/compile-fail/move-fragments-9.rs | 100 |
9 files changed, 565 insertions, 0 deletions
diff --git a/src/test/compile-fail/move-fragments-1.rs b/src/test/compile-fail/move-fragments-1.rs new file mode 100644 index 00000000000..ccf12cf79e1 --- /dev/null +++ b/src/test/compile-fail/move-fragments-1.rs @@ -0,0 +1,58 @@ +// Copyright 2014 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. + +#![feature(tuple_indexing)] + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// These are all fairly trivial cases: unused variables or direct +// drops of substructure. + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +#[rustc_move_fragments] +pub fn test_noop() { +} + +#[rustc_move_fragments] +pub fn test_take(_x: D) { + //~^ ERROR assigned_leaf_path: `$(local _x)` +} + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_take_struct(_p: Pair<D, D>) { + //~^ ERROR assigned_leaf_path: `$(local _p)` +} + +#[rustc_move_fragments] +pub fn test_drop_struct_part(p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).x` + //~| ERROR unmoved_fragment: `$(local p).y` + drop(p.x); +} + +#[rustc_move_fragments] +pub fn test_drop_tuple_part(p: (D, D)) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).#0` + //~| ERROR unmoved_fragment: `$(local p).#1` + drop(p.0); +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-2.rs b/src/test/compile-fail/move-fragments-2.rs new file mode 100644 index 00000000000..ceb1d5a0f09 --- /dev/null +++ b/src/test/compile-fail/move-fragments-2.rs @@ -0,0 +1,85 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// These are checking that enums are tracked; note that their output +// paths include "downcasts" of the path to a particular enum. + +use self::Lonely::{Zero, One, Two}; + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub enum Lonely<X,Y> { Zero, One(X), Two(X, Y) } + +#[rustc_move_fragments] +pub fn test_match_partial(p: Lonely<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR assigned_leaf_path: `($(local p) as Zero)` + match p { + Zero(..) => {} + _ => {} + } +} + +#[rustc_move_fragments] +pub fn test_match_full(p: Lonely<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR assigned_leaf_path: `($(local p) as Zero)` + //~| ERROR assigned_leaf_path: `($(local p) as One)` + //~| ERROR assigned_leaf_path: `($(local p) as Two)` + match p { + Zero(..) => {} + One(..) => {} + Two(..) => {} + } +} + +#[rustc_move_fragments] +pub fn test_match_bind_one(p: Lonely<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR assigned_leaf_path: `($(local p) as Zero)` + //~| ERROR parent_of_fragments: `($(local p) as One)` + //~| ERROR moved_leaf_path: `($(local p) as One).#0` + //~| ERROR assigned_leaf_path: `($(local p) as Two)` + //~| ERROR assigned_leaf_path: `$(local data)` + match p { + Zero(..) => {} + One(data) => {} + Two(..) => {} + } +} + +#[rustc_move_fragments] +pub fn test_match_bind_many(p: Lonely<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR assigned_leaf_path: `($(local p) as Zero)` + //~| ERROR parent_of_fragments: `($(local p) as One)` + //~| ERROR moved_leaf_path: `($(local p) as One).#0` + //~| ERROR assigned_leaf_path: `$(local data)` + //~| ERROR parent_of_fragments: `($(local p) as Two)` + //~| ERROR moved_leaf_path: `($(local p) as Two).#0` + //~| ERROR moved_leaf_path: `($(local p) as Two).#1` + //~| ERROR assigned_leaf_path: `$(local left)` + //~| ERROR assigned_leaf_path: `$(local right)` + match p { + Zero(..) => {} + One(data) => {} + Two(left, right) => {} + } +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-3.rs b/src/test/compile-fail/move-fragments-3.rs new file mode 100644 index 00000000000..4540b0c5a91 --- /dev/null +++ b/src/test/compile-fail/move-fragments-3.rs @@ -0,0 +1,47 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// This checks the handling of `_` within variants, especially when mixed +// with bindings. + +use self::Lonely::{Zero, One, Two}; + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub enum Lonely<X,Y> { Zero, One(X), Two(X, Y) } + +#[rustc_move_fragments] +pub fn test_match_bind_and_underscore(p: Lonely<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR assigned_leaf_path: `($(local p) as Zero)` + //~| ERROR assigned_leaf_path: `($(local p) as One)` + //~| ERROR parent_of_fragments: `($(local p) as Two)` + //~| ERROR moved_leaf_path: `($(local p) as Two).#0` + //~| ERROR unmoved_fragment: `($(local p) as Two).#1` + //~| ERROR assigned_leaf_path: `$(local left)` + + match p { + Zero(..) => {} + + One(_) => {} // <-- does not fragment `($(local p) as One)` ... + + Two(left, _) => {} // <-- ... *does* fragment `($(local p) as Two)`. + } +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-4.rs b/src/test/compile-fail/move-fragments-4.rs new file mode 100644 index 00000000000..dc43dcb9b0e --- /dev/null +++ b/src/test/compile-fail/move-fragments-4.rs @@ -0,0 +1,39 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// This checks that a move of deep structure is properly tracked. (An +// early draft of the code did not properly traverse up through all of +// the parents of the leaf fragment.) + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_move_substructure(pppp: Pair<Pair<Pair<Pair<D,D>, D>, D>, D>) { + //~^ ERROR parent_of_fragments: `$(local pppp)` + //~| ERROR parent_of_fragments: `$(local pppp).x` + //~| ERROR parent_of_fragments: `$(local pppp).x.x` + //~| ERROR unmoved_fragment: `$(local pppp).x.x.x` + //~| ERROR moved_leaf_path: `$(local pppp).x.x.y` + //~| ERROR unmoved_fragment: `$(local pppp).x.y` + //~| ERROR unmoved_fragment: `$(local pppp).y` + drop(pppp.x.x.y); +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-5.rs b/src/test/compile-fail/move-fragments-5.rs new file mode 100644 index 00000000000..df069461ab7 --- /dev/null +++ b/src/test/compile-fail/move-fragments-5.rs @@ -0,0 +1,92 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// This is the first test that checks moving into local variables. + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_move_field_to_local(p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).x` + //~| ERROR unmoved_fragment: `$(local p).y` + //~| ERROR assigned_leaf_path: `$(local _x)` + let _x = p.x; +} + +#[rustc_move_fragments] +pub fn test_move_field_to_local_to_local(p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).x` + //~| ERROR unmoved_fragment: `$(local p).y` + //~| ERROR assigned_leaf_path: `$(local _x)` + //~| ERROR moved_leaf_path: `$(local _x)` + //~| ERROR assigned_leaf_path: `$(local _y)` + let _x = p.x; + let _y = _x; +} + +// In the following fn's `test_move_field_to_local_delayed` and +// `test_uninitialized_local` , the instrumentation reports that `_x` +// is moved. This is unlike `test_move_field_to_local`, where `_x` is +// just reported as an assigned_leaf_path. Presumably because this is +// how we represent that it did not have an initalizing expression at +// the binding site. + +#[rustc_move_fragments] +pub fn test_uninitialized_local(_p: Pair<D, D>) { + //~^ ERROR assigned_leaf_path: `$(local _p)` + //~| ERROR moved_leaf_path: `$(local _x)` + let _x: D; +} + +#[rustc_move_fragments] +pub fn test_move_field_to_local_delayed(p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).x` + //~| ERROR unmoved_fragment: `$(local p).y` + //~| ERROR assigned_leaf_path: `$(local _x)` + //~| ERROR moved_leaf_path: `$(local _x)` + let _x; + _x = p.x; +} + +#[rustc_move_fragments] +pub fn test_move_field_mut_to_local(mut p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local mut p)` + //~| ERROR moved_leaf_path: `$(local mut p).x` + //~| ERROR unmoved_fragment: `$(local mut p).y` + //~| ERROR assigned_leaf_path: `$(local _x)` + let _x = p.x; +} + +#[rustc_move_fragments] +pub fn test_move_field_to_local_to_local_mut(p: Pair<D, D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR moved_leaf_path: `$(local p).x` + //~| ERROR unmoved_fragment: `$(local p).y` + //~| ERROR assigned_leaf_path: `$(local mut _x)` + //~| ERROR moved_leaf_path: `$(local mut _x)` + //~| ERROR assigned_leaf_path: `$(local _y)` + let mut _x = p.x; + let _y = _x; +} + +pub fn main() {} diff --git a/src/test/compile-fail/move-fragments-6.rs b/src/test/compile-fail/move-fragments-6.rs new file mode 100644 index 00000000000..b249d0d7397 --- /dev/null +++ b/src/test/compile-fail/move-fragments-6.rs @@ -0,0 +1,59 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// Test that moving into a field (i.e. overwriting it) fragments the +// receiver. + +use std::mem::drop; + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_overwrite_uninit_field<Z>(z: Z) { + //~^ ERROR parent_of_fragments: `$(local mut p)` + //~| ERROR assigned_leaf_path: `$(local z)` + //~| ERROR moved_leaf_path: `$(local z)` + //~| ERROR assigned_leaf_path: `$(local mut p).x` + //~| ERROR unmoved_fragment: `$(local mut p).y` + + let mut p: Pair<Z,Z>; + p.x = z; +} + +#[rustc_move_fragments] +pub fn test_overwrite_moved_field<Z>(mut p: Pair<Z,Z>, z: Z) { + //~^ ERROR parent_of_fragments: `$(local mut p)` + //~| ERROR assigned_leaf_path: `$(local z)` + //~| ERROR moved_leaf_path: `$(local z)` + //~| ERROR assigned_leaf_path: `$(local mut p).y` + //~| ERROR unmoved_fragment: `$(local mut p).x` + + drop(p); + p.y = z; +} + +#[rustc_move_fragments] +pub fn test_overwrite_same_field<Z>(mut p: Pair<Z,Z>) { + //~^ ERROR parent_of_fragments: `$(local mut p)` + //~| ERROR moved_leaf_path: `$(local mut p).x` + //~| ERROR assigned_leaf_path: `$(local mut p).x` + //~| ERROR unmoved_fragment: `$(local mut p).y` + + p.x = p.x; +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-7.rs b/src/test/compile-fail/move-fragments-7.rs new file mode 100644 index 00000000000..6b2c77bcac1 --- /dev/null +++ b/src/test/compile-fail/move-fragments-7.rs @@ -0,0 +1,46 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// Test that moving a Box<T> fragments its containing structure, for +// both moving out of the structure (i.e. reading `*p.x`) and writing +// into the container (i.e. writing `*p.x`). + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_deref_box_field(p: Pair<Box<D>, Box<D>>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR parent_of_fragments: `$(local p).x` + //~| ERROR moved_leaf_path: `$(local p).x.*` + //~| ERROR unmoved_fragment: `$(local p).y` + //~| ERROR assigned_leaf_path: `$(local i)` + let i : D = *p.x; +} + +#[rustc_move_fragments] +pub fn test_overwrite_deref_box_field(mut p: Pair<Box<D>, Box<D>>) { + //~^ ERROR parent_of_fragments: `$(local mut p)` + //~| ERROR parent_of_fragments: `$(local mut p).x` + //~| ERROR assigned_leaf_path: `$(local mut p).x.*` + //~| ERROR unmoved_fragment: `$(local mut p).y` + *p.x = D { d: 3 }; +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-8.rs b/src/test/compile-fail/move-fragments-8.rs new file mode 100644 index 00000000000..40ab541128c --- /dev/null +++ b/src/test/compile-fail/move-fragments-8.rs @@ -0,0 +1,39 @@ +// Copyright 2014 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. + +// Test that we correctly compute the move fragments for a fn. +// +// Note that the code below is not actually incorrect; the +// `rustc_move_fragments` attribute is a hack that uses the error +// reporting mechanisms as a channel for communicating from the +// internals of the compiler. + +// Test that assigning into a `&T` within structured container does +// *not* fragment its containing structure. +// +// Compare against the `Box<T>` handling in move-fragments-7.rs. Note +// also that in this case we cannot do a move out of `&T`, so we only +// test writing `*p.x` here. + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +pub struct Pair<X,Y> { x: X, y: Y } + +#[rustc_move_fragments] +pub fn test_overwrite_deref_ampersand_field<'a>(p: Pair<&'a mut D, &'a D>) { + //~^ ERROR parent_of_fragments: `$(local p)` + //~| ERROR parent_of_fragments: `$(local p).x` + //~| ERROR assigned_leaf_path: `$(local p).x.*` + //~| ERROR unmoved_fragment: `$(local p).y` + *p.x = D { d: 3 }; +} + +pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-9.rs b/src/test/compile-fail/move-fragments-9.rs new file mode 100644 index 00000000000..ce05087f659 --- /dev/null +++ b/src/test/compile-fail/move-fragments-9.rs @@ -0,0 +1,100 @@ +// Copyright 2014 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. + +// Test moving array structures, e.g. `[T, ..3]` as well as moving +// elements in and out of such arrays. +// +// Note also that the `test_move_array_then_overwrite` tests represent +// cases that we probably should make illegal. + +pub struct D { d: int } +impl Drop for D { fn drop(&mut self) { } } + +#[rustc_move_fragments] +pub fn test_move_array_via_return(a: [D, ..3]) -> [D, ..3] { + //~^ ERROR assigned_leaf_path: `$(local a)` + //~| ERROR moved_leaf_path: `$(local a)` + return a; +} + +#[rustc_move_fragments] +pub fn test_move_array_into_recv(a: [D, ..3], recv: &mut [D, ..3]) { + //~^ ERROR parent_of_fragments: `$(local recv)` + //~| ERROR assigned_leaf_path: `$(local a)` + //~| ERROR moved_leaf_path: `$(local a)` + //~| ERROR assigned_leaf_path: `$(local recv).*` + *recv = a; +} + +#[rustc_move_fragments] +pub fn test_extract_array_elem(a: [D, ..3], i: uint) -> D { + //~^ ERROR parent_of_fragments: `$(local a)` + //~| ERROR assigned_leaf_path: `$(local i)` + //~| ERROR moved_leaf_path: `$(local a).[]` + //~| ERROR unmoved_fragment: `$(allbutone $(local a).[])` + a[i] +} + +#[rustc_move_fragments] +pub fn test_overwrite_array_elem(mut a: [D, ..3], i: uint, d: D) { + //~^ ERROR parent_of_fragments: `$(local mut a)` + //~| ERROR assigned_leaf_path: `$(local i)` + //~| ERROR assigned_leaf_path: `$(local d)` + //~| ERROR moved_leaf_path: `$(local d)` + //~| ERROR assigned_leaf_path: `$(local mut a).[]` + //~| ERROR unmoved_fragment: `$(allbutone $(local mut a).[])` + a[i] = d; +} + +// FIXME (pnkfelix): Both test_move_array_then_overwrite_elem1 and +// test_move_array_then_overwrite_elem2 illustrate a behavior that +// we need to make illegal if we want to get rid of drop-flags. +// See RFC PR 320 for more discussion. + +#[rustc_move_fragments] +pub fn test_move_array_then_overwrite_elem1(mut a: [D, ..3], i: uint, recv: &mut [D, ..3], d: D) { + //~^ ERROR parent_of_fragments: `$(local mut a)` + //~| ERROR parent_of_fragments: `$(local recv)` + //~| ERROR assigned_leaf_path: `$(local recv).*` + //~| ERROR assigned_leaf_path: `$(local i)` + //~| ERROR assigned_leaf_path: `$(local d)` + //~| ERROR moved_leaf_path: `$(local d)` + //~| ERROR assigned_leaf_path: `$(local mut a).[]` + //~| ERROR unmoved_fragment: `$(allbutone $(local mut a).[])` + + // This test covers the case where the array contents have been all moved away, but + // we still need to deal with new initializing writes into the array. + *recv = a; + a[i] = d; +} + +#[rustc_move_fragments] +pub fn test_move_array_then_overwrite_elem2(mut a: [D, ..3], i: uint, j: uint, + recv: &mut [D, ..3], d1: D, d2: D) { + //~^^ ERROR parent_of_fragments: `$(local mut a)` + //~| ERROR parent_of_fragments: `$(local recv)` + //~| ERROR assigned_leaf_path: `$(local recv).*` + //~| ERROR assigned_leaf_path: `$(local i)` + //~| ERROR assigned_leaf_path: `$(local j)` + //~| ERROR assigned_leaf_path: `$(local d1)` + //~| ERROR assigned_leaf_path: `$(local d2)` + //~| ERROR moved_leaf_path: `$(local d1)` + //~| ERROR moved_leaf_path: `$(local d2)` + //~| ERROR assigned_leaf_path: `$(local mut a).[]` + //~| ERROR unmoved_fragment: `$(allbutone $(local mut a).[])` + + // This test covers the case where the array contents have been all moved away, but + // we still need to deal with new initializing writes into the array. + *recv = a; + a[i] = d1; + a[j] = d2; +} + +pub fn main() { } |
