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