summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/instance.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/instance.rs')
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs59
1 files changed, 54 insertions, 5 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 586460986..6ac00d16c 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -6,6 +6,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::Namespace;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::lang_items::LangItem;
+use rustc_index::bit_set::FiniteBitSet;
use rustc_macros::HashStable;
use rustc_middle::ty::normalize_erasing_regions::NormalizationError;
use rustc_span::Symbol;
@@ -385,6 +386,21 @@ impl<'tcx> Instance<'tcx> {
)
}
+ pub fn expect_resolve(
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ def_id: DefId,
+ substs: SubstsRef<'tcx>,
+ ) -> Instance<'tcx> {
+ match ty::Instance::resolve(tcx, param_env, def_id, substs) {
+ Ok(Some(instance)) => instance,
+ _ => bug!(
+ "failed to resolve instance for {}",
+ tcx.def_path_str_with_substs(def_id, substs)
+ ),
+ }
+ }
+
// This should be kept up to date with `resolve`.
pub fn resolve_opt_const_arg(
tcx: TyCtxt<'tcx>,
@@ -525,7 +541,7 @@ impl<'tcx> Instance<'tcx> {
pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
let substs = tcx.intern_substs(&[ty.into()]);
- Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap().unwrap()
+ Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs)
}
#[instrument(level = "debug", skip(tcx), ret)]
@@ -696,7 +712,7 @@ fn polymorphize<'tcx>(
}
InternalSubsts::for_item(tcx, def_id, |param, _| {
- let is_unused = unused.contains(param.index).unwrap_or(false);
+ let is_unused = unused.is_unused(param.index);
debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);
match param.kind {
// Upvar case: If parameter is a type parameter..
@@ -718,7 +734,7 @@ fn polymorphize<'tcx>(
// Simple case: 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) =>
+ unused.is_unused(param.index) =>
// ..then use the identity for this parameter.
tcx.mk_param_from_def(param),
@@ -740,14 +756,14 @@ fn needs_fn_once_adapter_shim(
Ok(false)
}
(ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
- // The closure fn `llfn` is a `fn(&self, ...)`. We want a
+ // The closure fn `llfn` is a `fn(&self, ...)`. We want a
// `fn(&mut self, ...)`. In fact, at codegen time, these are
// basically the same thing, so we can just return llfn.
Ok(false)
}
(ty::ClosureKind::Fn | ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
// The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
- // self, ...)`. We want a `fn(self, ...)`. We can produce
+ // self, ...)`. We want a `fn(self, ...)`. We can produce
// this by doing something like:
//
// fn call_once(self, ...) { call_mut(&self, ...) }
@@ -759,3 +775,36 @@ fn needs_fn_once_adapter_shim(
(ty::ClosureKind::FnMut | ty::ClosureKind::FnOnce, _) => Err(()),
}
}
+
+// Set bits represent unused generic parameters.
+// An empty set indicates that all parameters are used.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Decodable, Encodable, HashStable)]
+pub struct UnusedGenericParams(FiniteBitSet<u32>);
+
+impl UnusedGenericParams {
+ pub fn new_all_unused(amount: u32) -> Self {
+ let mut bitset = FiniteBitSet::new_empty();
+ bitset.set_range(0..amount);
+ Self(bitset)
+ }
+
+ pub fn new_all_used() -> Self {
+ Self(FiniteBitSet::new_empty())
+ }
+
+ pub fn mark_used(&mut self, idx: u32) {
+ self.0.clear(idx);
+ }
+
+ pub fn is_unused(&self, idx: u32) -> bool {
+ self.0.contains(idx).unwrap_or(false)
+ }
+
+ pub fn is_used(&self, idx: u32) -> bool {
+ !self.is_unused(idx)
+ }
+
+ pub fn all_used(&self) -> bool {
+ self.0.is_empty()
+ }
+}