mir: use attribute over -Z polymorphize-errors
This commit replaces the `-Z polymorphize-errors` debugging flag with a `#[rustc_polymorphize_error]` attribute for use on functions. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
5ce29d3d6f
commit
b1f8bd6356
21 changed files with 125 additions and 76 deletions
|
@ -568,6 +568,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
),
|
||||
rustc_attr!(TEST, rustc_synthetic, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_symbol_name, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_polymorphize_error, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_def_path, AssumedUsed, template!(Word)),
|
||||
rustc_attr!(TEST, rustc_mir, AssumedUsed, template!(List: "arg1, arg2, ...")),
|
||||
rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)),
|
||||
|
|
|
@ -16,6 +16,7 @@ use rustc_middle::ty::{
|
|||
query::Providers,
|
||||
Const, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_span::symbol::sym;
|
||||
use std::convert::TryInto;
|
||||
|
||||
/// Provide implementations of queries relating to polymorphization analysis.
|
||||
|
@ -77,7 +78,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> u64 {
|
|||
|
||||
// Emit errors for debugging and testing if enabled.
|
||||
let is_full = unused_parameters == 0;
|
||||
if tcx.sess.opts.debugging_opts.polymorphize_errors && !is_full {
|
||||
if !is_full {
|
||||
emit_unused_generic_params_error(tcx, def_id, generics, unused_parameters);
|
||||
}
|
||||
|
||||
|
@ -169,8 +170,8 @@ fn mark_used_by_predicates<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, used_paramete
|
|||
}
|
||||
}
|
||||
|
||||
/// Emit an error for the function represented by `def_id`, labelling each generic parameter which
|
||||
/// was unused.
|
||||
/// Emit errors for the function annotated by `#[rustc_polymorphize_error]`, labelling each generic
|
||||
/// parameter which was unused.
|
||||
fn emit_unused_generic_params_error<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
|
@ -178,7 +179,8 @@ fn emit_unused_generic_params_error<'tcx>(
|
|||
unused_parameters: u64,
|
||||
) {
|
||||
debug!("emit_unused_generic_params_error: def_id={:?}", def_id);
|
||||
if !def_id.is_local() {
|
||||
let base_def_id = tcx.closure_base_def_id(def_id);
|
||||
if !tcx.get_attrs(base_def_id).iter().any(|a| a.check_name(sym::rustc_polymorphize_error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -951,8 +951,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
"enable polonius-based borrow-checker (default: no)"),
|
||||
polymorphize: bool = (true, parse_bool, [TRACKED],
|
||||
"perform polymorphization analysis"),
|
||||
polymorphize_errors: bool = (false, parse_bool, [TRACKED],
|
||||
"emit errors from polymorphization analysis for debugging"),
|
||||
pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED],
|
||||
"a single extra argument to prepend the linker invocation (can be used several times)"),
|
||||
pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
|
||||
|
|
|
@ -921,6 +921,7 @@ symbols! {
|
|||
rustc_peek_liveness,
|
||||
rustc_peek_maybe_init,
|
||||
rustc_peek_maybe_uninit,
|
||||
rustc_polymorphize_error,
|
||||
rustc_private,
|
||||
rustc_proc_macro_decls,
|
||||
rustc_promotable,
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(const_generics)]
|
||||
#![feature(const_generics, rustc_attrs)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
// This test checks that the polymorphization analysis correctly detects unused const
|
||||
// parameters in closures.
|
||||
|
||||
// Function doesn't have any generic parameters to be unused.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn no_parameters() {
|
||||
let _ = || {};
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in parent and closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused<const T: usize>() -> usize {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let add_one = |x: usize| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in closure, but not in parent.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_parent<const T: usize>() -> usize {
|
||||
let x: usize = T;
|
||||
let add_one = |x: usize| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
x + add_one(3)
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding<const T: usize>() -> usize {
|
||||
let x = || {
|
||||
let y: usize = T;
|
||||
|
@ -38,14 +41,16 @@ pub fn used_binding<const T: usize>() -> usize {
|
|||
}
|
||||
|
||||
// Closure uses a value as an upvar, which used the generic parameter.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_upvar<const T: usize>() -> usize {
|
||||
let x: usize = T;
|
||||
let y = || x;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
y()
|
||||
}
|
||||
|
||||
// Closure uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs<const T: usize>() -> usize {
|
||||
let x = || unused::<T>();
|
||||
x()
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/closures.rs:3:12
|
||||
--> $DIR/closures.rs:2:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
LL | #![feature(const_generics, rustc_attrs)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:17:19
|
||||
--> $DIR/closures.rs:18:19
|
||||
|
|
||||
LL | pub fn unused<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
|
@ -17,13 +17,13 @@ LL | let add_one = |x: usize| x + 1;
|
|||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:15:8
|
||||
--> $DIR/closures.rs:16:8
|
||||
|
|
||||
LL | pub fn unused<const T: usize>() -> usize {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:25:19
|
||||
--> $DIR/closures.rs:27:19
|
||||
|
|
||||
LL | pub fn used_parent<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
|
@ -32,7 +32,7 @@ LL | let add_one = |x: usize| x + 1;
|
|||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:43:13
|
||||
--> $DIR/closures.rs:47:13
|
||||
|
|
||||
LL | pub fn unused_upvar<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(const_generics)]
|
||||
#![feature(const_generics, rustc_attrs)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
// This test checks that the polymorphization analysis correctly detects unused const
|
||||
// parameters in functions.
|
||||
|
||||
// Function doesn't have any generic parameters to be unused.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn no_parameters() {}
|
||||
|
||||
// Function has an unused generic parameter.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused<const T: usize>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding<const T: usize>() -> usize {
|
||||
let x: usize = T;
|
||||
x
|
||||
}
|
||||
|
||||
// Function uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs<const T: usize>() {
|
||||
unused::<T>()
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/functions.rs:3:12
|
||||
--> $DIR/functions.rs:2:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
LL | #![feature(const_generics, rustc_attrs)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/functions.rs:13:8
|
||||
--> $DIR/functions.rs:14:8
|
||||
|
|
||||
LL | pub fn unused<const T: usize>() {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(const_generics, generators, generator_trait)]
|
||||
#![feature(const_generics, generators, generator_trait, rustc_attrs)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
use std::marker::Unpin;
|
||||
|
@ -30,6 +29,7 @@ where
|
|||
|
||||
// This test checks that the polymorphization analysis functions on generators.
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
|| {
|
||||
|
@ -39,6 +39,7 @@ pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_type_in_yield<Y: Default>() -> impl Generator<(), Yield = Y, Return = u32> + Unpin {
|
||||
|| {
|
||||
yield Y::default();
|
||||
|
@ -46,6 +47,7 @@ pub fn used_type_in_yield<Y: Default>() -> impl Generator<(), Yield = Y, Return
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_type_in_return<R: Default>() -> impl Generator<(), Yield = u32, Return = R> + Unpin {
|
||||
|| {
|
||||
yield 3;
|
||||
|
@ -53,6 +55,7 @@ pub fn used_type_in_return<R: Default>() -> impl Generator<(), Yield = u32, Retu
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
|| {
|
||||
|
@ -62,6 +65,7 @@ pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return =
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_const_in_yield<const Y: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin
|
||||
{
|
||||
|| {
|
||||
|
@ -70,6 +74,7 @@ pub fn used_const_in_yield<const Y: u32>() -> impl Generator<(), Yield = u32, Re
|
|||
}
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_const_in_return<const R: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin
|
||||
{
|
||||
|| {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/generators.rs:3:12
|
||||
--> $DIR/generators.rs:2:12
|
||||
|
|
||||
LL | #![feature(const_generics, generators, generator_trait)]
|
||||
LL | #![feature(const_generics, generators, generator_trait, rustc_attrs)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
@ -27,7 +27,7 @@ LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> +
|
|||
| ^^^^^^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/generators.rs:58:5
|
||||
--> $DIR/generators.rs:61:5
|
||||
|
|
||||
LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
|
||||
| - generic parameter `T` is unused
|
||||
|
@ -40,7 +40,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/generators.rs:56:8
|
||||
--> $DIR/generators.rs:59:8
|
||||
|
|
||||
LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
|
||||
| ^^^^^^^^^^^^ - generic parameter `T` is unused
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// This test checks that the polymorphization analysis doesn't break when the
|
||||
// function/closure doesn't just have generic parameters.
|
||||
|
||||
// Function has an unused generic parameter.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused<'a, T>(_: &'a u32) {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used<'a, T: Default>(_: &'a u32) -> u32 {
|
||||
let _: T = Default::default();
|
||||
let add_one = |x: u32| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: item has unused generic parameters
|
||||
--> $DIR/lifetimes.rs:8:8
|
||||
--> $DIR/lifetimes.rs:9:8
|
||||
|
|
||||
LL | pub fn unused<'a, T>(_: &'a u32) {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/lifetimes.rs:14:19
|
||||
--> $DIR/lifetimes.rs:16:19
|
||||
|
|
||||
LL | pub fn used<'a, T: Default>(_: &'a u32) -> u32 {
|
||||
| - generic parameter `T` is unused
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// This test checks that `T` is considered used in `foo`, because it is used in a predicate for
|
||||
// `I`, which is used.
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
fn bar<I>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
fn foo<I, T>(_: I)
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: item has unused generic parameters
|
||||
--> $DIR/predicates.rs:7:4
|
||||
--> $DIR/predicates.rs:8:4
|
||||
|
|
||||
LL | fn bar<I>() {
|
||||
| ^^^ - generic parameter `I` is unused
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// build-pass
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// This test checks that the analysis doesn't panic when there are >64 generic parameters, but
|
||||
// instead considers those parameters used.
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
fn bar<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, AA,
|
||||
AB, AC, AD, AE, AF, AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU, AV, AW,
|
||||
AX, AY, AZ, BA, BB, BC, BD, BE, BF, BG, BH, BI, BJ, BK, BL>()
|
||||
|
|
|
@ -1,31 +1,36 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(stmt_expr_attributes, rustc_attrs)]
|
||||
|
||||
// This test checks that the polymorphization analysis correctly detects unused type
|
||||
// parameters in closures.
|
||||
|
||||
// Function doesn't have any generic parameters to be unused.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn no_parameters() {
|
||||
let _ = || {};
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in parent and closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused<T>() -> u32 {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
|
||||
let add_one = |x: u32| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in closure, but not in parent.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_parent<T: Default>() -> u32 {
|
||||
let _: T = Default::default();
|
||||
let add_one = |x: u32| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding_value<T: Default>() -> T {
|
||||
let x = || {
|
||||
let y: T = Default::default();
|
||||
|
@ -36,6 +41,7 @@ pub fn used_binding_value<T: Default>() -> T {
|
|||
}
|
||||
|
||||
// Function uses generic parameter in generic of a binding in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding_generic<T>() -> Option<T> {
|
||||
let x = || {
|
||||
let y: Option<T> = None;
|
||||
|
@ -46,26 +52,32 @@ pub fn used_binding_generic<T>() -> Option<T> {
|
|||
}
|
||||
|
||||
// Function and closure uses generic parameter in argument.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_argument<T>(t: T) -> u32 {
|
||||
let x = |_: T| 3;
|
||||
x(t)
|
||||
}
|
||||
|
||||
// Closure uses generic parameter in argument.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_argument_closure<T: Default>() -> u32 {
|
||||
let t: T = Default::default();
|
||||
|
||||
let x = |_: T| 3;
|
||||
x(t)
|
||||
}
|
||||
|
||||
// Closure uses generic parameter as upvar.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_upvar<T: Default>() -> T {
|
||||
let x: T = Default::default();
|
||||
|
||||
let y = || x;
|
||||
y()
|
||||
}
|
||||
|
||||
// Closure uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs<T>() -> u32 {
|
||||
let x = || unused::<T>();
|
||||
x()
|
||||
|
@ -75,14 +87,16 @@ struct Foo<F>(F);
|
|||
|
||||
impl<F: Default> Foo<F> {
|
||||
// Function has an unused generic parameter from impl and fn.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_all<G: Default>() -> u32 {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let add_one = |x: u32| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
// Function uses generic parameter from impl and fn in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_both<G: Default>() -> u32 {
|
||||
let add_one = |x: u32| {
|
||||
let _: F = Default::default();
|
||||
|
@ -94,10 +108,11 @@ impl<F: Default> Foo<F> {
|
|||
}
|
||||
|
||||
// Function uses generic parameter from fn in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_fn<G: Default>() -> u32 {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let add_one = |x: u32| {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let _: G = Default::default();
|
||||
x + 1
|
||||
};
|
||||
|
@ -106,10 +121,11 @@ impl<F: Default> Foo<F> {
|
|||
}
|
||||
|
||||
// Function uses generic parameter from impl in closure.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_impl<G: Default>() -> u32 {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let add_one = |x: u32| {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let _: F = Default::default();
|
||||
x + 1
|
||||
};
|
||||
|
@ -118,6 +134,7 @@ impl<F: Default> Foo<F> {
|
|||
}
|
||||
|
||||
// Closure uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs() -> u32 {
|
||||
let x = || unused::<F>();
|
||||
x()
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:15:19
|
||||
--> $DIR/closures.rs:18:19
|
||||
|
|
||||
LL | pub fn unused<T>() -> u32 {
|
||||
| - generic parameter `T` is unused
|
||||
LL |
|
||||
...
|
||||
LL | let add_one = |x: u32| x + 1;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:13:8
|
||||
--> $DIR/closures.rs:15:8
|
||||
|
|
||||
LL | pub fn unused<T>() -> u32 {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:23:19
|
||||
--> $DIR/closures.rs:27:19
|
||||
|
|
||||
LL | pub fn used_parent<T: Default>() -> u32 {
|
||||
| - generic parameter `T` is unused
|
||||
|
@ -23,11 +23,11 @@ LL | let add_one = |x: u32| x + 1;
|
|||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:80:23
|
||||
--> $DIR/closures.rs:93:23
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
LL | // Function has an unused generic parameter from impl and fn.
|
||||
...
|
||||
LL | pub fn unused_all<G: Default>() -> u32 {
|
||||
| - generic parameter `G` is unused
|
||||
LL |
|
||||
|
@ -35,16 +35,16 @@ LL | let add_one = |x: u32| x + 1;
|
|||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:78:12
|
||||
--> $DIR/closures.rs:91:12
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
LL | // Function has an unused generic parameter from impl and fn.
|
||||
...
|
||||
LL | pub fn unused_all<G: Default>() -> u32 {
|
||||
| ^^^^^^^^^^ - generic parameter `G` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:111:23
|
||||
--> $DIR/closures.rs:127:23
|
||||
|
|
||||
LL | pub fn used_impl<G: Default>() -> u32 {
|
||||
| - generic parameter `G` is unused
|
||||
|
@ -58,13 +58,13 @@ LL | | };
|
|||
| |_________^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:109:12
|
||||
--> $DIR/closures.rs:125:12
|
||||
|
|
||||
LL | pub fn used_impl<G: Default>() -> u32 {
|
||||
| ^^^^^^^^^ - generic parameter `G` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:99:23
|
||||
--> $DIR/closures.rs:114:23
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
|
@ -78,7 +78,7 @@ LL | | };
|
|||
| |_________^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:97:12
|
||||
--> $DIR/closures.rs:112:12
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
|
|
|
@ -1,32 +1,37 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// This test checks that the polymorphization analysis correctly detects unused type
|
||||
// parameters in functions.
|
||||
|
||||
// Function doesn't have any generic parameters to be unused.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn no_parameters() {}
|
||||
|
||||
// Function has an unused generic parameter.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused<T>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding_value<T: Default>() {
|
||||
let _: T = Default::default();
|
||||
}
|
||||
|
||||
// Function uses generic parameter in generic of a binding.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_binding_generic<T>() {
|
||||
let _: Option<T> = None;
|
||||
}
|
||||
|
||||
// Function uses generic parameter in argument.
|
||||
pub fn used_argument<T>(_: T) {
|
||||
}
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_argument<T>(_: T) {}
|
||||
|
||||
// Function uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs<T>() {
|
||||
unused::<T>()
|
||||
}
|
||||
|
@ -35,33 +40,39 @@ struct Foo<F>(F);
|
|||
|
||||
impl<F: Default> Foo<F> {
|
||||
// Function has an unused generic parameter from impl.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_impl() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter from impl and fn.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn unused_both<G: Default>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
// Function uses generic parameter from impl.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_impl() {
|
||||
let _: F = Default::default();
|
||||
}
|
||||
|
||||
// Function uses generic parameter from impl.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_fn<G: Default>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let _: G = Default::default();
|
||||
}
|
||||
|
||||
// Function uses generic parameter from impl.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_both<G: Default>() {
|
||||
let _: F = Default::default();
|
||||
let _: G = Default::default();
|
||||
}
|
||||
|
||||
// Function uses generic parameter in substitutions to another function.
|
||||
#[rustc_polymorphize_error]
|
||||
pub fn used_substs() {
|
||||
unused::<F>()
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
error: item has unused generic parameters
|
||||
--> $DIR/functions.rs:11:8
|
||||
--> $DIR/functions.rs:13:8
|
||||
|
|
||||
LL | pub fn unused<T>() {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/functions.rs:38:12
|
||||
--> $DIR/functions.rs:44:12
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
LL | // Function has an unused generic parameter from impl.
|
||||
...
|
||||
LL | pub fn unused_impl() {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/functions.rs:43:12
|
||||
--> $DIR/functions.rs:50:12
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
|
@ -23,7 +23,7 @@ LL | pub fn unused_both<G: Default>() {
|
|||
| ^^^^^^^^^^^ - generic parameter `G` is unused
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/functions.rs:53:12
|
||||
--> $DIR/functions.rs:62:12
|
||||
|
|
||||
LL | impl<F: Default> Foo<F> {
|
||||
| - generic parameter `F` is unused
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(fn_traits, unboxed_closures)]
|
||||
#![feature(fn_traits, rustc_attrs, unboxed_closures)]
|
||||
|
||||
// This test checks that the polymorphization analysis considers a closure
|
||||
// as using all generic parameters if it does an unsizing cast.
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
fn foo<T: Default>() {
|
||||
let _: T = Default::default();
|
||||
(|| Box::new(|| {}) as Box<dyn Fn()>)();
|
||||
|
@ -12,6 +12,7 @@ fn foo<T: Default>() {
|
|||
//~^^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
#[rustc_polymorphize_error]
|
||||
fn foo2<T: Default>() {
|
||||
let _: T = Default::default();
|
||||
(|| {
|
||||
|
|
|
@ -17,7 +17,7 @@ LL | (|| Box::new(|| {}) as Box<dyn Fn()>)();
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/unsized_cast.rs:19:15
|
||||
--> $DIR/unsized_cast.rs:20:15
|
||||
|
|
||||
LL | fn foo2<T: Default>() {
|
||||
| - generic parameter `T` is unused
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue