Move /src/test to /tests
This commit is contained in:
parent
ca855e6e42
commit
cf2dff2b1e
27592 changed files with 0 additions and 0 deletions
20
tests/codegen-units/item-collection/asm-sym.rs
Normal file
20
tests/codegen-units/item-collection/asm-sym.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// needs-asm-support
|
||||
// compile-flags: -Ccodegen-units=1 -Zprint-mono-items=lazy --crate-type=lib
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn f() {
|
||||
//~ MONO_ITEM static f::S @@ asm_sym-cgu.0[External]
|
||||
static S: usize = 1;
|
||||
//~ MONO_ITEM fn f::fun @@ asm_sym-cgu.0[External]
|
||||
fn fun() {}
|
||||
core::arch::asm!("/* {0} {1} */", sym S, sym fun);
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn g @@ asm_sym-cgu.0[External]
|
||||
pub unsafe fn g() {
|
||||
//~ MONO_ITEM static g::S @@ asm_sym-cgu.0[Internal]
|
||||
static S: usize = 2;
|
||||
//~ MONO_ITEM fn g::fun @@ asm_sym-cgu.0[Internal]
|
||||
fn fun() {}
|
||||
core::arch::asm!("/* {0} {1} */", sym S, sym fun);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
pub trait Trait : Sized {
|
||||
fn without_self() -> u32;
|
||||
fn without_self_default() -> u32 { 0 }
|
||||
|
||||
fn with_default_impl(self) -> Self { self }
|
||||
fn with_default_impl_generic<T>(self, x: T) -> (Self, T) { (self, x) }
|
||||
|
||||
fn without_default_impl(x: u32) -> (Self, u32);
|
||||
fn without_default_impl_generic<T>(x: T) -> (Self, T);
|
||||
}
|
||||
|
||||
impl Trait for char {
|
||||
fn without_self() -> u32 { 2 }
|
||||
fn without_default_impl(x: u32) -> (Self, u32) { ('c', x) }
|
||||
fn without_default_impl_generic<T>(x: T) -> (Self, T) { ('c', x) }
|
||||
}
|
||||
|
||||
impl Trait for u32 {
|
||||
fn without_self() -> u32 { 1 }
|
||||
fn without_default_impl(x: u32) -> (Self, u32) { (0, x) }
|
||||
fn without_default_impl_generic<T>(x: T) -> (Self, T) { (0, x) }
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
#[inline]
|
||||
pub fn inlined_fn(x: i32, y: i32) -> i32 {
|
||||
|
||||
let closure = |a, b| { a + b };
|
||||
|
||||
closure(x, y)
|
||||
}
|
||||
|
||||
pub fn inlined_fn_generic<T>(x: i32, y: i32, z: T) -> (i32, T) {
|
||||
|
||||
let closure = |a, b| { a + b };
|
||||
|
||||
(closure(x, y), z)
|
||||
}
|
||||
|
||||
pub fn non_inlined_fn(x: i32, y: i32) -> i32 {
|
||||
|
||||
let closure = |a, b| { a + b };
|
||||
|
||||
closure(x, y)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
struct Struct(u32);
|
||||
|
||||
#[inline(never)]
|
||||
pub fn foo<T>(x: T) -> (T, u32, i8) {
|
||||
let (x, Struct(y)) = bar(x);
|
||||
(x, y, 2)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn bar<T>(x: T) -> (T, Struct) {
|
||||
let _ = not_exported_and_not_generic(0);
|
||||
(x, Struct(1))
|
||||
}
|
||||
|
||||
// These should not contribute to the codegen items of other crates.
|
||||
#[inline(never)]
|
||||
pub fn exported_but_not_generic(x: i32) -> i64 {
|
||||
x as i64
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn not_exported_and_not_generic(x: u32) -> u64 {
|
||||
x as u64
|
||||
}
|
33
tests/codegen-units/item-collection/cross-crate-closures.rs
Normal file
33
tests/codegen-units/item-collection/cross-crate-closures.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
// In the current version of the collector that still has to support
|
||||
// legacy-codegen, closures do not generate their own MonoItems, so we are
|
||||
// ignoring this test until MIR codegen has taken over completely
|
||||
// ignore-test
|
||||
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
// aux-build:cgu_extern_closures.rs
|
||||
extern crate cgu_extern_closures;
|
||||
|
||||
//~ MONO_ITEM fn cross_crate_closures::start[0]
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
|
||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]
|
||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]::{{closure}}[0]
|
||||
let _ = cgu_extern_closures::inlined_fn(1, 2);
|
||||
|
||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]<i32>
|
||||
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]::{{closure}}[0]<i32>
|
||||
let _ = cgu_extern_closures::inlined_fn_generic(3, 4, 5i32);
|
||||
|
||||
// Nothing should be generated for this call, we just link to the instance
|
||||
// in the extern crate.
|
||||
let _ = cgu_extern_closures::non_inlined_fn(6, 7);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
//~ MONO_ITEM drop-glue i8
|
|
@ -0,0 +1,24 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
// aux-build:cgu_generic_function.rs
|
||||
extern crate cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn cgu_generic_function::bar::<u32>
|
||||
//~ MONO_ITEM fn cgu_generic_function::foo::<u32>
|
||||
let _ = cgu_generic_function::foo(1u32);
|
||||
|
||||
//~ MONO_ITEM fn cgu_generic_function::bar::<u64>
|
||||
//~ MONO_ITEM fn cgu_generic_function::foo::<u64>
|
||||
let _ = cgu_generic_function::foo(2u64);
|
||||
|
||||
// This should not introduce a codegen item
|
||||
let _ = cgu_generic_function::exported_but_not_generic(3);
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
// aux-build:cgu_export_trait_method.rs
|
||||
extern crate cgu_export_trait_method;
|
||||
|
||||
use cgu_export_trait_method::Trait;
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
// The object code of these methods is contained in the external crate, so
|
||||
// calling them should *not* introduce codegen items in the current crate.
|
||||
let _: (u32, u32) = Trait::without_default_impl(0);
|
||||
let _: (char, u32) = Trait::without_default_impl(0);
|
||||
|
||||
// Currently, no object code is generated for trait methods with default
|
||||
// implementations, unless they are actually called from somewhere. Therefore
|
||||
// we cannot import the implementations and have to create our own inline.
|
||||
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl
|
||||
let _ = Trait::with_default_impl(0u32);
|
||||
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl
|
||||
let _ = Trait::with_default_impl('c');
|
||||
|
||||
|
||||
|
||||
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<&str>
|
||||
let _ = Trait::with_default_impl_generic(0u32, "abc");
|
||||
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<bool>
|
||||
let _ = Trait::with_default_impl_generic(0u32, false);
|
||||
|
||||
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i16>
|
||||
let _ = Trait::with_default_impl_generic('x', 1i16);
|
||||
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i32>
|
||||
let _ = Trait::with_default_impl_generic('y', 0i32);
|
||||
|
||||
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
|
||||
let _: (u32, char) = Trait::without_default_impl_generic('c');
|
||||
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
|
||||
let _: (u32, bool) = Trait::without_default_impl_generic(false);
|
||||
|
||||
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
|
||||
let _: (char, char) = Trait::without_default_impl_generic('c');
|
||||
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
|
||||
let _: (char, bool) = Trait::without_default_impl_generic(false);
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDtor> - shim(Some(StructWithDtor)) @@ drop_in_place_intrinsic-cgu.0[Internal]
|
||||
struct StructWithDtor(u32);
|
||||
|
||||
impl Drop for StructWithDtor {
|
||||
//~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<[StructWithDtor; 2]> - shim(Some([StructWithDtor; 2])) @@ drop_in_place_intrinsic-cgu.0[Internal]
|
||||
let x = [StructWithDtor(0), StructWithDtor(1)];
|
||||
|
||||
drop_slice_in_place(&x);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn drop_slice_in_place
|
||||
fn drop_slice_in_place(x: &[StructWithDtor]) {
|
||||
unsafe {
|
||||
// This is the interesting thing in this test case: Normally we would
|
||||
// not have drop-glue for the unsized [StructWithDtor]. This has to be
|
||||
// generated though when the drop_in_place() intrinsic is used.
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<[StructWithDtor]> - shim(Some([StructWithDtor])) @@ drop_in_place_intrinsic-cgu.0[Internal]
|
||||
::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
|
||||
}
|
||||
}
|
40
tests/codegen-units/item-collection/function-as-argument.rs
Normal file
40
tests/codegen-units/item-collection/function-as-argument.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
fn take_fn_once<T1, T2, F: FnOnce(T1, T2)>(f: F, x: T1, y: T2) {
|
||||
(f)(x, y)
|
||||
}
|
||||
|
||||
fn function<T1, T2>(_: T1, _: T2) {}
|
||||
|
||||
fn take_fn_pointer<T1, T2>(f: fn(T1, T2), x: T1, y: T2) {
|
||||
(f)(x, y)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
|
||||
//~ MONO_ITEM fn take_fn_once::<u32, &str, fn(u32, &str) {function::<u32, &str>}>
|
||||
//~ MONO_ITEM fn function::<u32, &str>
|
||||
//~ MONO_ITEM fn <fn(u32, &str) {function::<u32, &str>} as std::ops::FnOnce<(u32, &str)>>::call_once - shim(fn(u32, &str) {function::<u32, &str>})
|
||||
take_fn_once(function, 0u32, "abc");
|
||||
|
||||
//~ MONO_ITEM fn take_fn_once::<char, f64, fn(char, f64) {function::<char, f64>}>
|
||||
//~ MONO_ITEM fn function::<char, f64>
|
||||
//~ MONO_ITEM fn <fn(char, f64) {function::<char, f64>} as std::ops::FnOnce<(char, f64)>>::call_once - shim(fn(char, f64) {function::<char, f64>})
|
||||
take_fn_once(function, 'c', 0f64);
|
||||
|
||||
//~ MONO_ITEM fn take_fn_pointer::<i32, ()>
|
||||
//~ MONO_ITEM fn function::<i32, ()>
|
||||
take_fn_pointer(function, 0i32, ());
|
||||
|
||||
//~ MONO_ITEM fn take_fn_pointer::<f32, i64>
|
||||
//~ MONO_ITEM fn function::<f32, i64>
|
||||
take_fn_pointer(function, 0f32, 0i64);
|
||||
|
||||
0
|
||||
}
|
91
tests/codegen-units/item-collection/generic-drop-glue.rs
Normal file
91
tests/codegen-units/item-collection/generic-drop-glue.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
struct StructWithDrop<T1, T2> {
|
||||
x: T1,
|
||||
y: T2,
|
||||
}
|
||||
|
||||
impl<T1, T2> Drop for StructWithDrop<T1, T2> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
struct StructNoDrop<T1, T2> {
|
||||
x: T1,
|
||||
y: T2,
|
||||
}
|
||||
|
||||
enum EnumWithDrop<T1, T2> {
|
||||
A(T1),
|
||||
B(T2)
|
||||
}
|
||||
|
||||
impl<T1, T2> Drop for EnumWithDrop<T1, T2> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
enum EnumNoDrop<T1, T2> {
|
||||
A(T1),
|
||||
B(T2)
|
||||
}
|
||||
|
||||
|
||||
struct NonGenericNoDrop(#[allow(unused_tuple_struct_fields)] i32);
|
||||
|
||||
struct NonGenericWithDrop(#[allow(unused_tuple_struct_fields)] i32);
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
|
||||
impl Drop for NonGenericWithDrop {
|
||||
//~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop<i8, char>> - shim(Some(StructWithDrop<i8, char>)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <StructWithDrop<i8, char> as std::ops::Drop>::drop
|
||||
let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop<&str, NonGenericNoDrop>> - shim(Some(StructWithDrop<&str, NonGenericNoDrop>)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <StructWithDrop<&str, NonGenericNoDrop> as std::ops::Drop>::drop
|
||||
let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
|
||||
|
||||
// Should produce no drop glue
|
||||
let _ = StructNoDrop { x: 'a', y: 0u32 }.x;
|
||||
|
||||
// This is supposed to generate drop-glue because it contains a field that
|
||||
// needs to be dropped.
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructNoDrop<NonGenericWithDrop, f64>> - shim(Some(StructNoDrop<NonGenericWithDrop, f64>)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop<i32, i64>> - shim(Some(EnumWithDrop<i32, i64>)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <EnumWithDrop<i32, i64> as std::ops::Drop>::drop
|
||||
let _ = match EnumWithDrop::A::<i32, i64>(0) {
|
||||
EnumWithDrop::A(x) => x,
|
||||
EnumWithDrop::B(x) => x as i32
|
||||
};
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop<f64, f32>> - shim(Some(EnumWithDrop<f64, f32>)) @@ generic_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <EnumWithDrop<f64, f32> as std::ops::Drop>::drop
|
||||
let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
|
||||
EnumWithDrop::A(x) => x,
|
||||
EnumWithDrop::B(x) => x as f64
|
||||
};
|
||||
|
||||
let _ = match EnumNoDrop::A::<i32, i64>(0) {
|
||||
EnumNoDrop::A(x) => x,
|
||||
EnumNoDrop::B(x) => x as i32
|
||||
};
|
||||
|
||||
let _ = match EnumNoDrop::B::<f64, f32>(1.0) {
|
||||
EnumNoDrop::A(x) => x,
|
||||
EnumNoDrop::B(x) => x as f64
|
||||
};
|
||||
|
||||
0
|
||||
}
|
55
tests/codegen-units/item-collection/generic-functions.rs
Normal file
55
tests/codegen-units/item-collection/generic-functions.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
fn foo1<T1>(a: T1) -> (T1, u32) {
|
||||
(a, 1)
|
||||
}
|
||||
|
||||
fn foo2<T1, T2>(a: T1, b: T2) -> (T1, T2) {
|
||||
(a, b)
|
||||
}
|
||||
|
||||
fn foo3<T1, T2, T3>(a: T1, b: T2, c: T3) -> (T1, T2, T3) {
|
||||
(a, b, c)
|
||||
}
|
||||
|
||||
// This function should be instantiated even if no used
|
||||
//~ MONO_ITEM fn lifetime_only
|
||||
pub fn lifetime_only<'a>(a: &'a u32) -> &'a u32 {
|
||||
a
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn foo1::<i32>
|
||||
let _ = foo1(2i32);
|
||||
//~ MONO_ITEM fn foo1::<i64>
|
||||
let _ = foo1(2i64);
|
||||
//~ MONO_ITEM fn foo1::<&str>
|
||||
let _ = foo1("abc");
|
||||
//~ MONO_ITEM fn foo1::<char>
|
||||
let _ = foo1('v');
|
||||
|
||||
//~ MONO_ITEM fn foo2::<i32, i32>
|
||||
let _ = foo2(2i32, 2i32);
|
||||
//~ MONO_ITEM fn foo2::<i64, &str>
|
||||
let _ = foo2(2i64, "abc");
|
||||
//~ MONO_ITEM fn foo2::<&str, usize>
|
||||
let _ = foo2("a", 2usize);
|
||||
//~ MONO_ITEM fn foo2::<char, ()>
|
||||
let _ = foo2('v', ());
|
||||
|
||||
//~ MONO_ITEM fn foo3::<i32, i32, i32>
|
||||
let _ = foo3(2i32, 2i32, 2i32);
|
||||
//~ MONO_ITEM fn foo3::<i64, &str, char>
|
||||
let _ = foo3(2i64, "abc", 'c');
|
||||
//~ MONO_ITEM fn foo3::<i16, &str, usize>
|
||||
let _ = foo3(0i16, "a", 2usize);
|
||||
//~ MONO_ITEM fn foo3::<char, (), ()>
|
||||
let _ = foo3('v', (), ());
|
||||
|
||||
0
|
||||
}
|
71
tests/codegen-units/item-collection/generic-impl.rs
Normal file
71
tests/codegen-units/item-collection/generic-impl.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
struct Struct<T> {
|
||||
x: T,
|
||||
f: fn(x: T) -> T,
|
||||
}
|
||||
|
||||
fn id<T>(x: T) -> T { x }
|
||||
|
||||
impl<T> Struct<T> {
|
||||
|
||||
fn new(x: T) -> Struct<T> {
|
||||
Struct {
|
||||
x: x,
|
||||
f: id
|
||||
}
|
||||
}
|
||||
|
||||
fn get<T2>(self, x: T2) -> (T, T2) {
|
||||
(self.x, x)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LifeTimeOnly<'a> {
|
||||
_a: &'a u32
|
||||
}
|
||||
|
||||
impl<'a> LifeTimeOnly<'a> {
|
||||
|
||||
//~ MONO_ITEM fn LifeTimeOnly::<'_>::foo
|
||||
pub fn foo(&self) {}
|
||||
//~ MONO_ITEM fn LifeTimeOnly::<'_>::bar
|
||||
pub fn bar(&'a self) {}
|
||||
//~ MONO_ITEM fn LifeTimeOnly::<'_>::baz
|
||||
pub fn baz<'b>(&'b self) {}
|
||||
|
||||
pub fn non_instantiated<T>(&self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn Struct::<i32>::new
|
||||
//~ MONO_ITEM fn id::<i32>
|
||||
//~ MONO_ITEM fn Struct::<i32>::get::<i16>
|
||||
let _ = Struct::new(0i32).get(0i16);
|
||||
|
||||
//~ MONO_ITEM fn Struct::<i64>::new
|
||||
//~ MONO_ITEM fn id::<i64>
|
||||
//~ MONO_ITEM fn Struct::<i64>::get::<i16>
|
||||
let _ = Struct::new(0i64).get(0i16);
|
||||
|
||||
//~ MONO_ITEM fn Struct::<char>::new
|
||||
//~ MONO_ITEM fn id::<char>
|
||||
//~ MONO_ITEM fn Struct::<char>::get::<i16>
|
||||
let _ = Struct::new('c').get(0i16);
|
||||
|
||||
//~ MONO_ITEM fn Struct::<&str>::new
|
||||
//~ MONO_ITEM fn id::<&str>
|
||||
//~ MONO_ITEM fn Struct::<Struct<&str>>::get::<i16>
|
||||
let _ = Struct::new(Struct::new("str")).get(0i16);
|
||||
|
||||
//~ MONO_ITEM fn Struct::<Struct<&str>>::new
|
||||
//~ MONO_ITEM fn id::<Struct<&str>>
|
||||
let _ = (Struct::new(Struct::new("str")).f)(Struct::new("str"));
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
trait SomeTrait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
// This function is never instantiated but the contained impl must still be
|
||||
// discovered.
|
||||
pub fn generic_function<T>(x: T) -> (T, i32) {
|
||||
impl SomeTrait for i64 {
|
||||
//~ MONO_ITEM fn generic_function::<impl SomeTrait for i64>::foo
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
(x, 0)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
0i64.foo();
|
||||
|
||||
0
|
||||
}
|
58
tests/codegen-units/item-collection/implicit-panic-call.rs
Normal file
58
tests/codegen-units/item-collection/implicit-panic-call.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
// compile-flags:-Zprint-mono-items=lazy
|
||||
|
||||
// rust-lang/rust#90405
|
||||
// Ensure implicit panic calls are collected
|
||||
|
||||
#![feature(lang_items)]
|
||||
#![feature(no_core)]
|
||||
#![crate_type = "lib"]
|
||||
#![no_core]
|
||||
#![no_std]
|
||||
|
||||
#[lang = "panic_location"]
|
||||
struct Location<'a> {
|
||||
_file: &'a str,
|
||||
_line: u32,
|
||||
_col: u32,
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn panic(_: &'static str) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[lang = "freeze"]
|
||||
trait Freeze {}
|
||||
|
||||
impl Copy for i32 {}
|
||||
|
||||
#[lang = "div"]
|
||||
trait Div<Rhs = Self> {
|
||||
type Output;
|
||||
fn div(self, rhs: Rhs) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Div for i32 {
|
||||
type Output = i32;
|
||||
fn div(self, rhs: i32) -> i32 {
|
||||
self / rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unconditional_panic)]
|
||||
pub fn foo() {
|
||||
// This implicitly generates a panic call.
|
||||
let _ = 1 / 0;
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn foo
|
||||
//~ MONO_ITEM fn <i32 as Div>::div
|
||||
//~ MONO_ITEM fn panic
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager -Zinline-in-all-cgus -Zmir-opt-level=0
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) -> u32;
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
struct Struct<T> {
|
||||
_a: T
|
||||
}
|
||||
|
||||
impl<T> Trait for Struct<T> {
|
||||
fn foo(&self) -> u32 { 0 }
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
let s1 = Struct { _a: 0u32 };
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u32>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <Struct<u32> as Trait>::foo
|
||||
//~ MONO_ITEM fn <Struct<u32> as Trait>::bar
|
||||
let _ = &s1 as &Trait;
|
||||
|
||||
let s1 = Struct { _a: 0u64 };
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u64>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <Struct<u64> as Trait>::foo
|
||||
//~ MONO_ITEM fn <Struct<u64> as Trait>::bar
|
||||
let _ = &s1 as &Trait;
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
fn generic_fn<T>(a: T) -> (T, i32) {
|
||||
//~ MONO_ITEM fn generic_fn::nested_fn
|
||||
fn nested_fn(a: i32) -> i32 {
|
||||
a + 1
|
||||
}
|
||||
|
||||
let x = {
|
||||
//~ MONO_ITEM fn generic_fn::nested_fn
|
||||
fn nested_fn(a: i32) -> i32 {
|
||||
a + 2
|
||||
}
|
||||
|
||||
1 + nested_fn(1)
|
||||
};
|
||||
|
||||
return (a, x + nested_fn(0));
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn generic_fn::<i64>
|
||||
let _ = generic_fn(0i64);
|
||||
//~ MONO_ITEM fn generic_fn::<u16>
|
||||
let _ = generic_fn(0u16);
|
||||
//~ MONO_ITEM fn generic_fn::<i8>
|
||||
let _ = generic_fn(0i8);
|
||||
|
||||
0
|
||||
}
|
60
tests/codegen-units/item-collection/non-generic-closures.rs
Normal file
60
tests/codegen-units/item-collection/non-generic-closures.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
// In the current version of the collector that still has to support
|
||||
// legacy-codegen, closures do not generate their own MonoItems, so we are
|
||||
// ignoring this test until MIR codegen has taken over completely
|
||||
// ignore-test
|
||||
|
||||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::temporary[0]
|
||||
fn temporary() {
|
||||
//~ MONO_ITEM fn non_generic_closures::temporary[0]::{{closure}}[0]
|
||||
(|a: u32| {
|
||||
let _ = a;
|
||||
})(4);
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]
|
||||
fn assigned_to_variable_but_not_executed() {
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]::{{closure}}[0]
|
||||
let _x = |a: i16| {
|
||||
let _ = a + 1;
|
||||
};
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]
|
||||
fn assigned_to_variable_executed_indirectly() {
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]::{{closure}}[0]
|
||||
let f = |a: i32| {
|
||||
let _ = a + 2;
|
||||
};
|
||||
run_closure(&f);
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]
|
||||
fn assigned_to_variable_executed_directly() {
|
||||
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]::{{closure}}[0]
|
||||
let f = |a: i64| {
|
||||
let _ = a + 3;
|
||||
};
|
||||
f(4);
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::start[0]
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
temporary();
|
||||
assigned_to_variable_but_not_executed();
|
||||
assigned_to_variable_executed_directly();
|
||||
assigned_to_variable_executed_indirectly();
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn non_generic_closures::run_closure[0]
|
||||
fn run_closure(f: &Fn(i32)) {
|
||||
f(3);
|
||||
}
|
49
tests/codegen-units/item-collection/non-generic-drop-glue.rs
Normal file
49
tests/codegen-units/item-collection/non-generic-drop-glue.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
|
||||
struct StructWithDrop {
|
||||
x: i32
|
||||
}
|
||||
|
||||
impl Drop for StructWithDrop {
|
||||
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
struct StructNoDrop {
|
||||
x: i32
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
|
||||
enum EnumWithDrop {
|
||||
A(i32)
|
||||
}
|
||||
|
||||
impl Drop for EnumWithDrop {
|
||||
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
enum EnumNoDrop {
|
||||
A(i32)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
let _ = StructWithDrop { x: 0 }.x;
|
||||
let _ = StructNoDrop { x: 0 }.x;
|
||||
let _ = match EnumWithDrop::A(0) {
|
||||
EnumWithDrop::A(x) => x
|
||||
};
|
||||
let _ = match EnumNoDrop::A(0) {
|
||||
EnumNoDrop::A(x) => x
|
||||
};
|
||||
|
||||
0
|
||||
}
|
72
tests/codegen-units/item-collection/non-generic-functions.rs
Normal file
72
tests/codegen-units/item-collection/non-generic-functions.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn foo
|
||||
fn foo() {
|
||||
{
|
||||
//~ MONO_ITEM fn foo::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
|
||||
{
|
||||
//~ MONO_ITEM fn foo::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn bar
|
||||
fn bar() {
|
||||
//~ MONO_ITEM fn bar::baz
|
||||
fn baz() {}
|
||||
baz();
|
||||
}
|
||||
|
||||
struct Struct { _x: i32 }
|
||||
|
||||
impl Struct {
|
||||
//~ MONO_ITEM fn Struct::foo
|
||||
fn foo() {
|
||||
{
|
||||
//~ MONO_ITEM fn Struct::foo::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
|
||||
{
|
||||
//~ MONO_ITEM fn Struct::foo::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn Struct::bar
|
||||
fn bar(&self) {
|
||||
{
|
||||
//~ MONO_ITEM fn Struct::bar::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
|
||||
{
|
||||
//~ MONO_ITEM fn Struct::bar::foo
|
||||
fn foo() {}
|
||||
foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
foo();
|
||||
bar();
|
||||
Struct::foo();
|
||||
let x = Struct { _x: 0 };
|
||||
x.bar();
|
||||
|
||||
0
|
||||
}
|
59
tests/codegen-units/item-collection/overloaded-operators.rs
Normal file
59
tests/codegen-units/item-collection/overloaded-operators.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
use std::ops::{Index, IndexMut, Add, Deref};
|
||||
|
||||
pub struct Indexable {
|
||||
data: [u8; 3]
|
||||
}
|
||||
|
||||
impl Index<usize> for Indexable {
|
||||
type Output = u8;
|
||||
|
||||
//~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
if index >= 3 {
|
||||
&self.data[0]
|
||||
} else {
|
||||
&self.data[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for Indexable {
|
||||
//~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
if index >= 3 {
|
||||
&mut self.data[0]
|
||||
} else {
|
||||
&mut self.data[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq
|
||||
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne
|
||||
#[derive(PartialEq)]
|
||||
pub struct Equatable(u32);
|
||||
|
||||
|
||||
impl Add<u32> for Equatable {
|
||||
type Output = u32;
|
||||
|
||||
//~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add
|
||||
fn add(self, rhs: u32) -> u32 {
|
||||
self.0 + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Equatable {
|
||||
type Target = u32;
|
||||
|
||||
//~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
16
tests/codegen-units/item-collection/static-init.rs
Normal file
16
tests/codegen-units/item-collection/static-init.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
|
||||
|
||||
#![feature(start)]
|
||||
|
||||
pub static FN : fn() = foo::<i32>;
|
||||
|
||||
pub fn foo<T>() { }
|
||||
|
||||
//~ MONO_ITEM fn foo::<T>
|
||||
//~ MONO_ITEM static FN
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
54
tests/codegen-units/item-collection/statics-and-consts.rs
Normal file
54
tests/codegen-units/item-collection/statics-and-consts.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
static STATIC1: i64 = {
|
||||
const STATIC1_CONST1: i64 = 2;
|
||||
1 + CONST1 as i64 + STATIC1_CONST1
|
||||
};
|
||||
|
||||
const CONST1: i64 = {
|
||||
const CONST1_1: i64 = {
|
||||
const CONST1_1_1: i64 = 2;
|
||||
CONST1_1_1 + 1
|
||||
};
|
||||
1 + CONST1_1 as i64
|
||||
};
|
||||
|
||||
fn foo() {
|
||||
let _ = {
|
||||
const CONST2: i64 = 0;
|
||||
static STATIC2: i64 = CONST2;
|
||||
|
||||
let x = {
|
||||
const CONST2: i64 = 1;
|
||||
static STATIC2: i64 = CONST2;
|
||||
STATIC2
|
||||
};
|
||||
|
||||
x + STATIC2
|
||||
};
|
||||
|
||||
let _ = {
|
||||
const CONST2: i64 = 0;
|
||||
static STATIC2: i64 = CONST2;
|
||||
STATIC2
|
||||
};
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
foo();
|
||||
let _ = STATIC1;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
//~ MONO_ITEM static STATIC1
|
||||
|
||||
//~ MONO_ITEM fn foo
|
||||
//~ MONO_ITEM static foo::STATIC2
|
||||
//~ MONO_ITEM static foo::STATIC2
|
||||
//~ MONO_ITEM static foo::STATIC2
|
73
tests/codegen-units/item-collection/trait-implementations.rs
Normal file
73
tests/codegen-units/item-collection/trait-implementations.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
pub trait SomeTrait {
|
||||
fn foo(&self);
|
||||
fn bar<T>(&self, x: T);
|
||||
}
|
||||
|
||||
impl SomeTrait for i64 {
|
||||
|
||||
//~ MONO_ITEM fn <i64 as SomeTrait>::foo
|
||||
fn foo(&self) {}
|
||||
|
||||
fn bar<T>(&self, _: T) {}
|
||||
}
|
||||
|
||||
impl SomeTrait for i32 {
|
||||
|
||||
//~ MONO_ITEM fn <i32 as SomeTrait>::foo
|
||||
fn foo(&self) {}
|
||||
|
||||
fn bar<T>(&self, _: T) {}
|
||||
}
|
||||
|
||||
pub trait SomeGenericTrait<T> {
|
||||
fn foo(&self, x: T);
|
||||
fn bar<T2>(&self, x: T, y: T2);
|
||||
}
|
||||
|
||||
// Concrete impl of generic trait
|
||||
impl SomeGenericTrait<u32> for f64 {
|
||||
|
||||
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::foo
|
||||
fn foo(&self, _: u32) {}
|
||||
|
||||
fn bar<T2>(&self, _: u32, _: T2) {}
|
||||
}
|
||||
|
||||
// Generic impl of generic trait
|
||||
impl<T> SomeGenericTrait<T> for f32 {
|
||||
|
||||
fn foo(&self, _: T) {}
|
||||
fn bar<T2>(&self, _: T, _: T2) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn <i32 as SomeTrait>::bar::<char>
|
||||
0i32.bar('x');
|
||||
|
||||
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<&str>
|
||||
0f64.bar(0u32, "&str");
|
||||
|
||||
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<()>
|
||||
0f64.bar(0u32, ());
|
||||
|
||||
//~ MONO_ITEM fn <f32 as SomeGenericTrait<char>>::foo
|
||||
0f32.foo('x');
|
||||
|
||||
//~ MONO_ITEM fn <f32 as SomeGenericTrait<i64>>::foo
|
||||
0f32.foo(-1i64);
|
||||
|
||||
//~ MONO_ITEM fn <f32 as SomeGenericTrait<u32>>::bar::<()>
|
||||
0f32.bar(0u32, ());
|
||||
|
||||
//~ MONO_ITEM fn <f32 as SomeGenericTrait<&str>>::bar::<&str>
|
||||
0f32.bar("&str", "&str");
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
trait Trait : Sized {
|
||||
fn foo(self) -> Self { self }
|
||||
}
|
||||
|
||||
impl Trait for u32 {
|
||||
fn foo(self) -> u32 { self }
|
||||
}
|
||||
|
||||
impl Trait for char {
|
||||
}
|
||||
|
||||
fn take_foo_once<T, F: FnOnce(T) -> T>(f: F, arg: T) -> T {
|
||||
(f)(arg)
|
||||
}
|
||||
|
||||
fn take_foo<T, F: Fn(T) -> T>(f: F, arg: T) -> T {
|
||||
(f)(arg)
|
||||
}
|
||||
|
||||
fn take_foo_mut<T, F: FnMut(T) -> T>(mut f: F, arg: T) -> T {
|
||||
(f)(arg)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn take_foo_once::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <u32 as Trait>::foo
|
||||
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnOnce<(u32,)>>::call_once - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
|
||||
take_foo_once(Trait::foo, 0u32);
|
||||
|
||||
//~ MONO_ITEM fn take_foo_once::<char, fn(char) -> char {<char as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <char as Trait>::foo
|
||||
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnOnce<(char,)>>::call_once - shim(fn(char) -> char {<char as Trait>::foo})
|
||||
take_foo_once(Trait::foo, 'c');
|
||||
|
||||
//~ MONO_ITEM fn take_foo::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::Fn<(u32,)>>::call - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
|
||||
take_foo(Trait::foo, 0u32);
|
||||
|
||||
//~ MONO_ITEM fn take_foo::<char, fn(char) -> char {<char as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::Fn<(char,)>>::call - shim(fn(char) -> char {<char as Trait>::foo})
|
||||
take_foo(Trait::foo, 'c');
|
||||
|
||||
//~ MONO_ITEM fn take_foo_mut::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnMut<(u32,)>>::call_mut - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
|
||||
take_foo_mut(Trait::foo, 0u32);
|
||||
|
||||
//~ MONO_ITEM fn take_foo_mut::<char, fn(char) -> char {<char as Trait>::foo}>
|
||||
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnMut<(char,)>>::call_mut - shim(fn(char) -> char {<char as Trait>::foo})
|
||||
take_foo_mut(Trait::foo, 'c');
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
trait SomeTrait {
|
||||
fn foo(&self) { }
|
||||
fn bar<T>(&self, x: T) -> T { x }
|
||||
}
|
||||
|
||||
impl SomeTrait for i8 {
|
||||
// take the default implementations
|
||||
|
||||
// For the non-generic foo(), we should generate a codegen-item even if it
|
||||
// is not called anywhere
|
||||
//~ MONO_ITEM fn <i8 as SomeTrait>::foo
|
||||
}
|
||||
|
||||
trait SomeGenericTrait<T1> {
|
||||
fn foo(&self) { }
|
||||
fn bar<T2>(&self, x: T1, y: T2) {}
|
||||
}
|
||||
|
||||
// Non-generic impl of generic trait
|
||||
impl SomeGenericTrait<u64> for i32 {
|
||||
// take the default implementations
|
||||
|
||||
// For the non-generic foo(), we should generate a codegen-item even if it
|
||||
// is not called anywhere
|
||||
//~ MONO_ITEM fn <i32 as SomeGenericTrait<T1>>::foo
|
||||
}
|
||||
|
||||
// Non-generic impl of generic trait
|
||||
impl<T1> SomeGenericTrait<T1> for u32 {
|
||||
// take the default implementations
|
||||
// since nothing is monomorphic here, nothing should be generated unless used somewhere.
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn <i8 as SomeTrait>::bar::<char>
|
||||
let _ = 1i8.bar('c');
|
||||
|
||||
//~ MONO_ITEM fn <i8 as SomeTrait>::bar::<&str>
|
||||
let _ = 2i8.bar("&str");
|
||||
|
||||
//~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<char>
|
||||
0i32.bar(0u64, 'c');
|
||||
|
||||
//~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<&str>
|
||||
0i32.bar(0u64, "&str");
|
||||
|
||||
//~ MONO_ITEM fn <u32 as SomeGenericTrait<i8>>::bar::<&[char; 1]>
|
||||
0u32.bar(0i8, &['c']);
|
||||
|
||||
//~ MONO_ITEM fn <u32 as SomeGenericTrait<i16>>::bar::<()>
|
||||
0u32.bar(0i16, ());
|
||||
|
||||
0
|
||||
}
|
46
tests/codegen-units/item-collection/transitive-drop-glue.rs
Normal file
46
tests/codegen-units/item-collection/transitive-drop-glue.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
struct Root(#[allow(unused_tuple_struct_fields)] Intermediate);
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
struct Intermediate(#[allow(unused_tuple_struct_fields)] Leaf);
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
struct Leaf;
|
||||
|
||||
impl Drop for Leaf {
|
||||
//~ MONO_ITEM fn <Leaf as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
struct RootGen<T>(#[allow(unused_tuple_struct_fields)] IntermediateGen<T>);
|
||||
struct IntermediateGen<T>(#[allow(unused_tuple_struct_fields)] LeafGen<T>);
|
||||
struct LeafGen<T>(#[allow(unused_tuple_struct_fields)] T);
|
||||
|
||||
impl<T> Drop for LeafGen<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
let _ = Root(Intermediate(Leaf));
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<RootGen<u32>> - shim(Some(RootGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<IntermediateGen<u32>> - shim(Some(IntermediateGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<LeafGen<u32>> - shim(Some(LeafGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <LeafGen<u32> as std::ops::Drop>::drop
|
||||
let _ = RootGen(IntermediateGen(LeafGen(0u32)));
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<RootGen<i16>> - shim(Some(RootGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<IntermediateGen<i16>> - shim(Some(IntermediateGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<LeafGen<i16>> - shim(Some(LeafGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <LeafGen<i16> as std::ops::Drop>::drop
|
||||
let _ = RootGen(IntermediateGen(LeafGen(0i16)));
|
||||
|
||||
0
|
||||
}
|
27
tests/codegen-units/item-collection/tuple-drop-glue.rs
Normal file
27
tests/codegen-units/item-collection/tuple-drop-glue.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Dropped> - shim(Some(Dropped)) @@ tuple_drop_glue-cgu.0[Internal]
|
||||
struct Dropped;
|
||||
|
||||
impl Drop for Dropped {
|
||||
//~ MONO_ITEM fn <Dropped as std::ops::Drop>::drop
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Dropped)> - shim(Some((u32, Dropped))) @@ tuple_drop_glue-cgu.0[Internal]
|
||||
let x = (0u32, Dropped);
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(i16, (Dropped, bool))> - shim(Some((i16, (Dropped, bool)))) @@ tuple_drop_glue-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(Dropped, bool)> - shim(Some((Dropped, bool))) @@ tuple_drop_glue-cgu.0[Internal]
|
||||
let x = (0i16, (Dropped, true));
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// compile-flags:-Zprint-mono-items=lazy
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
//~ MONO_ITEM fn foo @@ unreferenced_const_fn-cgu.0[External]
|
||||
pub const fn foo(x: u32) -> u32 {
|
||||
x + 0xf00
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// compile-flags:-Zprint-mono-items=lazy
|
||||
|
||||
// N.B., we do not expect *any* monomorphization to be generated here.
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[inline]
|
||||
pub fn foo() -> bool {
|
||||
[1, 2] == [3, 4]
|
||||
}
|
79
tests/codegen-units/item-collection/unsizing.rs
Normal file
79
tests/codegen-units/item-collection/unsizing.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
// compile-flags:-Zmir-opt-level=0
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![feature(coerce_unsized)]
|
||||
#![feature(unsize)]
|
||||
#![feature(start)]
|
||||
|
||||
use std::marker::Unsize;
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
// Simple Case
|
||||
impl Trait for bool {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
impl Trait for char {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
// Struct Field Case
|
||||
struct Struct<T: ?Sized> {
|
||||
_a: u32,
|
||||
_b: i32,
|
||||
_c: T
|
||||
}
|
||||
|
||||
impl Trait for f64 {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
// Custom Coercion Case
|
||||
impl Trait for u32 {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Wrapper<T: ?Sized>(#[allow(unused_tuple_struct_fields)] *const T);
|
||||
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
// simple case
|
||||
let bool_sized = &true;
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<bool> - shim(None) @@ unsizing-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <bool as Trait>::foo
|
||||
let _bool_unsized = bool_sized as &Trait;
|
||||
|
||||
let char_sized = &'a';
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<char> - shim(None) @@ unsizing-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <char as Trait>::foo
|
||||
let _char_unsized = char_sized as &Trait;
|
||||
|
||||
// struct field
|
||||
let struct_sized = &Struct {
|
||||
_a: 1,
|
||||
_b: 2,
|
||||
_c: 3.0f64
|
||||
};
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<f64> - shim(None) @@ unsizing-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <f64 as Trait>::foo
|
||||
let _struct_unsized = struct_sized as &Struct<Trait>;
|
||||
|
||||
// custom coercion
|
||||
let wrapper_sized = Wrapper(&0u32);
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<u32> - shim(None) @@ unsizing-cgu.0[Internal]
|
||||
//~ MONO_ITEM fn <u32 as Trait>::foo
|
||||
let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
|
||||
|
||||
0
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![crate_type="lib"]
|
||||
#![deny(dead_code)]
|
||||
|
||||
// This test asserts that no codegen items are generated for generic items that
|
||||
// are never instantiated in the local crate.
|
||||
|
||||
pub trait Trait {
|
||||
fn foo() {}
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
pub fn foo<T: Copy>(x: T) -> (T, T) {
|
||||
(x, x)
|
||||
}
|
||||
|
||||
pub struct Struct<T> {
|
||||
x: T
|
||||
}
|
||||
|
||||
impl<T> Struct<T> {
|
||||
pub fn foo(self) -> T {
|
||||
self.x
|
||||
}
|
||||
|
||||
pub fn bar() {}
|
||||
}
|
||||
|
||||
pub enum Enum<T> {
|
||||
A(T),
|
||||
B { x: T }
|
||||
}
|
||||
|
||||
impl<T> Enum<T> {
|
||||
pub fn foo(self) -> T {
|
||||
match self {
|
||||
Enum::A(x) => x,
|
||||
Enum::B { x } => x,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bar() {}
|
||||
}
|
||||
|
||||
pub struct TupleStruct<T>(T);
|
||||
|
||||
impl<T> TupleStruct<T> {
|
||||
pub fn foo(self) -> T {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn bar() {}
|
||||
}
|
||||
|
||||
pub type Pair<T> = (T, T);
|
||||
|
||||
pub struct NonGeneric {
|
||||
x: i32
|
||||
}
|
||||
|
||||
impl NonGeneric {
|
||||
pub fn foo(self) -> i32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
pub fn generic_foo<T>(&self, x: T) -> (T, i32) {
|
||||
(x, self.x)
|
||||
}
|
||||
|
||||
pub fn generic_bar<T: Copy>(x: T) -> (T, T) {
|
||||
(x, x)
|
||||
}
|
||||
}
|
||||
|
||||
// Only the non-generic methods should be instantiated:
|
||||
//~ MONO_ITEM fn NonGeneric::foo
|
|
@ -0,0 +1,10 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
#[inline]
|
||||
pub fn inlined() {}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn always_inlined() {}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn never_inlined() {}
|
|
@ -0,0 +1,7 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
pub struct Struct(pub u32);
|
||||
|
||||
impl Drop for Struct {
|
||||
fn drop(&mut self) {}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
struct Struct(u32);
|
||||
|
||||
#[inline(never)]
|
||||
pub fn foo<T>(x: T) -> (T, u32, i8) {
|
||||
let (x, Struct(y)) = bar(x);
|
||||
(x, y, 2)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn bar<T>(x: T) -> (T, Struct) {
|
||||
let _ = not_exported_and_not_generic(0);
|
||||
(x, Struct(1))
|
||||
}
|
||||
|
||||
// These should not contribute to the codegen items of other crates.
|
||||
#[inline(never)]
|
||||
pub fn exported_but_not_generic(x: i32) -> i64 {
|
||||
x as i64
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn not_exported_and_not_generic(x: u32) -> u64 {
|
||||
x as u64
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
|
||||
// prevent drop-glue from participating in share-generics.
|
||||
// compile-flags:-Zshare-generics=yes -Copt-level=0
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type="rlib"]
|
||||
|
||||
pub fn generic_fn<T>(x: T, y: T) -> (T, T) {
|
||||
(x, y)
|
||||
}
|
||||
|
||||
pub fn use_generic_fn_f32() -> (f32, f32) {
|
||||
// This line causes drop glue for Foo to be instantiated. We want to make
|
||||
// sure that this crate exports an instance to be re-used by share-generics.
|
||||
let _ = Foo(0);
|
||||
|
||||
generic_fn(0.0f32, 1.0f32)
|
||||
}
|
||||
|
||||
pub struct Foo(pub u32);
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&mut self) {
|
||||
println!("foo");
|
||||
}
|
||||
}
|
36
tests/codegen-units/partitioning/extern-drop-glue.rs
Normal file
36
tests/codegen-units/partitioning/extern-drop-glue.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// aux-build:cgu_extern_drop_glue.rs
|
||||
extern crate cgu_extern_drop_glue;
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<cgu_extern_drop_glue::Struct> - shim(Some(cgu_extern_drop_glue::Struct)) @@ extern_drop_glue-fallback.cgu[External]
|
||||
|
||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||
|
||||
//~ MONO_ITEM fn user @@ extern_drop_glue[External]
|
||||
pub fn user() {
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<LocalStruct> - shim(Some(LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
|
||||
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
||||
}
|
||||
|
||||
pub mod mod1 {
|
||||
use cgu_extern_drop_glue;
|
||||
|
||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ extern_drop_glue-mod1[External]
|
||||
pub fn user() {
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::LocalStruct> - shim(Some(mod1::LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
|
||||
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
|
||||
}
|
||||
}
|
53
tests/codegen-units/partitioning/extern-generic.rs
Normal file
53
tests/codegen-units/partitioning/extern-generic.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=eager -Zshare-generics=y
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
// aux-build:cgu_generic_function.rs
|
||||
extern crate cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn user @@ extern_generic[Internal]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
}
|
||||
|
||||
mod mod3 {
|
||||
//~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal]
|
||||
fn non_user() {}
|
||||
}
|
||||
|
||||
// Make sure the two generic functions from the extern crate get instantiated
|
||||
// once for the current crate
|
||||
//~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
|
||||
//~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
|
42
tests/codegen-units/partitioning/incremental-merging.rs
Normal file
42
tests/codegen-units/partitioning/incremental-merging.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Ccodegen-units=3
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// This test makes sure that merging of CGUs works together with incremental
|
||||
// compilation but at the same time does not modify names of CGUs that were not
|
||||
// affected by merging.
|
||||
//
|
||||
// We expect CGUs `aaa` and `bbb` to be merged (because they are the smallest),
|
||||
// while `ccc` and `ddd` are supposed to stay untouched.
|
||||
|
||||
pub mod aaa {
|
||||
//~ MONO_ITEM fn aaa::foo @@ incremental_merging-aaa--incremental_merging-bbb[External]
|
||||
pub fn foo(a: u64) -> u64 {
|
||||
a + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub mod bbb {
|
||||
//~ MONO_ITEM fn bbb::foo @@ incremental_merging-aaa--incremental_merging-bbb[External]
|
||||
pub fn foo(a: u64, b: u64) -> u64 {
|
||||
a + b + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub mod ccc {
|
||||
//~ MONO_ITEM fn ccc::foo @@ incremental_merging-ccc[External]
|
||||
pub fn foo(a: u64, b: u64, c: u64) -> u64 {
|
||||
a + b + c + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub mod ddd {
|
||||
//~ MONO_ITEM fn ddd::foo @@ incremental_merging-ddd[External]
|
||||
pub fn foo(a: u64, b: u64, c: u64, d: u64) -> u64 {
|
||||
a + b + c + d + 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
// aux-build:cgu_explicit_inlining.rs
|
||||
extern crate cgu_explicit_inlining;
|
||||
|
||||
// This test makes sure that items inlined from external crates are privately
|
||||
// instantiated in every codegen unit they are used in.
|
||||
|
||||
//~ MONO_ITEM fn cgu_explicit_inlining::inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal]
|
||||
//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal]
|
||||
|
||||
//~ MONO_ITEM fn user @@ inlining_from_extern_crate[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::inlined();
|
||||
cgu_explicit_inlining::always_inlined();
|
||||
|
||||
// does not generate a monomorphization in this crate
|
||||
cgu_explicit_inlining::never_inlined();
|
||||
}
|
||||
|
||||
pub mod mod1 {
|
||||
use cgu_explicit_inlining;
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ inlining_from_extern_crate-mod1[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::inlined();
|
||||
|
||||
// does not generate a monomorphization in this crate
|
||||
cgu_explicit_inlining::never_inlined();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod mod2 {
|
||||
use cgu_explicit_inlining;
|
||||
|
||||
//~ MONO_ITEM fn mod2::user @@ inlining_from_extern_crate-mod2[External]
|
||||
pub fn user()
|
||||
{
|
||||
cgu_explicit_inlining::always_inlined();
|
||||
|
||||
// does not generate a monomorphization in this crate
|
||||
cgu_explicit_inlining::never_inlined();
|
||||
}
|
||||
}
|
46
tests/codegen-units/partitioning/local-drop-glue.rs
Normal file
46
tests/codegen-units/partitioning/local-drop-glue.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct> - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Struct {
|
||||
_a: u32,
|
||||
}
|
||||
|
||||
impl Drop for Struct {
|
||||
//~ MONO_ITEM fn <Struct as std::ops::Drop>::drop @@ local_drop_glue-fallback.cgu[External]
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Outer> - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Outer {
|
||||
_a: Struct,
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn user @@ local_drop_glue[External]
|
||||
pub fn user() {
|
||||
let _ = Outer { _a: Struct { _a: 0 } };
|
||||
}
|
||||
|
||||
pub mod mod1 {
|
||||
use super::Struct;
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::Struct2> - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Struct2 {
|
||||
_a: Struct,
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal]
|
||||
_b: (u32, Struct),
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ local_drop_glue-mod1[External]
|
||||
pub fn user() {
|
||||
let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) };
|
||||
}
|
||||
}
|
45
tests/codegen-units/partitioning/local-generic.rs
Normal file
45
tests/codegen-units/partitioning/local-generic.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
//~ MONO_ITEM fn generic::<u32> @@ local_generic.volatile[External]
|
||||
//~ MONO_ITEM fn generic::<u64> @@ local_generic.volatile[External]
|
||||
//~ MONO_ITEM fn generic::<char> @@ local_generic.volatile[External]
|
||||
//~ MONO_ITEM fn generic::<&str> @@ local_generic.volatile[External]
|
||||
pub fn generic<T>(x: T) -> T { x }
|
||||
|
||||
//~ MONO_ITEM fn user @@ local_generic[Internal]
|
||||
fn user() {
|
||||
let _ = generic(0u32);
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
pub use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal]
|
||||
fn user() {
|
||||
let _ = generic(0u64);
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal]
|
||||
fn user() {
|
||||
let _ = generic('c');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal]
|
||||
fn user() {
|
||||
let _ = generic("abc");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus=no
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
mod inline {
|
||||
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External]
|
||||
#[inline]
|
||||
pub fn inlined_function()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user1::foo @@ local_inlining_but_not_all-user1[External]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user2::bar @@ local_inlining_but_not_all-user2[External]
|
||||
pub fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External]
|
||||
pub fn baz() {
|
||||
|
||||
}
|
||||
}
|
46
tests/codegen-units/partitioning/local-inlining.rs
Normal file
46
tests/codegen-units/partitioning/local-inlining.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
mod inline {
|
||||
|
||||
// Important: This function should show up in all codegen units where it is inlined
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_inlining-user1[Internal] local_inlining-user2[Internal]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user1::foo @@ local_inlining-user1[External]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user2::bar @@ local_inlining-user2[External]
|
||||
pub fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ local_inlining-non_user[External]
|
||||
pub fn baz() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="rlib"]
|
||||
|
||||
mod inline {
|
||||
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_transitive_inlining-indirect_user[Internal]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mod direct_user {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn direct_user::foo @@ local_transitive_inlining-indirect_user[Internal]
|
||||
#[inline(always)]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod indirect_user {
|
||||
use super::direct_user;
|
||||
|
||||
//~ MONO_ITEM fn indirect_user::bar @@ local_transitive_inlining-indirect_user[External]
|
||||
pub fn bar() {
|
||||
direct_user::foo();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ local_transitive_inlining-non_user[External]
|
||||
pub fn baz() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
// Currently, all generic functions are instantiated in each codegen unit that
|
||||
// uses them, even those not marked with #[inline], so this test does not make
|
||||
// much sense at the moment.
|
||||
// ignore-test
|
||||
|
||||
//
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(start)]
|
||||
|
||||
struct SomeType;
|
||||
|
||||
struct SomeGenericType<T1, T2>(T1, T2);
|
||||
|
||||
mod mod1 {
|
||||
use super::{SomeType, SomeGenericType};
|
||||
|
||||
// Even though the impl is in `mod1`, the methods should end up in the
|
||||
// parent module, since that is where their self-type is.
|
||||
impl SomeType {
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::method[0] @@ methods_are_with_self_type[External]
|
||||
fn method(&self) {}
|
||||
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::associated_fn[0] @@ methods_are_with_self_type[External]
|
||||
fn associated_fn() {}
|
||||
}
|
||||
|
||||
impl<T1, T2> SomeGenericType<T1, T2> {
|
||||
pub fn method(&self) {}
|
||||
pub fn associated_fn(_: T1, _: T2) {}
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self);
|
||||
fn default(&self) {}
|
||||
}
|
||||
|
||||
// We provide an implementation of `Trait` for all types. The corresponding
|
||||
// monomorphizations should end up in whichever module the concrete `T` is.
|
||||
impl<T> Trait for T
|
||||
{
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
mod type1 {
|
||||
pub struct Struct;
|
||||
}
|
||||
|
||||
mod type2 {
|
||||
pub struct Struct;
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::start[0]
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::method[0]<u32, u64> @@ methods_are_with_self_type.volatile[WeakODR]
|
||||
SomeGenericType(0u32, 0u64).method();
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::associated_fn[0]<char, &str> @@ methods_are_with_self_type.volatile[WeakODR]
|
||||
SomeGenericType::associated_fn('c', "&str");
|
||||
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0]<methods_are_with_self_type::type1[0]::Struct[0]> @@ methods_are_with_self_type-type1.volatile[WeakODR]
|
||||
type1::Struct.foo();
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0]<methods_are_with_self_type::type2[0]::Struct[0]> @@ methods_are_with_self_type-type2.volatile[WeakODR]
|
||||
type2::Struct.foo();
|
||||
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::Trait[0]::default[0]<methods_are_with_self_type::type1[0]::Struct[0]> @@ methods_are_with_self_type-type1.volatile[WeakODR]
|
||||
type1::Struct.default();
|
||||
//~ MONO_ITEM fn methods_are_with_self_type::Trait[0]::default[0]<methods_are_with_self_type::type2[0]::Struct[0]> @@ methods_are_with_self_type-type2.volatile[WeakODR]
|
||||
type2::Struct.default();
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
//~ MONO_ITEM drop-glue i8
|
72
tests/codegen-units/partitioning/regular-modules.rs
Normal file
72
tests/codegen-units/partitioning/regular-modules.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=eager
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
//~ MONO_ITEM fn foo @@ regular_modules[Internal]
|
||||
fn foo() {}
|
||||
|
||||
//~ MONO_ITEM fn bar @@ regular_modules[Internal]
|
||||
fn bar() {}
|
||||
|
||||
//~ MONO_ITEM static BAZ @@ regular_modules[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
|
||||
//~ MONO_ITEM fn mod1::foo @@ regular_modules-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::bar @@ regular_modules-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::BAZ @@ regular_modules-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
//~ MONO_ITEM fn mod1::mod1::foo @@ regular_modules-mod1-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod1::bar @@ regular_modules-mod1-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod1::BAZ @@ regular_modules-mod1-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ MONO_ITEM fn mod1::mod2::foo @@ regular_modules-mod1-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod2::bar @@ regular_modules-mod1-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod2::BAZ @@ regular_modules-mod1-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
|
||||
//~ MONO_ITEM fn mod2::foo @@ regular_modules-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::bar @@ regular_modules-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::BAZ @@ regular_modules-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
//~ MONO_ITEM fn mod2::mod1::foo @@ regular_modules-mod2-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod1::bar @@ regular_modules-mod2-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod1::BAZ @@ regular_modules-mod2-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ MONO_ITEM fn mod2::mod2::foo @@ regular_modules-mod2-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod2::bar @@ regular_modules-mod2-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod2::BAZ @@ regular_modules-mod2-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
}
|
||||
}
|
28
tests/codegen-units/partitioning/shared-generics.rs
Normal file
28
tests/codegen-units/partitioning/shared-generics.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// no-prefer-dynamic
|
||||
// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
|
||||
// prevent drop-glue from participating in share-generics.
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Copt-level=0
|
||||
|
||||
#![crate_type="rlib"]
|
||||
|
||||
// aux-build:shared_generics_aux.rs
|
||||
extern crate shared_generics_aux;
|
||||
|
||||
//~ MONO_ITEM fn foo
|
||||
pub fn foo() {
|
||||
|
||||
//~ MONO_ITEM fn shared_generics_aux::generic_fn::<u16> @@ shared_generics_aux-in-shared_generics.volatile[External]
|
||||
let _ = shared_generics_aux::generic_fn(0u16, 1u16);
|
||||
|
||||
// This should not generate a monomorphization because it's already
|
||||
// available in `shared_generics_aux`.
|
||||
let _ = shared_generics_aux::generic_fn(0.0f32, 3.0f32);
|
||||
|
||||
// The following line will drop an instance of `Foo`, generating a call to
|
||||
// Foo's drop-glue function. However, share-generics should take care of
|
||||
// reusing the drop-glue from the upstream crate, so we do not expect a
|
||||
// mono item for the drop-glue
|
||||
let _ = shared_generics_aux::Foo(1);
|
||||
}
|
38
tests/codegen-units/partitioning/statics.rs
Normal file
38
tests/codegen-units/partitioning/statics.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
|
||||
#![crate_type="rlib"]
|
||||
|
||||
//~ MONO_ITEM static FOO @@ statics[Internal]
|
||||
static FOO: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM static BAR @@ statics[Internal]
|
||||
static BAR: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM fn function @@ statics[External]
|
||||
pub fn function() {
|
||||
//~ MONO_ITEM static function::FOO @@ statics[Internal]
|
||||
static FOO: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM static function::BAR @@ statics[Internal]
|
||||
static BAR: u32 = 0;
|
||||
}
|
||||
|
||||
pub mod mod1 {
|
||||
//~ MONO_ITEM static mod1::FOO @@ statics-mod1[Internal]
|
||||
static FOO: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM static mod1::BAR @@ statics-mod1[Internal]
|
||||
static BAR: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM fn mod1::function @@ statics-mod1[External]
|
||||
pub fn function() {
|
||||
//~ MONO_ITEM static mod1::function::FOO @@ statics-mod1[Internal]
|
||||
static FOO: u32 = 0;
|
||||
|
||||
//~ MONO_ITEM static mod1::function::BAR @@ statics-mod1[Internal]
|
||||
static BAR: u32 = 0;
|
||||
}
|
||||
}
|
94
tests/codegen-units/partitioning/vtable-through-const.rs
Normal file
94
tests/codegen-units/partitioning/vtable-through-const.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
|
||||
// We specify incremental here because we want to test the partitioning for
|
||||
// incremental compilation
|
||||
// incremental
|
||||
// compile-flags:-Zprint-mono-items=lazy
|
||||
// compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
// This test case makes sure, that references made through constants are
|
||||
// recorded properly in the InliningMap.
|
||||
|
||||
#![feature(start)]
|
||||
|
||||
mod mod1 {
|
||||
pub trait Trait1 {
|
||||
fn do_something(&self) {}
|
||||
fn do_something_else(&self) {}
|
||||
}
|
||||
|
||||
impl Trait1 for u32 {}
|
||||
|
||||
pub trait Trait1Gen<T> {
|
||||
fn do_something(&self, x: T) -> T;
|
||||
fn do_something_else(&self, x: T) -> T;
|
||||
}
|
||||
|
||||
impl<T> Trait1Gen<T> for u32 {
|
||||
fn do_something(&self, x: T) -> T { x }
|
||||
fn do_something_else(&self, x: T) -> T { x }
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn mod1::id::<i64> @@ vtable_through_const-mod1.volatile[Internal]
|
||||
fn id<T>(x: T) -> T { x }
|
||||
|
||||
// These are referenced, so they produce mono-items (see start())
|
||||
pub const TRAIT1_REF: &'static Trait1 = &0u32 as &Trait1;
|
||||
pub const TRAIT1_GEN_REF: &'static Trait1Gen<u8> = &0u32 as &Trait1Gen<u8>;
|
||||
pub const ID_CHAR: fn(char) -> char = id::<char>;
|
||||
|
||||
|
||||
|
||||
pub trait Trait2 {
|
||||
fn do_something(&self) {}
|
||||
fn do_something_else(&self) {}
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something @@ vtable_through_const-mod1.volatile[Internal]
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait2>::do_something_else @@ vtable_through_const-mod1.volatile[Internal]
|
||||
impl Trait2 for u32 {}
|
||||
|
||||
pub trait Trait2Gen<T> {
|
||||
fn do_something(&self, x: T) -> T;
|
||||
fn do_something_else(&self, x: T) -> T;
|
||||
}
|
||||
|
||||
impl<T> Trait2Gen<T> for u32 {
|
||||
fn do_something(&self, x: T) -> T { x }
|
||||
fn do_something_else(&self, x: T) -> T { x }
|
||||
}
|
||||
|
||||
// These are not referenced, so they do not produce mono-items
|
||||
pub const TRAIT2_REF: &'static Trait2 = &0u32 as &Trait2;
|
||||
pub const TRAIT2_GEN_REF: &'static Trait2Gen<u8> = &0u32 as &Trait2Gen<u8>;
|
||||
pub const ID_I64: fn(i64) -> i64 = id::<i64>;
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<u32> - shim(None) @@ vtable_through_const[Internal]
|
||||
|
||||
// Since Trait1::do_something() is instantiated via its default implementation,
|
||||
// it is considered a generic and is instantiated here only because it is
|
||||
// referenced in this module.
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something_else @@ vtable_through_const-mod1.volatile[External]
|
||||
|
||||
// Although it is never used, Trait1::do_something_else() has to be
|
||||
// instantiated locally here too, otherwise the <&u32 as &Trait1> vtable
|
||||
// could not be fully constructed.
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait1>::do_something @@ vtable_through_const-mod1.volatile[External]
|
||||
mod1::TRAIT1_REF.do_something();
|
||||
|
||||
// Same as above
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[External]
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait1Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[External]
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something @@ vtable_through_const-mod1.volatile[Internal]
|
||||
//~ MONO_ITEM fn <u32 as mod1::Trait2Gen<u8>>::do_something_else @@ vtable_through_const-mod1.volatile[Internal]
|
||||
mod1::TRAIT1_GEN_REF.do_something(0u8);
|
||||
|
||||
//~ MONO_ITEM fn mod1::id::<char> @@ vtable_through_const-mod1.volatile[External]
|
||||
mod1::ID_CHAR('x');
|
||||
|
||||
0
|
||||
}
|
322
tests/codegen-units/polymorphization/unused_type_parameters.rs
Normal file
322
tests/codegen-units/polymorphization/unused_type_parameters.rs
Normal file
|
@ -0,0 +1,322 @@
|
|||
// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// This test checks that the polymorphization analysis correctly reduces the
|
||||
// generated mono items.
|
||||
|
||||
mod functions {
|
||||
// Function doesn't have any type parameters to be unused.
|
||||
pub fn no_parameters() {}
|
||||
|
||||
//~ MONO_ITEM fn functions::no_parameters
|
||||
|
||||
// Function has an unused type parameter.
|
||||
pub fn unused<T>() {
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn functions::unused::<T>
|
||||
|
||||
// Function uses type parameter in value of a binding.
|
||||
pub fn used_binding_value<T: Default>() {
|
||||
let _: T = Default::default();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn functions::used_binding_value::<u32>
|
||||
//~ MONO_ITEM fn functions::used_binding_value::<u64>
|
||||
|
||||
// Function uses type parameter in type of a binding.
|
||||
pub fn used_binding_type<T>() {
|
||||
let _: Option<T> = None;
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn functions::used_binding_type::<u32>
|
||||
//~ MONO_ITEM fn functions::used_binding_type::<u64>
|
||||
|
||||
// Function uses type parameter in argument.
|
||||
pub fn used_argument<T>(_: T) {
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn functions::used_argument::<u32>
|
||||
//~ MONO_ITEM fn functions::used_argument::<u64>
|
||||
//
|
||||
// Function uses type parameter in substitutions to another function.
|
||||
pub fn used_substs<T>() {
|
||||
unused::<T>()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn functions::used_substs::<u32>
|
||||
//~ MONO_ITEM fn functions::used_substs::<u64>
|
||||
}
|
||||
|
||||
|
||||
mod closures {
|
||||
// Function doesn't have any type parameters to be unused.
|
||||
pub fn no_parameters() {
|
||||
let _ = || {};
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::no_parameters
|
||||
|
||||
// Function has an unused type parameter in parent and closure.
|
||||
pub fn unused<T>() -> u32 {
|
||||
let add_one = |x: u32| x + 1;
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::unused::<T>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::unused::<T>
|
||||
|
||||
// Function has an unused type parameter in closure, but not in parent.
|
||||
pub fn used_parent<T: Default>() -> u32 {
|
||||
let _: T = Default::default();
|
||||
let add_one = |x: u32| x + 1;
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_parent::<T>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_parent::<u32>
|
||||
//~ MONO_ITEM fn closures::used_parent::<u64>
|
||||
|
||||
// Function uses type parameter in value of a binding in closure.
|
||||
pub fn used_binding_value<T: Default>() -> T {
|
||||
let x = || {
|
||||
let y: T = Default::default();
|
||||
y
|
||||
};
|
||||
|
||||
x()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_binding_value::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_binding_value::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_binding_value::<u32>
|
||||
//~ MONO_ITEM fn closures::used_binding_value::<u64>
|
||||
|
||||
// Function uses type parameter in type of a binding in closure.
|
||||
pub fn used_binding_type<T>() -> Option<T> {
|
||||
let x = || {
|
||||
let y: Option<T> = None;
|
||||
y
|
||||
};
|
||||
|
||||
x()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_binding_type::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_binding_type::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_binding_type::<u32>
|
||||
//~ MONO_ITEM fn closures::used_binding_type::<u64>
|
||||
|
||||
// Function and closure uses type parameter in argument.
|
||||
pub fn used_argument<T>(t: T) -> u32 {
|
||||
let x = |_: T| 3;
|
||||
x(t)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_argument::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_argument::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_argument::<u32>
|
||||
//~ MONO_ITEM fn closures::used_argument::<u64>
|
||||
|
||||
// Closure uses type parameter in argument.
|
||||
pub fn used_argument_closure<T: Default>() -> u32 {
|
||||
let t: T = Default::default();
|
||||
let x = |_: T| 3;
|
||||
x(t)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_argument_closure::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_argument_closure::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_argument_closure::<u32>
|
||||
//~ MONO_ITEM fn closures::used_argument_closure::<u64>
|
||||
|
||||
// Closure uses type parameter as upvar.
|
||||
pub fn used_upvar<T: Default>() -> T {
|
||||
let x: T = Default::default();
|
||||
let y = || x;
|
||||
y()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_upvar::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_upvar::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_upvar::<u32>
|
||||
//~ MONO_ITEM fn closures::used_upvar::<u64>
|
||||
|
||||
// Closure uses type parameter in substitutions to another function.
|
||||
pub fn used_substs<T>() {
|
||||
let x = || super::functions::unused::<T>();
|
||||
x()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn closures::used_substs::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_substs::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn closures::used_substs::<u32>
|
||||
//~ MONO_ITEM fn closures::used_substs::<u64>
|
||||
}
|
||||
|
||||
mod methods {
|
||||
pub struct Foo<F>(F);
|
||||
|
||||
impl<F: Default> Foo<F> {
|
||||
// Function has an unused type parameter from impl.
|
||||
pub fn unused_impl() {
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::unused_impl
|
||||
|
||||
// Function has an unused type parameter from impl and fn.
|
||||
pub fn unused_both<G: Default>() {
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::unused_both::<G>
|
||||
|
||||
// Function uses type parameter from impl.
|
||||
pub fn used_impl() {
|
||||
let _: F = Default::default();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::used_impl
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::used_impl
|
||||
|
||||
// Function uses type parameter from impl.
|
||||
pub fn used_fn<G: Default>() {
|
||||
let _: G = Default::default();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u32>
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u64>
|
||||
|
||||
// Function uses type parameter from impl.
|
||||
pub fn used_both<G: Default>() {
|
||||
let _: F = Default::default();
|
||||
let _: G = Default::default();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::used_both::<u32>
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::used_both::<u64>
|
||||
|
||||
// Function uses type parameter in substitutions to another function.
|
||||
pub fn used_substs() {
|
||||
super::functions::unused::<F>()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::used_substs
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::used_substs
|
||||
|
||||
// Function has an unused type parameter from impl and fn.
|
||||
pub fn closure_unused_all<G: Default>() -> u32 {
|
||||
let add_one = |x: u32| x + 1;
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>
|
||||
|
||||
// Function uses type parameter from impl and fn in closure.
|
||||
pub fn closure_used_both<G: Default>() -> u32 {
|
||||
let add_one = |x: u32| {
|
||||
let _: F = Default::default();
|
||||
let _: G = Default::default();
|
||||
x + 1
|
||||
};
|
||||
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>
|
||||
|
||||
// Function uses type parameter from fn in closure.
|
||||
pub fn closure_used_fn<G: Default>() -> u32 {
|
||||
let add_one = |x: u32| {
|
||||
let _: G = Default::default();
|
||||
x + 1
|
||||
};
|
||||
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>
|
||||
//~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>
|
||||
|
||||
// Function uses type parameter from impl in closure.
|
||||
pub fn closure_used_impl<G: Default>() -> u32 {
|
||||
let add_one = |x: u32| {
|
||||
let _: F = Default::default();
|
||||
x + 1
|
||||
};
|
||||
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>
|
||||
|
||||
// Closure uses type parameter in substitutions to another function.
|
||||
pub fn closure_used_substs() {
|
||||
let x = || super::functions::unused::<F>();
|
||||
x()
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs::{closure#0}
|
||||
//~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs
|
||||
//~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn dispatch<T: Default>() {
|
||||
functions::no_parameters();
|
||||
functions::unused::<T>();
|
||||
functions::used_binding_value::<T>();
|
||||
functions::used_binding_type::<T>();
|
||||
functions::used_argument::<T>(Default::default());
|
||||
functions::used_substs::<T>();
|
||||
|
||||
closures::no_parameters();
|
||||
let _ = closures::unused::<T>();
|
||||
let _ = closures::used_parent::<T>();
|
||||
let _ = closures::used_binding_value::<T>();
|
||||
let _ = closures::used_binding_type::<T>();
|
||||
let _ = closures::used_argument::<T>(Default::default());
|
||||
let _ = closures::used_argument_closure::<T>();
|
||||
let _ = closures::used_upvar::<T>();
|
||||
let _ = closures::used_substs::<T>();
|
||||
|
||||
methods::Foo::<T>::unused_impl();
|
||||
methods::Foo::<T>::unused_both::<T>();
|
||||
methods::Foo::<T>::used_impl();
|
||||
methods::Foo::<T>::used_fn::<T>();
|
||||
methods::Foo::<T>::used_both::<T>();
|
||||
methods::Foo::<T>::used_substs();
|
||||
let _ = methods::Foo::<T>::closure_unused_all::<T>();
|
||||
let _ = methods::Foo::<T>::closure_used_both::<T>();
|
||||
let _ = methods::Foo::<T>::closure_used_impl::<T>();
|
||||
let _ = methods::Foo::<T>::closure_used_fn::<T>();
|
||||
let _ = methods::Foo::<T>::closure_used_substs();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn dispatch::<u32>
|
||||
//~ MONO_ITEM fn dispatch::<u64>
|
||||
|
||||
pub fn foo() {
|
||||
// Generate two copies of each function to check that where the type parameter is unused,
|
||||
// there is only a single copy.
|
||||
dispatch::<u32>();
|
||||
dispatch::<u64>();
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn foo @@ unused_type_parameters-cgu.0[External]
|
||||
|
||||
// These are all the items that aren't relevant to the test.
|
||||
//~ MONO_ITEM fn <u32 as std::default::Default>::default
|
||||
//~ MONO_ITEM fn <u64 as std::default::Default>::default
|
Loading…
Add table
Add a link
Reference in a new issue