diff options
| author | David Wood <david@davidtw.co> | 2020-08-07 17:57:21 +0100 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2020-08-07 18:41:45 +0100 |
| commit | ac50d61785ae5112b9b4e30a58cfcffe096b31ec (patch) | |
| tree | 193546fbb3d2110e3c9db793b84abf79b3fa7743 | |
| parent | 4ccaf6f38ce5b617635ec5dc738275c681090eff (diff) | |
| download | rust-ac50d61785ae5112b9b4e30a58cfcffe096b31ec.tar.gz rust-ac50d61785ae5112b9b4e30a58cfcffe096b31ec.zip | |
instance: polymorphize `FnDef` substs
This commit extends previous polymorphization of substs to polymorphize `FnDef`. Signed-off-by: David Wood <david@davidtw.co>
| -rw-r--r-- | src/librustc_middle/ty/flags.rs | 2 | ||||
| -rw-r--r-- | src/librustc_middle/ty/fold.rs | 2 | ||||
| -rw-r--r-- | src/librustc_middle/ty/instance.rs | 8 | ||||
| -rw-r--r-- | src/librustc_middle/ty/mod.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/polymorphization/pr-75255.rs | 23 |
5 files changed, 31 insertions, 6 deletions
diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index 1782c38f573..81f7474962c 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -196,6 +196,8 @@ impl FlagComputation { } &ty::FnDef(_, substs) => { + self.add_flags(TypeFlags::MAY_POLYMORPHIZE); + self.add_substs(substs); } diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs index c7dbd79e033..87434f3f267 100644 --- a/src/librustc_middle/ty/fold.rs +++ b/src/librustc_middle/ty/fold.rs @@ -150,7 +150,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) } - /// Does this value contain closures or generators such that it may require + /// Does this value contain closures, generators or functions such that it may require /// polymorphization? fn may_polymorphize(&self) -> bool { self.has_type_flags(TypeFlags::MAY_POLYMORPHIZE) diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs index 0eea10513d1..cf876db26bc 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/src/librustc_middle/ty/instance.rs @@ -512,6 +512,14 @@ fn polymorphize<'tcx>( self.tcx.mk_closure(def_id, polymorphized_substs) } } + ty::FnDef(def_id, substs) => { + let polymorphized_substs = polymorphize(self.tcx, def_id, substs); + if substs == polymorphized_substs { + ty + } else { + self.tcx.mk_fn_def(def_id, polymorphized_substs) + } + } ty::Generator(def_id, substs, movability) => { let polymorphized_substs = polymorphize(self.tcx, def_id, substs); if substs == polymorphized_substs { diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 349add46fb2..c82fb2712c2 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -576,7 +576,7 @@ bitflags! { /// replaced later, in a way that would change the results of `impl` specialization? const STILL_FURTHER_SPECIALIZABLE = 1 << 17; - /// Does this value contain closures or generators such that it may require + /// Does this value contain closures, generators or functions such that it may require /// polymorphization? const MAY_POLYMORPHIZE = 1 << 18; } diff --git a/src/test/codegen-units/polymorphization/pr-75255.rs b/src/test/codegen-units/polymorphization/pr-75255.rs index ea9a6e8b181..af47b440640 100644 --- a/src/test/codegen-units/polymorphization/pr-75255.rs +++ b/src/test/codegen-units/polymorphization/pr-75255.rs @@ -3,20 +3,33 @@ #![crate_type = "rlib"] -// Test that only one copy of `Iter::map` is generated. +// Test that only one copy of `Iter::map` and `iter::repeat` are generated. + +fn unused<T>() -> u64 { + 42 +} fn foo<T>() { let x = [1, 2, 3, std::mem::size_of::<T>()]; x.iter().map(|_| ()); } +//~ MONO_ITEM fn core::iter[0]::adapters[0]::{{impl}}[29]::new[0]<core::slice[0]::Iter[0]<usize>, pr_75255::foo[0]::{{closure}}[0]<T>> @@ pr_75255-cgu.0[External] +//~ MONO_ITEM fn core::iter[0]::traits[0]::iterator[0]::Iterator[0]::map[0]<core::slice[0]::Iter[0]<usize>, (), pr_75255::foo[0]::{{closure}}[0]<T>> @@ pr_75255-cgu.1[Internal] + +fn bar<T>() { + std::iter::repeat(unused::<T>); +} + +//~ MONO_ITEM fn core::iter[0]::sources[0]::repeat[0]<fn() -> u64> @@ pr_75255-cgu.1[Internal] + pub fn dispatch() { foo::<String>(); foo::<Vec<String>>(); -} -//~ MONO_ITEM fn core::iter[0]::adapters[0]::{{impl}}[29]::new[0]<core::slice[0]::Iter[0]<usize>, pr_75255::foo[0]::{{closure}}[0]<T>> @@ pr_75255-cgu.0[External] -//~ MONO_ITEM fn core::iter[0]::traits[0]::iterator[0]::Iterator[0]::map[0]<core::slice[0]::Iter[0]<usize>, (), pr_75255::foo[0]::{{closure}}[0]<T>> @@ pr_75255-cgu.1[Internal] + bar::<String>(); + bar::<Vec<String>>(); +} // These are all the items that aren't relevant to the test. //~ MONO_ITEM fn core::mem[0]::size_of[0]<alloc::string[0]::String[0]> @@ pr_75255-cgu.1[Internal] @@ -35,3 +48,5 @@ pub fn dispatch() { //~ MONO_ITEM fn pr_75255::dispatch[0] @@ pr_75255-cgu.1[External] //~ MONO_ITEM fn pr_75255::foo[0]<alloc::string[0]::String[0]> @@ pr_75255-cgu.1[Internal] //~ MONO_ITEM fn pr_75255::foo[0]<alloc::vec[0]::Vec[0]<alloc::string[0]::String[0]>> @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::bar[0]<alloc::string[0]::String[0]> @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::bar[0]<alloc::vec[0]::Vec[0]<alloc::string[0]::String[0]>> @@ pr_75255-cgu.1[Internal] |
