about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_index/bit_set.rs24
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs2
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs7
-rw-r--r--src/librustc_metadata/rmeta/mod.rs2
-rw-r--r--src/librustc_middle/query/mod.rs2
-rw-r--r--src/librustc_mir/interpret/util.rs16
-rw-r--r--src/librustc_mir/monomorphize/polymorphize.rs23
7 files changed, 61 insertions, 15 deletions
diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs
index b369be25218..e4b7c24a249 100644
--- a/src/librustc_index/bit_set.rs
+++ b/src/librustc_index/bit_set.rs
@@ -1034,6 +1034,30 @@ pub trait FiniteBitSetTy:
     fn checked_shr(self, rhs: u32) -> Option<Self>;
 }
 
+impl FiniteBitSetTy for u32 {
+    const DOMAIN_SIZE: u32 = 32;
+
+    const FILLED: Self = Self::MAX;
+    const EMPTY: Self = Self::MIN;
+
+    const ONE: Self = 1u32;
+    const ZERO: Self = 0u32;
+
+    fn checked_shl(self, rhs: u32) -> Option<Self> {
+        self.checked_shl(rhs)
+    }
+
+    fn checked_shr(self, rhs: u32) -> Option<Self> {
+        self.checked_shr(rhs)
+    }
+}
+
+impl std::fmt::Debug for FiniteBitSet<u32> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:032b}", self.0)
+    }
+}
+
 impl FiniteBitSetTy for u64 {
     const DOMAIN_SIZE: u32 = 64;
 
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 3c045df45da..10dc407c060 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -1150,7 +1150,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, tcx))
     }
 
