]> git.lizzy.rs Git - rust.git/blob - src/test/incremental/change_add_field/struct_point.rs
Add test for eval order for a+=b
[rust.git] / src / test / incremental / change_add_field / struct_point.rs
1 // Test where we change a type definition by adding a field.  Fns with
2 // this type in their signature are recompiled, as are their callers.
3 // Fns with that type used only in their body are also recompiled, but
4 // their callers are not.
5
6 // revisions:cfail1 cfail2
7 // compile-flags: -Z query-dep-graph
8 // build-pass (FIXME(62277): could be check-pass?)
9
10 #![feature(rustc_attrs)]
11 #![feature(stmt_expr_attributes)]
12 #![allow(dead_code)]
13 #![crate_type = "rlib"]
14
15 // These are expected to require codegen.
16 #![rustc_partition_codegened(module="struct_point-point", cfg="cfail2")]
17 #![rustc_partition_codegened(module="struct_point-fn_with_type_in_sig", cfg="cfail2")]
18 #![rustc_partition_codegened(module="struct_point-call_fn_with_type_in_sig", cfg="cfail2")]
19 #![rustc_partition_codegened(module="struct_point-fn_with_type_in_body", cfg="cfail2")]
20 #![rustc_partition_codegened(module="struct_point-fn_make_struct", cfg="cfail2")]
21 #![rustc_partition_codegened(module="struct_point-fn_read_field", cfg="cfail2")]
22 #![rustc_partition_codegened(module="struct_point-fn_write_field", cfg="cfail2")]
23
24 #![rustc_partition_reused(module="struct_point-call_fn_with_type_in_body", cfg="cfail2")]
25
26 pub mod point {
27     #[cfg(cfail1)]
28     pub struct Point {
29         pub x: f32,
30         pub y: f32,
31     }
32
33     #[cfg(cfail2)]
34     pub struct Point {
35         pub x: f32,
36         pub y: f32,
37         pub z: f32,
38     }
39
40     impl Point {
41         pub fn origin() -> Point {
42             #[cfg(cfail1)]
43             return Point { x: 0.0, y: 0.0 };
44
45             #[cfg(cfail2)]
46             return Point { x: 0.0, y: 0.0, z: 0.0 };
47         }
48
49         pub fn total(&self) -> f32 {
50             #[cfg(cfail1)]
51             return self.x + self.y;
52
53             #[cfg(cfail2)]
54             return self.x + self.y + self.z;
55         }
56
57         pub fn x(&self) -> f32 {
58             self.x
59         }
60     }
61 }
62
63 /// A function that has the changed type in its signature; must currently be
64 /// rebuilt.
65 ///
66 /// You could imagine that, in the future, if the change were
67 /// sufficiently "private", we might not need to type-check again.
68 /// Rebuilding is probably always necessary since the layout may be
69 /// affected.
70 pub mod fn_with_type_in_sig {
71     use point::Point;
72
73     #[rustc_dirty(label="typeck", cfg="cfail2")]
74     pub fn boop(p: Option<&Point>) -> f32 {
75         p.map(|p| p.total()).unwrap_or(0.0)
76     }
77 }
78
79 /// Call a function that has the changed type in its signature; this
80 /// currently must also be rebuilt.
81 ///
82 /// You could imagine that, in the future, if the change were
83 /// sufficiently "private", we might not need to type-check again.
84 /// Rebuilding is probably always necessary since the layout may be
85 /// affected.
86 pub mod call_fn_with_type_in_sig {
87     use fn_with_type_in_sig;
88
89     #[rustc_dirty(label="typeck", cfg="cfail2")]
90     pub fn bip() -> f32 {
91         fn_with_type_in_sig::boop(None)
92     }
93 }
94
95 /// A function that uses the changed type, but only in its body, not its
96 /// signature.
97 ///
98 /// You could imagine that, in the future, if the change were
99 /// sufficiently "private", we might not need to type-check again.
100 /// Rebuilding is probably always necessary since the layout may be
101 /// affected.
102 pub mod fn_with_type_in_body {
103     use point::Point;
104
105     #[rustc_dirty(label="typeck", cfg="cfail2")]
106     pub fn boop() -> f32 {
107         Point::origin().total()
108     }
109 }
110
111 /// A function `X` that calls a function `Y`, where `Y` uses the changed type in its
112 /// body. In this case, the effects of the change should be contained
113 /// to `Y`; `X` should not have to be rebuilt, nor should it need to be
114 /// type-checked again.
115 pub mod call_fn_with_type_in_body {
116     use fn_with_type_in_body;
117
118     #[rustc_clean(label="typeck", cfg="cfail2")]
119     pub fn bip() -> f32 {
120         fn_with_type_in_body::boop()
121     }
122 }
123
124 /// A function item that makes an instance of `Point` but does not invoke methods.
125 pub mod fn_make_struct {
126     use point::Point;
127
128     #[rustc_dirty(label="typeck", cfg="cfail2")]
129     pub fn make_origin(p: Point) -> Point {
130         Point { ..p }
131     }
132 }
133
134 /// A function item that reads fields from `Point` but does not invoke methods.
135 pub mod fn_read_field {
136     use point::Point;
137
138     #[rustc_dirty(label="typeck", cfg="cfail2")]
139     pub fn get_x(p: Point) -> f32 {
140         p.x
141     }
142 }
143
144 /// A function item that writes to a field of `Point` but does not invoke methods.
145 pub mod fn_write_field {
146     use point::Point;
147
148     #[rustc_dirty(label="typeck", cfg="cfail2")]
149     pub fn inc_x(p: &mut Point) {
150         p.x += 1.0;
151     }
152 }