about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_middle/ty/instance.rs46
-rw-r--r--src/test/codegen-units/polymorphization/pr-75255.rs37
2 files changed, 45 insertions, 38 deletions
diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs
index bdacc04c291..294bdd76d93 100644
--- a/src/librustc_middle/ty/instance.rs
+++ b/src/librustc_middle/ty/instance.rs
@@ -492,25 +492,6 @@ fn polymorphize<'tcx>(
     let unused = tcx.unused_generic_params(def_id);
     debug!("polymorphize: unused={:?}", unused);
 
-    if unused.is_empty() {
-        // Exit early if every parameter was used.
-        return substs;
-    }
-
-    // If this is a closure or generator then we need to handle the case where another closure
-    // from the function is captured as an upvar and hasn't been polymorphized. In this case,
-    // the unpolymorphized upvar closure would result in a polymorphized closure producing
-    // multiple mono items (and eventually symbol clashes).
-    let upvars_ty = if tcx.is_closure(def_id) {
-        Some(substs.as_closure().tupled_upvars_ty())
-    } else if tcx.type_of(def_id).is_generator() {
-        Some(substs.as_generator().tupled_upvars_ty())
-    } else {
-        None
-    };
-    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);
-    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);
-
     struct PolymorphizationFolder<'tcx> {
         tcx: TyCtxt<'tcx>,
     };
@@ -540,31 +521,20 @@ fn polymorphize<'tcx>(
         let is_unused = unused.contains(param.index).unwrap_or(false);
         debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);
         match param.kind {
-            // Upvar case: If parameter is a type parameter..
-            ty::GenericParamDefKind::Type { .. } if
-                // ..and has upvars..
-                has_upvars &&
-                // ..and this param has the same type as the tupled upvars..
-                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {
-                    // ..then double-check that polymorphization marked it used..
-                    debug_assert!(!is_unused);
-                    // ..and polymorphize any closures/generators captured as upvars.
-                    let upvars_ty = upvars_ty.unwrap();
-                    let polymorphized_upvars_ty = upvars_ty.fold_with(
-                        &mut PolymorphizationFolder { tcx });
-                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);
-                    ty::GenericArg::from(polymorphized_upvars_ty)
-                },
-
-            // Simple case: If parameter is a const or type parameter..
+            // If parameter is a const or type parameter..
             ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if
                 // ..and is within range and unused..
                 unused.contains(param.index).unwrap_or(false) =>
                     // ..then use the identity for this parameter.
                     tcx.mk_param_from_def(param),
 
-            // Otherwise, use the parameter as before.
-            _ => substs[param.index as usize],
+            // Otherwise, use the parameter as before (polymorphizing any closures or generators).
+            _ => {
+                let arg = substs[param.index as usize];
+                let polymorphized_arg = arg.fold_with(&mut PolymorphizationFolder { tcx });
+                debug!("polymorphize: arg={:?} polymorphized_arg={:?}", arg, polymorphized_arg);
+                ty::GenericArg::from(polymorphized_arg)
+            }
         }
     })
 }
diff --git a/src/test/codegen-units/polymorphization/pr-75255.rs b/src/test/codegen-units/polymorphization/pr-75255.rs
new file mode 100644
index 00000000000..ea9a6e8b181
--- /dev/null
+++ b/src/test/codegen-units/polymorphization/pr-75255.rs
@@ -0,0 +1,37 @@
+// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
+// ignore-tidy-linelength
+
+#![crate_type = "rlib"]
+
+// Test that only one copy of `Iter::map` is generated.
+
+fn foo<T>() {
+    let x = [1, 2, 3, std::mem::size_of::<T>()];
+    x.iter().map(|_| ());
+}
+
+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]
+
+// 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]
+//~ MONO_ITEM fn core::mem[0]::size_of[0]<alloc::vec[0]::Vec[0]<alloc::string[0]::String[0]>> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::mem[0]::size_of[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::add[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::is_null[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::offset[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::wrapping_add[0]<u8> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::wrapping_offset[0]<u8> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::non_null[0]::{{impl}}[3]::new_unchecked[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::null[0]<u8> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::as_ptr[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::iter[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::len[0]<usize> @@ pr_75255-cgu.1[Internal]
+//~ 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]