Skip to content

Commit 6e0c404

Browse files
authored
Rollup merge of #106648 - Nilstrieb:poly-cleanup, r=compiler-errors
Polymorphization cleanup Split out of #106233 Use a newtype instead of a bitset directly. This makes the code way easier to read and easier to adapt for future changes.
2 parents c962b07 + a4b859e commit 6e0c404

File tree

10 files changed

+66
-79
lines changed

10 files changed

+66
-79
lines changed

compiler/rustc_const_eval/src/interpret/util.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,11 @@ where
4040
let index = index
4141
.try_into()
4242
.expect("more generic parameters than can fit into a `u32`");
43-
let is_used = unused_params.contains(index).map_or(true, |unused| !unused);
4443
// Only recurse when generic parameters in fns, closures and generators
4544
// are used and require substitution.
4645
// Just in case there are closures or generators within this subst,
4746
// recurse.
48-
if is_used && subst.needs_subst() {
47+
if unused_params.is_used(index) && subst.needs_subst() {
4948
return subst.visit_with(self);
5049
}
5150
}

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14291429
let instance =
14301430
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
14311431
let unused = tcx.unused_generic_params(instance);
1432-
if !unused.is_empty() {
1432+
if !unused.all_used() {
14331433
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
14341434
}
14351435
}

