};
let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters };
vis.visit_body(body);
- debug!(?unused_parameters, "(after visitor)");
-
- mark_used_by_predicates(tcx, def_id, &mut unused_parameters);
debug!(?unused_parameters, "(end)");
// Emit errors for debugging and testing if enabled.
}
}
-/// Search the predicates on used generic parameters for any unused generic parameters, and mark
-/// those as used.
-#[instrument(level = "debug", skip(tcx, def_id))]
-fn mark_used_by_predicates<'tcx>(
- tcx: TyCtxt<'tcx>,
- def_id: DefId,
- unused_parameters: &mut FiniteBitSet<u32>,
-) {
- let def_id = tcx.closure_base_def_id(def_id);
- let predicates = tcx.explicit_predicates_of(def_id);
-
- let mut current_unused_parameters = FiniteBitSet::new_empty();
- // Run to a fixed point to support `where T: Trait<U>, U: Trait<V>`, starting with an empty
- // bit set so that this is skipped if all parameters are already used.
- while current_unused_parameters != *unused_parameters {
- debug!(?current_unused_parameters, ?unused_parameters);
- current_unused_parameters = *unused_parameters;
-
- for (predicate, _) in predicates.predicates {
- // Consider all generic params in a predicate as used if any other parameter in the
- // predicate is used.
- let any_param_used = {
- let mut vis = HasUsedGenericParams { tcx, unused_parameters };
- predicate.visit_with(&mut vis).is_break()
- };
-
- if any_param_used {
- let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters };
- predicate.visit_with(&mut vis);
- }
- }
- }
-
- if let Some(parent) = predicates.parent {
- mark_used_by_predicates(tcx, parent, unused_parameters);
- }
-}
-
/// Emit errors for the function annotated by `#[rustc_polymorphize_error]`, labelling each generic
/// parameter which was unused.
#[instrument(level = "debug", skip(tcx, generics))]
#[rustc_polymorphize_error]
fn foo<I, T>(_: I)
+//~^ ERROR item has unused generic parameters
where
I: Iterator<Item = T>,
{
#[rustc_polymorphize_error]
fn baz<I, T>(_: I)
+//~^ ERROR item has unused generic parameters
where
std::iter::Repeat<I>: Iterator<Item = T>,
{
#[rustc_polymorphize_error]
fn next(&mut self) -> Option<Self::Item> {
self.find(|_| true)
+ //~^ ERROR item has unused generic parameters
}
}
#[rustc_polymorphize_error]
fn quux<A, B, C: Default>() -> usize
+//~^ ERROR item has unused generic parameters
where
A: Baz<B>,
B: Baz<C>,
#[rustc_polymorphize_error]
fn foobar<F, G>() -> usize
+//~^ ERROR item has unused generic parameters
where
(): Foobar<F, G>,
{
+error: item has unused generic parameters
+ --> $DIR/predicates.rs:14:4
+ |
+LL | fn foo<I, T>(_: I)
+ | ^^^ - generic parameter `T` is unused
+
+error: item has unused generic parameters
+ --> $DIR/predicates.rs:23:4
+ |
+LL | fn baz<I, T>(_: I)
+ | ^^^ - generic parameter `T` is unused
+
+error: item has unused generic parameters
+ --> $DIR/predicates.rs:44:19
+ |
+LL | impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E>
+ | - - generic parameter `E` is unused
+ | |
+ | generic parameter `I` is unused
+...
+LL | self.find(|_| true)
+ | ^^^^^^^^
+
+error: item has unused generic parameters
+ --> $DIR/predicates.rs:58:4
+ |
+LL | fn quux<A, B, C: Default>() -> usize
+ | ^^^^ - - generic parameter `B` is unused
+ | |
+ | generic parameter `A` is unused
+
+error: item has unused generic parameters
+ --> $DIR/predicates.rs:75:4
+ |
+LL | fn foobar<F, G>() -> usize
+ | ^^^^^^ - generic parameter `F` is unused
+
error: item has unused generic parameters
--> $DIR/predicates.rs:9:4
|
LL | fn bar<I>() {
| ^^^ - generic parameter `I` is unused
-error: aborting due to previous error
+error: aborting due to 6 previous errors