about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2020-08-07 17:57:21 +0100
committerDavid Wood <david@davidtw.co>2020-08-07 18:41:45 +0100
commitac50d61785ae5112b9b4e30a58cfcffe096b31ec (patch)
tree193546fbb3d2110e3c9db793b84abf79b3fa7743
parent4ccaf6f38ce5b617635ec5dc738275c681090eff (diff)
downloadrust-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.rs2
-rw-r--r--src/librustc_middle/ty/fold.rs2
-rw-r--r--src/librustc_middle/ty/instance.rs8
-rw-r--r--src/librustc_middle/ty/mod.rs2
-rw-r--r--src/test/codegen-units/polymorphization/pr-75255.rs23
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]