compiler/rustc_metadata/src/rmeta/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::def::{CtorKind, DefKind};
1313
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
1414
use rustc_hir::definitions::DefKey;
1515
use rustc_hir::lang_items::LangItem;
16-
use rustc_index::bit_set::{BitSet, FiniteBitSet};
16+
use rustc_index::bit_set::BitSet;
1717
use rustc_index::vec::IndexVec;
1818
use rustc_middle::metadata::ModChild;
1919
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
@@ -22,7 +22,7 @@ use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
2222
use rustc_middle::mir;
2323
use rustc_middle::ty::fast_reject::SimplifiedType;
2424
use rustc_middle::ty::query::Providers;
25-
use rustc_middle::ty::{self, ReprOptions, Ty};
25+
use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams};
2626
use rustc_middle::ty::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
2727
use rustc_serialize::opaque::FileEncoder;
2828
use rustc_session::config::SymbolManglingVersion;
@@ -384,7 +384,7 @@ define_tables! {
384384
trait_item_def_id: Table<DefIndex, RawDefId>,
385385
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
386386
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
387-
unused_generic_params: Table<DefIndex, LazyValue<FiniteBitSet<u32>>>,
387+
unused_generic_params: Table<DefIndex, LazyValue<UnusedGenericParams>>,
388388
params_in_repr: Table<DefIndex, LazyValue<BitSet<u32>>>,
389389
repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
390390
// `def_keys` and `def_path_hashes` represent a lazy version of a

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,7 @@ rustc_queries! {
18391839
desc { "getting codegen unit `{sym}`" }
18401840
}
18411841

1842-
query unused_generic_params(key: ty::InstanceDef<'tcx>) -> FiniteBitSet<u32> {
1842+
query unused_generic_params(key: ty::InstanceDef<'tcx>) -> UnusedGenericParams {
18431843
cache_on_disk_if { key.def_id().is_local() }
18441844
desc {
18451845
|tcx| "determining which generic parameters are unused by `{}`",

compiler/rustc_middle/src/ty/instance.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_errors::ErrorGuaranteed;
66
use rustc_hir::def::Namespace;
77
use rustc_hir::def_id::{CrateNum, DefId};
88
use rustc_hir::lang_items::LangItem;
9+
use rustc_index::bit_set::FiniteBitSet;
910
use rustc_macros::HashStable;
1011
use rustc_middle::ty::normalize_erasing_regions::NormalizationError;
1112
use rustc_span::Symbol;
@@ -711,7 +712,7 @@ fn polymorphize<'tcx>(
711712
}
712713

713714
InternalSubsts::for_item(tcx, def_id, |param, _| {
714-
let is_unused = unused.contains(param.index).unwrap_or(false);
715+
let is_unused = unused.is_unused(param.index);
715716
debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);
716717
match param.kind {
717718
// Upvar case: If parameter is a type parameter..
@@ -733,7 +734,7 @@ fn polymorphize<'tcx>(
733734
// Simple case: If parameter is a const or type parameter..
734735
ty::GenericParamDefKind::Const { .. } | ty::GenericParamDefKind::Type { .. } if
735736
// ..and is within range and unused..
736-
unused.contains(param.index).unwrap_or(false) =>
737+
unused.is_unused(param.index) =>
737738
// ..then use the identity for this parameter.
738739
tcx.mk_param_from_def(param),
739740

@@ -774,3 +775,36 @@ fn needs_fn_once_adapter_shim(
774775
(ty::ClosureKind::FnMut | ty::ClosureKind::FnOnce, _) => Err(()),
775776
}
776777
}
778+
779+
// Set bits represent unused generic parameters.
780+
// An empty set indicates that all parameters are used.
781+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Decodable, Encodable, HashStable)]
782+
pub struct UnusedGenericParams(FiniteBitSet<u32>);
783+
784+
impl UnusedGenericParams {
785+
pub fn new_all_unused(amount: u32) -> Self {
786+
let mut bitset = FiniteBitSet::new_empty();
787+
bitset.set_range(0..amount);
788+
Self(bitset)
789+
}
790+
791+
pub fn new_all_used() -> Self {
792+
Self(FiniteBitSet::new_empty())
793+
}
794+
795+
pub fn mark_used(&mut self, idx: u32) {
796+
self.0.clear(idx);
797+
}
798+
799+
pub fn is_unused(&self, idx: u32) -> bool {
800+
self.0.contains(idx).unwrap_or(false)
801+
}
802+
803+
pub fn is_used(&self, idx: u32) -> bool {
804+
!self.is_unused(idx)
805+
}
806+
807+
pub fn all_used(&self) -> bool {
808+
self.0.is_empty()
809+
}
810+
}

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub use self::context::{
8686
tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, OnDiskCache, TyCtxt,
8787
TyCtxtFeed,
8888
};
89-
pub use self::instance::{Instance, InstanceDef, ShortInstance};
89+
pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams};
9090
pub use self::list::List;
9191
pub use self::parameterized::ParameterizedOverTcx;
9292
pub use self::rvalue_scopes::RvalueScopes;

compiler/rustc_middle/src/ty/parameterized.rs

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ trivially_parameterized_over_tcx! {
6060
ty::ImplPolarity,
6161
ty::ReprOptions,
6262
ty::TraitDef,
63+
ty::UnusedGenericParams,
6364
ty::Visibility<DefIndex>,
6465
ty::adjustment::CoerceUnsizedInfo,
6566
ty::fast_reject::SimplifiedType,

compiler/rustc_middle/src/ty/query.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::ty::layout::TyAndLayout;
3434
use crate::ty::subst::{GenericArg, SubstsRef};
3535
use crate::ty::util::AlwaysRequiresDrop;
3636
use crate::ty::GeneratorDiagnosticData;
37-
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
37+
use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
3838
use rustc_ast as ast;
3939
use rustc_ast::expand::allocator::AllocatorKind;
4040
use rustc_attr as attr;
@@ -50,7 +50,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
5050
use rustc_hir::hir_id::OwnerId;
5151
use rustc_hir::lang_items::{LangItem, LanguageItems};
5252
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
53-
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
53+
use rustc_index::vec::IndexVec;
5454
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
5555
use rustc_session::cstore::{CrateDepKind, CrateSource};
5656
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};

compiler/rustc_monomorphize/src/errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ pub struct TypeLengthLimit {
3232
pub type_length: usize,
3333
}
3434

35-
pub struct UnusedGenericParams {
35+
pub struct UnusedGenericParamsHint {
3636
pub span: Span,
3737
pub param_spans: Vec<Span>,
3838
pub param_names: Vec<String>,
3939
}
4040

41-
impl IntoDiagnostic<'_> for UnusedGenericParams {
41+
impl IntoDiagnostic<'_> for UnusedGenericParamsHint {
4242
#[track_caller]
4343
fn into_diagnostic(
4444
self,

compiler/rustc_monomorphize/src/polymorphize.rs

+18-65
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//! for their size, offset of a field, etc.).
77
88
use rustc_hir::{def::DefKind, def_id::DefId, ConstContext};
9-
use rustc_index::bit_set::FiniteBitSet;
109
use rustc_middle::mir::{
1110
self,
1211
visit::{TyContext, Visitor},
@@ -17,12 +16,12 @@ use rustc_middle::ty::{
1716
query::Providers,
1817
subst::SubstsRef,
1918
visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
20-
Const, Ty, TyCtxt,
19+
Const, Ty, TyCtxt, UnusedGenericParams,
2120
};
2221
use rustc_span::symbol::sym;
2322
use std::ops::ControlFlow;
2423

25-
use crate::errors::UnusedGenericParams;
24+
use crate::errors::UnusedGenericParamsHint;
2625

2726
/// Provide implementations of queries relating to polymorphization analysis.
2827
pub fn provide(providers: &mut Providers) {
@@ -36,31 +35,30 @@ pub fn provide(providers: &mut Providers) {
3635
fn unused_generic_params<'tcx>(
3736
tcx: TyCtxt<'tcx>,
3837
instance: ty::InstanceDef<'tcx>,
39-
) -> FiniteBitSet<u32> {
38+
) -> UnusedGenericParams {
4039
if !tcx.sess.opts.unstable_opts.polymorphize {
4140
// If polymorphization disabled, then all parameters are used.
42-
return FiniteBitSet::new_empty();
41+
return UnusedGenericParams::new_all_used();
4342
}
4443

4544
let def_id = instance.def_id();
4645
// Exit early if this instance should not be polymorphized.
4746
if !should_polymorphize(tcx, def_id, instance) {
48-
return FiniteBitSet::new_empty();
47+
return UnusedGenericParams::new_all_used();
4948
}
5049

5150
let generics = tcx.generics_of(def_id);
5251
debug!(?generics);
5352

5453
// Exit early when there are no parameters to be unused.
5554
if generics.count() == 0 {
56-
return FiniteBitSet::new_empty();
55+
return UnusedGenericParams::new_all_used();
5756
}
5857

5958
// Create a bitset with N rightmost ones for each parameter.
6059
let generics_count: u32 =
6160
generics.count().try_into().expect("more generic parameters than can fit into a `u32`");
62-
let mut unused_parameters = FiniteBitSet::<u32>::new_empty();
63-
unused_parameters.set_range(0..generics_count);
61+
let mut unused_parameters = UnusedGenericParams::new_all_unused(generics_count);
6462
debug!(?unused_parameters, "(start)");
6563

6664
mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters);
@@ -78,7 +76,7 @@ fn unused_generic_params<'tcx>(
7876
debug!(?unused_parameters, "(end)");
7977

8078
// Emit errors for debugging and testing if enabled.
81-
if !unused_parameters.is_empty() {
79+
if !unused_parameters.all_used() {
8280
emit_unused_generic_params_error(tcx, def_id, generics, &unused_parameters);
8381
}
8482

@@ -136,13 +134,13 @@ fn mark_used_by_default_parameters<'tcx>(
136134
tcx: TyCtxt<'tcx>,
137135
def_id: DefId,
138136
generics: &'tcx ty::Generics,
139-
unused_parameters: &mut FiniteBitSet<u32>,
137+
unused_parameters: &mut UnusedGenericParams,
140138
) {
141139
match tcx.def_kind(def_id) {
142140
DefKind::Closure | DefKind::Generator => {
143141
for param in &generics.params {
144142
debug!(?param, "(closure/gen)");
145-
unused_parameters.clear(param.index);
143+
unused_parameters.mark_used(param.index);
146144
}
147145
}
148146
DefKind::Mod
@@ -178,7 +176,7 @@ fn mark_used_by_default_parameters<'tcx>(
178176
for param in &generics.params {
179177
debug!(?param, "(other)");
180178
if let ty::GenericParamDefKind::Lifetime = param.kind {
181-
unused_parameters.clear(param.index);
179+
unused_parameters.mark_used(param.index);
182180
}
183181
}
184182
}
@@ -196,7 +194,7 @@ fn emit_unused_generic_params_error<'tcx>(
196194
tcx: TyCtxt<'tcx>,
197195
def_id: DefId,
198196
generics: &'tcx ty::Generics,
199-
unused_parameters: &FiniteBitSet<u32>,
197+
unused_parameters: &UnusedGenericParams,
200198
) {
201199
let base_def_id = tcx.typeck_root_def_id(def_id);
202200
if !tcx.has_attr(base_def_id, sym::rustc_polymorphize_error) {
@@ -213,7 +211,7 @@ fn emit_unused_generic_params_error<'tcx>(
213211
let mut next_generics = Some(generics);
214212
while let Some(generics) = next_generics {
215213
for param in &generics.params {
216-
if unused_parameters.contains(param.index).unwrap_or(false) {
214+
if unused_parameters.is_unused(param.index) {
217215
debug!(?param);
218216
let def_span = tcx.def_span(param.def_id);
219217
param_spans.push(def_span);
@@ -224,14 +222,14 @@ fn emit_unused_generic_params_error<'tcx>(
224222
next_generics = generics.parent.map(|did| tcx.generics_of(did));
225223
}
226224

227-
tcx.sess.emit_err(UnusedGenericParams { span: fn_span, param_spans, param_names });
225+
tcx.sess.emit_err(UnusedGenericParamsHint { span: fn_span, param_spans, param_names });
228226
}
229227

230228
/// Visitor used to aggregate generic parameter uses.
231229
struct MarkUsedGenericParams<'a, 'tcx> {
232230
tcx: TyCtxt<'tcx>,
233231
def_id: DefId,
234-
unused_parameters: &'a mut FiniteBitSet<u32>,
232+
unused_parameters: &'a mut UnusedGenericParams,
235233
}
236234

237235
impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
@@ -244,7 +242,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
244242
debug!(?self.unused_parameters, ?unused);
245243
for (i, arg) in substs.iter().enumerate() {
246244
let i = i.try_into().unwrap();
247-
if !unused.contains(i).unwrap_or(false) {
245+
if unused.is_used(i) {
248246
arg.visit_with(self);
249247
}
250248
}
@@ -308,7 +306,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
308306
match c.kind() {
309307
ty::ConstKind::Param(param) => {
310308
debug!(?param);
311-
self.unused_parameters.clear(param.index);
309+
self.unused_parameters.mark_used(param.index);
312310
ControlFlow::CONTINUE
313311
}
314312
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs })
@@ -342,55 +340,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
342340
}
343341
ty::Param(param) => {
344342
debug!(?param);
345-
self.unused_parameters.clear(param.index);
343+
self.unused_parameters.mark_used(param.index);
346344
ControlFlow::CONTINUE
347345
}
348346
_ => ty.super_visit_with(self),
349347
}
350348
}
351349
}
352-
353-
/// Visitor used to check if a generic parameter is used.
354-
struct HasUsedGenericParams<'a> {
355-
unused_parameters: &'a FiniteBitSet<u32>,
356-
}
357-
358-
impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> {
359-
type BreakTy = ();
360-
361-
#[instrument(level = "debug", skip(self))]
362-
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
363-
if !c.has_non_region_param() {
364-
return ControlFlow::CONTINUE;
365-
}
366-
367-
match c.kind() {
368-
ty::ConstKind::Param(param) => {
369-
if self.unused_parameters.contains(param.index).unwrap_or(false) {
370-
ControlFlow::CONTINUE
371-
} else {
372-
ControlFlow::BREAK
373-
}
374-
}
375-
_ => c.super_visit_with(self),
376-
}
377-
}
378-
379-
#[instrument(level = "debug", skip(self))]
380-
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
381-
if !ty.has_non_region_param() {
382-
return ControlFlow::CONTINUE;
383-
}
384-
385-
match ty.kind() {
386-
ty::Param(param) => {
387-
if self.unused_parameters.contains(param.index).unwrap_or(false) {
388-
ControlFlow::CONTINUE
389-
} else {
390-
ControlFlow::BREAK
391-
}
392-
}
393-
_ => ty.super_visit_with(self),
394-
}
395-
}
396-
}

0 commit comments

Comments
 (0)