// revisions: cfail1 cfail2 // compile-flags: -O -Zhuman-readable-cgu-names -Cllvm-args=-import-instr-limit=10 // build-pass // rust-lang/rust#59535: // // This is analogous to cgu_invalidated_when_import_removed.rs, but it covers // the other direction: // // We start with a call-graph like `[A] -> [B -> D] [C]` (where the letters are // functions and the modules are enclosed in `[]`), and add a new call `D <- C`, // yielding the new call-graph: `[A] -> [B -> D] <- [C]` // // The effect of this is that the compiler previously classfied `D` as internal // and the import-set of `[A]` to be just `B`. But after adding the `D <- C` call, // `D` is no longer classified as internal, and the import-set of `[A]` becomes // both `B` and `D`. // // We check this case because an early proposed pull request included an // assertion that the import-sets monotonically decreased over time, a claim // which this test case proves to be false. fn main() { foo::foo(); bar::baz(); } mod foo { // In cfail1, ThinLTO decides that foo() does not get inlined into main, and // instead bar() gets inlined into foo(). // In cfail2, foo() gets inlined into main. pub fn foo(){ bar() } // This function needs to be big so that it does not get inlined by ThinLTO // but *does* get inlined into foo() when it is declared `internal` in // cfail1 (alone). pub fn bar(){ println!("quux1"); println!("quux2"); println!("quux3"); println!("quux4"); println!("quux5"); println!("quux6"); println!("quux7"); println!("quux8"); println!("quux9"); } } mod bar { #[inline(never)] pub fn baz() { #[cfg(cfail2)] { crate::foo::bar(); } } }