-    fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u64> {
+    fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u32> {
         self.root
             .tables
             .unused_generic_params
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 352b8bff7e2..aec9e8daa0f 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1134,8 +1134,11 @@ impl EncodeContext<'a, 'tcx> {
         debug!("EntryBuilder::encode_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
             record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
-            record!(self.tables.unused_generic_params[def_id.to_def_id()] <-
-                    self.tcx.unused_generic_params(def_id));
+
+            let unused = self.tcx.unused_generic_params(def_id);
+            if !unused.is_empty() {
+                record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
+            }
         }
     }
 
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index 12d2f50363c..465461ebf97 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -285,7 +285,7 @@ define_tables! {
     super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
     mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
     promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
-    unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u64>>>,
+    unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index 862c046358b..7e9226f83c3 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -1319,7 +1319,7 @@ rustc_queries! {
         query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
             desc { "codegen_unit" }
         }
-        query unused_generic_params(key: DefId) -> FiniteBitSet<u64> {
+        query unused_generic_params(key: DefId) -> FiniteBitSet<u32> {
             cache_on_disk_if { key.is_local() }
             desc {
                 |tcx| "determining which generic parameters are unused by `{}`",
diff --git a/src/librustc_mir/interpret/util.rs b/src/librustc_mir/interpret/util.rs
index c0eac8a9305..57c5fc59cc0 100644
--- a/src/librustc_mir/interpret/util.rs
+++ b/src/librustc_mir/interpret/util.rs
@@ -47,14 +47,26 @@ where
                             unused_params.contains(index).map(|unused| !unused).unwrap_or(true);
                         // Only recurse when generic parameters in fns, closures and generators
                         // are used and require substitution.
-                        if is_used && subst.needs_subst() {
+                        match (is_used, subst.needs_subst()) {
                             // Just in case there are closures or generators within this subst,
                             // recurse.
-                            if subst.super_visit_with(self) {
+                            (true, true) if subst.super_visit_with(self) => {
                                 // Only return when we find a parameter so the remaining substs
                                 // are not skipped.
                                 return true;
                             }
+                            // Confirm that polymorphization replaced the parameter with
+                            // `ty::Param`/`ty::ConstKind::Param`.
+                            (false, true) if cfg!(debug_assertions) => match subst.unpack() {
+                                ty::subst::GenericArgKind::Type(ty) => {
+                                    assert!(matches!(ty.kind, ty::Param(_)))
+                                }
+                                ty::subst::GenericArgKind::Const(ct) => {
+                                    assert!(matches!(ct.val, ty::ConstKind::Param(_)))
+                                }
+                                ty::subst::GenericArgKind::Lifetime(..) => (),
+                            },
+                            _ => {}
                         }
                     }
                     false
diff --git a/src/librustc_mir/monomorphize/polymorphize.rs b/src/librustc_mir/monomorphize/polymorphize.rs
index 562f512c5da..8fc1458f592 100644
--- a/src/librustc_mir/monomorphize/polymorphize.rs
+++ b/src/librustc_mir/monomorphize/polymorphize.rs
@@ -28,7 +28,7 @@ pub fn provide(providers: &mut Providers) {
 /// Determine which generic parameters are used by the function/method/closure represented by
 /// `def_id`. Returns a bitset where bits representing unused parameters are set (`is_empty`
 /// indicates all parameters are used).
-fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
+fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
     debug!("unused_generic_params({:?})", def_id);
 
     if !tcx.sess.opts.debugging_opts.polymorphize {
@@ -36,6 +36,13 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
         return FiniteBitSet::new_empty();
     }
 
+    // Polymorphization results are stored in cross-crate metadata only when there are unused
+    // parameters, so assume that non-local items must have only used parameters (else this query
+    // would not be invoked, and the cross-crate metadata used instead).
+    if !def_id.is_local() {
+        return FiniteBitSet::new_empty();
+    }
+
     let generics = tcx.generics_of(def_id);
     debug!("unused_generic_params: generics={:?}", generics);
 
@@ -53,7 +60,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u64> {
     // Create a bitset with N rightmost ones for each parameter.
     let generics_count: u32 =
         generics.count().try_into().expect("more generic parameters than can fit into a `u32`");
-    let mut unused_parameters = FiniteBitSet::<u64>::new_empty();
+    let mut unused_parameters = FiniteBitSet::<u32>::new_empty();
     unused_parameters.set_range(0..generics_count);
     debug!("unused_generic_params: (start) unused_parameters={:?}", unused_parameters);
     mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters);
@@ -84,7 +91,7 @@ fn mark_used_by_default_parameters<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     generics: &'tcx ty::Generics,
-    unused_parameters: &mut FiniteBitSet<u64>,
+    unused_parameters: &mut FiniteBitSet<u32>,
 ) {
     if !tcx.is_trait(def_id) && (tcx.is_closure(def_id) || tcx.type_of(def_id).is_generator()) {
         for param in &generics.params {
@@ -110,11 +117,11 @@ fn mark_used_by_default_parameters<'tcx>(
 fn mark_used_by_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    unused_parameters: &mut FiniteBitSet<u64>,
+    unused_parameters: &mut FiniteBitSet<u32>,
 ) {
     let def_id = tcx.closure_base_def_id(def_id);
 
-    let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u64>, self_ty: Ty<'tcx>| {
+    let is_self_ty_used = |unused_parameters: &mut FiniteBitSet<u32>, self_ty: Ty<'tcx>| {
         debug!("unused_generic_params: self_ty={:?}", self_ty);
         if let ty::Param(param) = self_ty.kind {
             !unused_parameters.contains(param.index).unwrap_or(false)
@@ -123,7 +130,7 @@ fn mark_used_by_predicates<'tcx>(
         }
     };
 
-    let mark_ty = |unused_parameters: &mut FiniteBitSet<u64>, ty: Ty<'tcx>| {
+    let mark_ty = |unused_parameters: &mut FiniteBitSet<u32>, ty: Ty<'tcx>| {
         let mut vis = UsedGenericParametersVisitor { tcx, def_id, unused_parameters };
         ty.visit_with(&mut vis);
     };
@@ -159,7 +166,7 @@ fn emit_unused_generic_params_error<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     generics: &'tcx ty::Generics,
-    unused_parameters: &FiniteBitSet<u64>,
+    unused_parameters: &FiniteBitSet<u32>,
 ) {
     debug!("emit_unused_generic_params_error: def_id={:?}", def_id);
     let base_def_id = tcx.closure_base_def_id(def_id);
@@ -195,7 +202,7 @@ fn emit_unused_generic_params_error<'tcx>(
 struct UsedGenericParametersVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    unused_parameters: &'a mut FiniteBitSet<u64>,
+    unused_parameters: &'a mut FiniteBitSet<u32>,
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {