summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_monomorphize/src/polymorphize.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_monomorphize/src/polymorphize.rs')
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs98
1 files changed, 25 insertions, 73 deletions
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 650076c22..cf13d4584 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -6,7 +6,6 @@
//! for their size, offset of a field, etc.).
use rustc_hir::{def::DefKind, def_id::DefId, ConstContext};
-use rustc_index::bit_set::FiniteBitSet;
use rustc_middle::mir::{
self,
visit::{TyContext, Visitor},
@@ -17,13 +16,12 @@ use rustc_middle::ty::{
query::Providers,
subst::SubstsRef,
visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
- Const, Ty, TyCtxt,
+ Const, Ty, TyCtxt, UnusedGenericParams,
};
use rustc_span::symbol::sym;
-use std::convert::TryInto;
use std::ops::ControlFlow;
-use crate::errors::UnusedGenericParams;
+use crate::errors::UnusedGenericParamsHint;
/// Provide implementations of queries relating to polymorphization analysis.
pub fn provide(providers: &mut Providers) {
@@ -37,16 +35,16 @@ pub fn provide(providers: &mut Providers) {
fn unused_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
-) -> FiniteBitSet<u32> {
+) -> UnusedGenericParams {
if !tcx.sess.opts.unstable_opts.polymorphize {
// If polymorphization disabled, then all parameters are used.
- return FiniteBitSet::new_empty();
+ return UnusedGenericParams::new_all_used();
}
let def_id = instance.def_id();
// Exit early if this instance should not be polymorphized.
if !should_polymorphize(tcx, def_id, instance) {
- return FiniteBitSet::new_empty();
+ return UnusedGenericParams::new_all_used();
}
let generics = tcx.generics_of(def_id);
@@ -54,14 +52,13 @@ fn unused_generic_params<'tcx>(
// Exit early when there are no parameters to be unused.
if generics.count() == 0 {
- return FiniteBitSet::new_empty();
+ return UnusedGenericParams::new_all_used();
}
// 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::<u32>::new_empty();
- unused_parameters.set_range(0..generics_count);
+ let mut unused_parameters = UnusedGenericParams::new_all_unused(generics_count);
debug!(?unused_parameters, "(start)");
mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters);
@@ -79,7 +76,7 @@ fn unused_generic_params<'tcx>(
debug!(?unused_parameters, "(end)");
// Emit errors for debugging and testing if enabled.
- if !unused_parameters.is_empty() {
+ if !unused_parameters.all_used() {
emit_unused_generic_params_error(tcx, def_id, generics, &unused_parameters);
}
@@ -137,13 +134,13 @@ fn mark_used_by_default_parameters<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
generics: &'tcx ty::Generics,
- unused_parameters: &mut FiniteBitSet<u32>,
+ unused_parameters: &mut UnusedGenericParams,
) {
match tcx.def_kind(def_id) {
DefKind::Closure | DefKind::Generator => {
for param in &generics.params {
debug!(?param, "(closure/gen)");
- unused_parameters.clear(param.index);
+ unused_parameters.mark_used(param.index);
}
}
DefKind::Mod
@@ -179,7 +176,7 @@ fn mark_used_by_default_parameters<'tcx>(
for param in &generics.params {
debug!(?param, "(other)");
if let ty::GenericParamDefKind::Lifetime = param.kind {
- unused_parameters.clear(param.index);
+ unused_parameters.mark_used(param.index);
}
}
}
@@ -197,7 +194,7 @@ fn emit_unused_generic_params_error<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
generics: &'tcx ty::Generics,
- unused_parameters: &FiniteBitSet<u32>,
+ unused_parameters: &UnusedGenericParams,
) {
let base_def_id = tcx.typeck_root_def_id(def_id);
if !tcx.has_attr(base_def_id, sym::rustc_polymorphize_error) {
@@ -214,7 +211,7 @@ fn emit_unused_generic_params_error<'tcx>(
let mut next_generics = Some(generics);
while let Some(generics) = next_generics {
for param in &generics.params {
- if unused_parameters.contains(param.index).unwrap_or(false) {
+ if unused_parameters.is_unused(param.index) {
debug!(?param);
let def_span = tcx.def_span(param.def_id);
param_spans.push(def_span);
@@ -225,14 +222,14 @@ fn emit_unused_generic_params_error<'tcx>(
next_generics = generics.parent.map(|did| tcx.generics_of(did));
}
- tcx.sess.emit_err(UnusedGenericParams { span: fn_span, param_spans, param_names });
+ tcx.sess.emit_err(UnusedGenericParamsHint { span: fn_span, param_spans, param_names });
}
/// Visitor used to aggregate generic parameter uses.
struct MarkUsedGenericParams<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
def_id: DefId,
- unused_parameters: &'a mut FiniteBitSet<u32>,
+ unused_parameters: &'a mut UnusedGenericParams,
}
impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
@@ -245,7 +242,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
debug!(?self.unused_parameters, ?unused);
for (i, arg) in substs.iter().enumerate() {
let i = i.try_into().unwrap();
- if !unused.contains(i).unwrap_or(false) {
+ if unused.is_used(i) {
arg.visit_with(self);
}
}
@@ -303,20 +300,20 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if !c.has_non_region_param() {
- return ControlFlow::CONTINUE;
+ return ControlFlow::Continue(());
}
match c.kind() {
ty::ConstKind::Param(param) => {
debug!(?param);
- self.unused_parameters.clear(param.index);
- ControlFlow::CONTINUE
+ self.unused_parameters.mark_used(param.index);
+ ControlFlow::Continue(())
}
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs })
if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) =>
{
self.visit_child_body(def.did, substs);
- ControlFlow::CONTINUE
+ ControlFlow::Continue(())
}
_ => c.super_visit_with(self),
}
@@ -325,7 +322,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if !ty.has_non_region_param() {
- return ControlFlow::CONTINUE;
+ return ControlFlow::Continue(());
}
match *ty.kind() {
@@ -333,63 +330,18 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
debug!(?def_id);
// Avoid cycle errors with generators.
if def_id == self.def_id {
- return ControlFlow::CONTINUE;
+ return ControlFlow::Continue(());
}
// Consider any generic parameters used by any closures/generators as used in the
// parent.
self.visit_child_body(def_id, substs);
- ControlFlow::CONTINUE
+ ControlFlow::Continue(())
}
ty::Param(param) => {
debug!(?param);
- self.unused_parameters.clear(param.index);
- ControlFlow::CONTINUE
- }
- _ => ty.super_visit_with(self),
- }
- }
-}
-
-/// Visitor used to check if a generic parameter is used.
-struct HasUsedGenericParams<'a> {
- unused_parameters: &'a FiniteBitSet<u32>,
-}
-
-impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> {
- type BreakTy = ();
-
- #[instrument(level = "debug", skip(self))]
- fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
- if !c.has_non_region_param() {
- return ControlFlow::CONTINUE;
- }
-
- match c.kind() {
- ty::ConstKind::Param(param) => {
- if self.unused_parameters.contains(param.index).unwrap_or(false) {
- ControlFlow::CONTINUE
- } else {
- ControlFlow::BREAK
- }
- }
- _ => c.super_visit_with(self),
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
- if !ty.has_non_region_param() {
- return ControlFlow::CONTINUE;
- }
-
- match ty.kind() {
- ty::Param(param) => {
- if self.unused_parameters.contains(param.index).unwrap_or(false) {
- ControlFlow::CONTINUE
- } else {
- ControlFlow::BREAK
- }
+ self.unused_parameters.mark_used(param.index);
+ ControlFlow::Continue(())
}
_ => ty.super_visit_with(self),
}