Skip to content

Commit 5fbe0ca

Browse files
committed
First tests making use of the new fn move-fragments instrumentation.
The tests use new "//~| ERROR" follow syntax. Includes a test for moves involving array elements. It was easier than i realized to get something naive off the ground here.
1 parent c9a1c37 commit 5fbe0ca

9 files changed

+565
-0
lines changed
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(tuple_indexing)]
12+
13+
// Test that we correctly compute the move fragments for a fn.
14+
//
15+
// Note that the code below is not actually incorrect; the
16+
// `rustc_move_fragments` attribute is a hack that uses the error
17+
// reporting mechanisms as a channel for communicating from the
18+
// internals of the compiler.
19+
20+
// These are all fairly trivial cases: unused variables or direct
21+
// drops of substructure.
22+
23+
pub struct D { d: int }
24+
impl Drop for D { fn drop(&mut self) { } }
25+
26+
#[rustc_move_fragments]
27+
pub fn test_noop() {
28+
}
29+
30+
#[rustc_move_fragments]
31+
pub fn test_take(_x: D) {
32+
//~^ ERROR assigned_leaf_path: `$(local _x)`
33+
}
34+
35+
pub struct Pair<X,Y> { x: X, y: Y }
36+
37+
#[rustc_move_fragments]
38+
pub fn test_take_struct(_p: Pair<D, D>) {
39+
//~^ ERROR assigned_leaf_path: `$(local _p)`
40+
}
41+
42+
#[rustc_move_fragments]
43+
pub fn test_drop_struct_part(p: Pair<D, D>) {
44+
//~^ ERROR parent_of_fragments: `$(local p)`
45+
//~| ERROR moved_leaf_path: `$(local p).x`
46+
//~| ERROR unmoved_fragment: `$(local p).y`
47+
drop(p.x);
48+
}
49+
50+
#[rustc_move_fragments]
51+
pub fn test_drop_tuple_part(p: (D, D)) {
52+
//~^ ERROR parent_of_fragments: `$(local p)`
53+
//~| ERROR moved_leaf_path: `$(local p).#0`
54+
//~| ERROR unmoved_fragment: `$(local p).#1`
55+
drop(p.0);
56+
}
57+
58+
pub fn main() { }
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we correctly compute the move fragments for a fn.
12+
//
13+
// Note that the code below is not actually incorrect; the
14+
// `rustc_move_fragments` attribute is a hack that uses the error
15+
// reporting mechanisms as a channel for communicating from the
16+
// internals of the compiler.
17+
18+
// These are checking that enums are tracked; note that their output
19+
// paths include "downcasts" of the path to a particular enum.
20+
21+
use self::Lonely::{Zero, One, Two};
22+
23+
pub struct D { d: int }
24+
impl Drop for D { fn drop(&mut self) { } }
25+
26+
pub enum Lonely<X,Y> { Zero, One(X), Two(X, Y) }
27+
28+
#[rustc_move_fragments]
29+
pub fn test_match_partial(p: Lonely<D, D>) {
30+
//~^ ERROR parent_of_fragments: `$(local p)`
31+
//~| ERROR assigned_leaf_path: `($(local p) as Zero)`
32+
match p {
33+
Zero(..) => {}
34+
_ => {}
35+
}
36+
}
37+
38+
#[rustc_move_fragments]
39+
pub fn test_match_full(p: Lonely<D, D>) {
40+
//~^ ERROR parent_of_fragments: `$(local p)`
41+
//~| ERROR assigned_leaf_path: `($(local p) as Zero)`
42+
//~| ERROR assigned_leaf_path: `($(local p) as One)`
43+
//~| ERROR assigned_leaf_path: `($(local p) as Two)`
44+
match p {
45+
Zero(..) => {}
46+
One(..) => {}
47+
Two(..) => {}
48+
}
49+
}
50+
51+
#[rustc_move_fragments]
52+
pub fn test_match_bind_one(p: Lonely<D, D>) {
53+
//~^ ERROR parent_of_fragments: `$(local p)`
54+
//~| ERROR assigned_leaf_path: `($(local p) as Zero)`
55+
//~| ERROR parent_of_fragments: `($(local p) as One)`
56+
//~| ERROR moved_leaf_path: `($(local p) as One).#0`
57+
//~| ERROR assigned_leaf_path: `($(local p) as Two)`
58+
//~| ERROR assigned_leaf_path: `$(local data)`
59+
match p {
60+
Zero(..) => {}
61+
One(data) => {}
62+
Two(..) => {}
63+
}
64+
}
65+
66+
#[rustc_move_fragments]
67+
pub fn test_match_bind_many(p: Lonely<D, D>) {
68+
//~^ ERROR parent_of_fragments: `$(local p)`
69+
//~| ERROR assigned_leaf_path: `($(local p) as Zero)`
70+
//~| ERROR parent_of_fragments: `($(local p) as One)`
71+
//~| ERROR moved_leaf_path: `($(local p) as One).#0`
72+
//~| ERROR assigned_leaf_path: `$(local data)`
73+
//~| ERROR parent_of_fragments: `($(local p) as Two)`
74+
//~| ERROR moved_leaf_path: `($(local p) as Two).#0`
75+
//~| ERROR moved_leaf_path: `($(local p) as Two).#1`
76+
//~| ERROR assigned_leaf_path: `$(local left)`
77+
//~| ERROR assigned_leaf_path: `$(local right)`
78+
match p {
79+
Zero(..) => {}
80+
One(data) => {}
81+
Two(left, right) => {}
82+
}
83+
}
84+
85+
pub fn main() { }
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we correctly compute the move fragments for a fn.
12+
//
13+
// Note that the code below is not actually incorrect; the
14+
// `rustc_move_fragments` attribute is a hack that uses the error
15+
// reporting mechanisms as a channel for communicating from the
16+
// internals of the compiler.
17+
18+
// This checks the handling of `_` within variants, especially when mixed
19+
// with bindings.
20+
21+
use self::Lonely::{Zero, One, Two};
22+
23+
pub struct D { d: int }
24+
impl Drop for D { fn drop(&mut self) { } }
25+
26+
pub enum Lonely<X,Y> { Zero, One(X), Two(X, Y) }
27+
28+
#[rustc_move_fragments]
29+
pub fn test_match_bind_and_underscore(p: Lonely<D, D>) {
30+
//~^ ERROR parent_of_fragments: `$(local p)`
31+
//~| ERROR assigned_leaf_path: `($(local p) as Zero)`
32+
//~| ERROR assigned_leaf_path: `($(local p) as One)`
33+
//~| ERROR parent_of_fragments: `($(local p) as Two)`
34+
//~| ERROR moved_leaf_path: `($(local p) as Two).#0`
35+
//~| ERROR unmoved_fragment: `($(local p) as Two).#1`
36+
//~| ERROR assigned_leaf_path: `$(local left)`
37+
38+
match p {
39+
Zero(..) => {}
40+
41+
One(_) => {} // <-- does not fragment `($(local p) as One)` ...
42+
43+
Two(left, _) => {} // <-- ... *does* fragment `($(local p) as Two)`.
44+
}
45+
}
46+
47+
pub fn main() { }
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we correctly compute the move fragments for a fn.
12+
//
13+
// Note that the code below is not actually incorrect; the
14+
// `rustc_move_fragments` attribute is a hack that uses the error
15+
// reporting mechanisms as a channel for communicating from the
16+
// internals of the compiler.
17+
18+
// This checks that a move of deep structure is properly tracked. (An
19+
// early draft of the code did not properly traverse up through all of
20+
// the parents of the leaf fragment.)
21+
22+
pub struct D { d: int }
23+
impl Drop for D { fn drop(&mut self) { } }
24+
25+
pub struct Pair<X,Y> { x: X, y: Y }
26+
27+
#[rustc_move_fragments]
28+
pub fn test_move_substructure(pppp: Pair<Pair<Pair<Pair<D,D>, D>, D>, D>) {
29+
//~^ ERROR parent_of_fragments: `$(local pppp)`
30+
//~| ERROR parent_of_fragments: `$(local pppp).x`
31+
//~| ERROR parent_of_fragments: `$(local pppp).x.x`
32+
//~| ERROR unmoved_fragment: `$(local pppp).x.x.x`
33+
//~| ERROR moved_leaf_path: `$(local pppp).x.x.y`
34+
//~| ERROR unmoved_fragment: `$(local pppp).x.y`
35+
//~| ERROR unmoved_fragment: `$(local pppp).y`
36+
drop(pppp.x.x.y);
37+
}
38+
39+
pub fn main() { }
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we correctly compute the move fragments for a fn.
12+
//
13+
// Note that the code below is not actually incorrect; the
14+
// `rustc_move_fragments` attribute is a hack that uses the error
15+
// reporting mechanisms as a channel for communicating from the
16+
// internals of the compiler.
17+
18+
// This is the first test that checks moving into local variables.
19+
20+
pub struct D { d: int }
21+
impl Drop for D { fn drop(&mut self) { } }
22+
23+
pub struct Pair<X,Y> { x: X, y: Y }
24+
25+
#[rustc_move_fragments]
26+
pub fn test_move_field_to_local(p: Pair<D, D>) {
27+
//~^ ERROR parent_of_fragments: `$(local p)`
28+
//~| ERROR moved_leaf_path: `$(local p).x`
29+
//~| ERROR unmoved_fragment: `$(local p).y`
30+
//~| ERROR assigned_leaf_path: `$(local _x)`
31+
let _x = p.x;
32+
}
33+
34+
#[rustc_move_fragments]
35+
pub fn test_move_field_to_local_to_local(p: Pair<D, D>) {
36+
//~^ ERROR parent_of_fragments: `$(local p)`
37+
//~| ERROR moved_leaf_path: `$(local p).x`
38+
//~| ERROR unmoved_fragment: `$(local p).y`
39+
//~| ERROR assigned_leaf_path: `$(local _x)`
40+
//~| ERROR moved_leaf_path: `$(local _x)`
41+
//~| ERROR assigned_leaf_path: `$(local _y)`
42+
let _x = p.x;
43+
let _y = _x;
44+
}
45+
46+
// In the following fn's `test_move_field_to_local_delayed` and
47+
// `test_uninitialized_local` , the instrumentation reports that `_x`
48+
// is moved. This is unlike `test_move_field_to_local`, where `_x` is
49+
// just reported as an assigned_leaf_path. Presumably because this is
50+
// how we represent that it did not have an initalizing expression at
51+
// the binding site.
52+
53+
#[rustc_move_fragments]
54+
pub fn test_uninitialized_local(_p: Pair<D, D>) {
55+
//~^ ERROR assigned_leaf_path: `$(local _p)`
56+
//~| ERROR moved_leaf_path: `$(local _x)`
57+
let _x: D;
58+
}
59+
60+
#[rustc_move_fragments]
61+
pub fn test_move_field_to_local_delayed(p: Pair<D, D>) {
62+
//~^ ERROR parent_of_fragments: `$(local p)`
63+
//~| ERROR moved_leaf_path: `$(local p).x`
64+
//~| ERROR unmoved_fragment: `$(local p).y`
65+
//~| ERROR assigned_leaf_path: `$(local _x)`
66+
//~| ERROR moved_leaf_path: `$(local _x)`
67+
let _x;
68+
_x = p.x;
69+
}
70+
71+
#[rustc_move_fragments]
72+
pub fn test_move_field_mut_to_local(mut p: Pair<D, D>) {
73+
//~^ ERROR parent_of_fragments: `$(local mut p)`
74+
//~| ERROR moved_leaf_path: `$(local mut p).x`
75+
//~| ERROR unmoved_fragment: `$(local mut p).y`
76+
//~| ERROR assigned_leaf_path: `$(local _x)`
77+
let _x = p.x;
78+
}
79+
80+
#[rustc_move_fragments]
81+
pub fn test_move_field_to_local_to_local_mut(p: Pair<D, D>) {
82+
//~^ ERROR parent_of_fragments: `$(local p)`
83+
//~| ERROR moved_leaf_path: `$(local p).x`
84+
//~| ERROR unmoved_fragment: `$(local p).y`
85+
//~| ERROR assigned_leaf_path: `$(local mut _x)`
86+
//~| ERROR moved_leaf_path: `$(local mut _x)`
87+
//~| ERROR assigned_leaf_path: `$(local _y)`
88+
let mut _x = p.x;
89+
let _y = _x;
90+
}
91+
92+
pub fn main() {}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we correctly compute the move fragments for a fn.
12+
//
13+
// Note that the code below is not actually incorrect; the
14+
// `rustc_move_fragments` attribute is a hack that uses the error
15+
// reporting mechanisms as a channel for communicating from the
16+
// internals of the compiler.
17+
18+
// Test that moving into a field (i.e. overwriting it) fragments the
19+
// receiver.
20+
21+
use std::mem::drop;
22+
23+
pub struct Pair<X,Y> { x: X, y: Y }
24+
25+
#[rustc_move_fragments]
26+
pub fn test_overwrite_uninit_field<Z>(z: Z) {
27+
//~^ ERROR parent_of_fragments: `$(local mut p)`
28+
//~| ERROR assigned_leaf_path: `$(local z)`
29+
//~| ERROR moved_leaf_path: `$(local z)`
30+
//~| ERROR assigned_leaf_path: `$(local mut p).x`
31+
//~| ERROR unmoved_fragment: `$(local mut p).y`
32+
33+
let mut p: Pair<Z,Z>;
34+
p.x = z;
35+
}
36+
37+
#[rustc_move_fragments]
38+
pub fn test_overwrite_moved_field<Z>(mut p: Pair<Z,Z>, z: Z) {
39+
//~^ ERROR parent_of_fragments: `$(local mut p)`
40+
//~| ERROR assigned_leaf_path: `$(local z)`
41+
//~| ERROR moved_leaf_path: `$(local z)`
42+
//~| ERROR assigned_leaf_path: `$(local mut p).y`
43+
//~| ERROR unmoved_fragment: `$(local mut p).x`
44+
45+
drop(p);
46+
p.y = z;
47+
}
48+
49+
#[rustc_move_fragments]
50+
pub fn test_overwrite_same_field<Z>(mut p: Pair<Z,Z>) {
51+
//~^ ERROR parent_of_fragments: `$(local mut p)`
52+
//~| ERROR moved_leaf_path: `$(local mut p).x`
53+
//~| ERROR assigned_leaf_path: `$(local mut p).x`
54+
//~| ERROR unmoved_fragment: `$(local mut p).y`
55+
56+
p.x = p.x;
57+
}
58+
59+
pub fn main() { }

0 commit comments

Comments
 (0)