1
Fork 0

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:
David Wood 2020-07-16 17:52:23 +01:00
parent 5ce29d3d6f
commit b1f8bd6356
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
21 changed files with 125 additions and 76 deletions

View file

@ -568,6 +568,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
), ),
rustc_attr!(TEST, rustc_synthetic, AssumedUsed, template!(Word)), rustc_attr!(TEST, rustc_synthetic, AssumedUsed, template!(Word)),
rustc_attr!(TEST, rustc_symbol_name, 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_def_path, AssumedUsed, template!(Word)),
rustc_attr!(TEST, rustc_mir, AssumedUsed, template!(List: "arg1, arg2, ...")), rustc_attr!(TEST, rustc_mir, AssumedUsed, template!(List: "arg1, arg2, ...")),
rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)), rustc_attr!(TEST, rustc_dump_program_clauses, AssumedUsed, template!(Word)),

View file

@ -16,6 +16,7 @@ use rustc_middle::ty::{
query::Providers, query::Providers,
Const, Ty, TyCtxt, Const, Ty, TyCtxt,
}; };
use rustc_span::symbol::sym;
use std::convert::TryInto; use std::convert::TryInto;
/// Provide implementations of queries relating to polymorphization analysis. /// 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. // Emit errors for debugging and testing if enabled.
let is_full = unused_parameters == 0; 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); 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 /// Emit errors for the function annotated by `#[rustc_polymorphize_error]`, labelling each generic
/// was unused. /// parameter which was unused.
fn emit_unused_generic_params_error<'tcx>( fn emit_unused_generic_params_error<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
@ -178,7 +179,8 @@ fn emit_unused_generic_params_error<'tcx>(
unused_parameters: u64, unused_parameters: u64,
) { ) {
debug!("emit_unused_generic_params_error: def_id={:?}", def_id); 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; return;
} }

View file

@ -951,8 +951,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"enable polonius-based borrow-checker (default: no)"), "enable polonius-based borrow-checker (default: no)"),
polymorphize: bool = (true, parse_bool, [TRACKED], polymorphize: bool = (true, parse_bool, [TRACKED],
"perform polymorphization analysis"), "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], 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)"), "a single extra argument to prepend the linker invocation (can be used several times)"),
pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED], pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],

View file

@ -921,6 +921,7 @@ symbols! {
rustc_peek_liveness, rustc_peek_liveness,
rustc_peek_maybe_init, rustc_peek_maybe_init,
rustc_peek_maybe_uninit, rustc_peek_maybe_uninit,
rustc_polymorphize_error,
rustc_private, rustc_private,
rustc_proc_macro_decls, rustc_proc_macro_decls,
rustc_promotable, rustc_promotable,

View file

@ -1,33 +1,36 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(const_generics, rustc_attrs)]
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
// This test checks that the polymorphization analysis correctly detects unused const // This test checks that the polymorphization analysis correctly detects unused const
// parameters in closures. // parameters in closures.
// Function doesn't have any generic parameters to be unused. // Function doesn't have any generic parameters to be unused.
#[rustc_polymorphize_error]
pub fn no_parameters() { pub fn no_parameters() {
let _ = || {}; let _ = || {};
} }
// Function has an unused generic parameter in parent and closure. // Function has an unused generic parameter in parent and closure.
#[rustc_polymorphize_error]
pub fn unused<const T: usize>() -> usize { 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; let add_one = |x: usize| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
add_one(3) add_one(3)
} }
// Function has an unused generic parameter in closure, but not in parent. // Function has an unused generic parameter in closure, but not in parent.
#[rustc_polymorphize_error]
pub fn used_parent<const T: usize>() -> usize { pub fn used_parent<const T: usize>() -> usize {
let x: usize = T; let x: usize = T;
let add_one = |x: usize| x + 1; let add_one = |x: usize| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
x + add_one(3) x + add_one(3)
} }
// Function uses generic parameter in value of a binding in closure. // Function uses generic parameter in value of a binding in closure.
#[rustc_polymorphize_error]
pub fn used_binding<const T: usize>() -> usize { pub fn used_binding<const T: usize>() -> usize {
let x = || { let x = || {
let y: usize = T; 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. // Closure uses a value as an upvar, which used the generic parameter.
#[rustc_polymorphize_error]
pub fn unused_upvar<const T: usize>() -> usize { pub fn unused_upvar<const T: usize>() -> usize {
let x: usize = T; let x: usize = T;
let y = || x; let y = || x;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
y() y()
} }
// Closure uses generic parameter in substitutions to another function. // Closure uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs<const T: usize>() -> usize { pub fn used_substs<const T: usize>() -> usize {
let x = || unused::<T>(); let x = || unused::<T>();
x() x()

View file

@ -1,14 +1,14 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes 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: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:17:19 --> $DIR/closures.rs:18:19
| |
LL | pub fn unused<const T: usize>() -> usize { LL | pub fn unused<const T: usize>() -> usize {
| - generic parameter `T` is unused | - generic parameter `T` is unused
@ -17,13 +17,13 @@ LL | let add_one = |x: usize| x + 1;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:15:8 --> $DIR/closures.rs:16:8
| |
LL | pub fn unused<const T: usize>() -> usize { LL | pub fn unused<const T: usize>() -> usize {
| ^^^^^^ - generic parameter `T` is unused | ^^^^^^ - generic parameter `T` is unused
error: item has unused generic parameters 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 { LL | pub fn used_parent<const T: usize>() -> usize {
| - generic parameter `T` is unused | - generic parameter `T` is unused
@ -32,7 +32,7 @@ LL | let add_one = |x: usize| x + 1;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: item has unused generic parameters 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 { LL | pub fn unused_upvar<const T: usize>() -> usize {
| - generic parameter `T` is unused | - generic parameter `T` is unused

View file

@ -1,26 +1,29 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(const_generics, rustc_attrs)]
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
// This test checks that the polymorphization analysis correctly detects unused const // This test checks that the polymorphization analysis correctly detects unused const
// parameters in functions. // parameters in functions.
// Function doesn't have any generic parameters to be unused. // Function doesn't have any generic parameters to be unused.
#[rustc_polymorphize_error]
pub fn no_parameters() {} pub fn no_parameters() {}
// Function has an unused generic parameter. // Function has an unused generic parameter.
#[rustc_polymorphize_error]
pub fn unused<const T: usize>() { 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. // Function uses generic parameter in value of a binding.
#[rustc_polymorphize_error]
pub fn used_binding<const T: usize>() -> usize { pub fn used_binding<const T: usize>() -> usize {
let x: usize = T; let x: usize = T;
x x
} }
// Function uses generic parameter in substitutions to another function. // Function uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs<const T: usize>() { pub fn used_substs<const T: usize>() {
unused::<T>() unused::<T>()
} }

View file

@ -1,14 +1,14 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes 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: `#[warn(incomplete_features)]` on by default
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/functions.rs:13:8 --> $DIR/functions.rs:14:8
| |
LL | pub fn unused<const T: usize>() { LL | pub fn unused<const T: usize>() {
| ^^^^^^ - generic parameter `T` is unused | ^^^^^^ - generic parameter `T` is unused

View file

@ -1,6 +1,5 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(const_generics, generators, generator_trait, rustc_attrs)]
#![feature(const_generics, generators, generator_trait)]
//~^ WARN the feature `const_generics` is incomplete //~^ WARN the feature `const_generics` is incomplete
use std::marker::Unpin; use std::marker::Unpin;
@ -30,6 +29,7 @@ where
// This test checks that the polymorphization analysis functions on generators. // 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 { pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
//~^ ERROR item has unused generic parameters //~^ 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 { pub fn used_type_in_yield<Y: Default>() -> impl Generator<(), Yield = Y, Return = u32> + Unpin {
|| { || {
yield Y::default(); 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 { pub fn used_type_in_return<R: Default>() -> impl Generator<(), Yield = u32, Return = R> + Unpin {
|| { || {
yield 3; 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 { pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
//~^ ERROR item has unused generic parameters //~^ 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 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 pub fn used_const_in_return<const R: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin
{ {
|| { || {

View file

@ -1,7 +1,7 @@
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes 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 = 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 | ^^^^^^^^^^^ - generic parameter `T` is unused
error: item has unused generic parameters 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 { LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
| - generic parameter `T` is unused | - generic parameter `T` is unused
@ -40,7 +40,7 @@ LL | | }
| |_____^ | |_____^
error: item has unused generic parameters 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 { LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Return = u32> + Unpin {
| ^^^^^^^^^^^^ - generic parameter `T` is unused | ^^^^^^^^^^^^ - generic parameter `T` is unused

View file

@ -1,18 +1,20 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(rustc_attrs)]
// This test checks that the polymorphization analysis doesn't break when the // This test checks that the polymorphization analysis doesn't break when the
// function/closure doesn't just have generic parameters. // function/closure doesn't just have generic parameters.
// Function has an unused generic parameter. // Function has an unused generic parameter.
#[rustc_polymorphize_error]
pub fn unused<'a, T>(_: &'a u32) { 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 { pub fn used<'a, T: Default>(_: &'a u32) -> u32 {
let _: T = Default::default(); let _: T = Default::default();
let add_one = |x: u32| x + 1; let add_one = |x: u32| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
add_one(3) add_one(3)
} }

View file

@ -1,11 +1,11 @@
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/lifetimes.rs:8:8 --> $DIR/lifetimes.rs:9:8
| |
LL | pub fn unused<'a, T>(_: &'a u32) { LL | pub fn unused<'a, T>(_: &'a u32) {
| ^^^^^^ - generic parameter `T` is unused | ^^^^^^ - generic parameter `T` is unused
error: item has unused generic parameters 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 { LL | pub fn used<'a, T: Default>(_: &'a u32) -> u32 {
| - generic parameter `T` is unused | - generic parameter `T` is unused

View file

@ -1,13 +1,15 @@
// build-fail // 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 // This test checks that `T` is considered used in `foo`, because it is used in a predicate for
// `I`, which is used. // `I`, which is used.
#[rustc_polymorphize_error]
fn bar<I>() { fn bar<I>() {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
} }
#[rustc_polymorphize_error]
fn foo<I, T>(_: I) fn foo<I, T>(_: I)
where where
I: Iterator<Item = T>, I: Iterator<Item = T>,

View file

@ -1,5 +1,5 @@
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/predicates.rs:7:4 --> $DIR/predicates.rs:8:4
| |
LL | fn bar<I>() { LL | fn bar<I>() {
| ^^^ - generic parameter `I` is unused | ^^^ - generic parameter `I` is unused

View file

@ -1,9 +1,10 @@
// build-pass // 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 // This test checks that the analysis doesn't panic when there are >64 generic parameters, but
// instead considers those parameters used. // 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, 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, 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>() AX, AY, AZ, BA, BB, BC, BD, BE, BF, BG, BH, BI, BJ, BK, BL>()

View file

@ -1,31 +1,36 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(stmt_expr_attributes, rustc_attrs)]
// This test checks that the polymorphization analysis correctly detects unused type // This test checks that the polymorphization analysis correctly detects unused type
// parameters in closures. // parameters in closures.
// Function doesn't have any generic parameters to be unused. // Function doesn't have any generic parameters to be unused.
#[rustc_polymorphize_error]
pub fn no_parameters() { pub fn no_parameters() {
let _ = || {}; let _ = || {};
} }
// Function has an unused generic parameter in parent and closure. // Function has an unused generic parameter in parent and closure.
#[rustc_polymorphize_error]
pub fn unused<T>() -> u32 { pub fn unused<T>() -> u32 {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let add_one = |x: u32| x + 1; let add_one = |x: u32| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
add_one(3) add_one(3)
} }
// Function has an unused generic parameter in closure, but not in parent. // Function has an unused generic parameter in closure, but not in parent.
#[rustc_polymorphize_error]
pub fn used_parent<T: Default>() -> u32 { pub fn used_parent<T: Default>() -> u32 {
let _: T = Default::default(); let _: T = Default::default();
let add_one = |x: u32| x + 1; let add_one = |x: u32| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
add_one(3) add_one(3)
} }
// Function uses generic parameter in value of a binding in closure. // Function uses generic parameter in value of a binding in closure.
#[rustc_polymorphize_error]
pub fn used_binding_value<T: Default>() -> T { pub fn used_binding_value<T: Default>() -> T {
let x = || { let x = || {
let y: T = Default::default(); 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. // Function uses generic parameter in generic of a binding in closure.
#[rustc_polymorphize_error]
pub fn used_binding_generic<T>() -> Option<T> { pub fn used_binding_generic<T>() -> Option<T> {
let x = || { let x = || {
let y: Option<T> = None; 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. // Function and closure uses generic parameter in argument.
#[rustc_polymorphize_error]
pub fn used_argument<T>(t: T) -> u32 { pub fn used_argument<T>(t: T) -> u32 {
let x = |_: T| 3; let x = |_: T| 3;
x(t) x(t)
} }
// Closure uses generic parameter in argument. // Closure uses generic parameter in argument.
#[rustc_polymorphize_error]
pub fn used_argument_closure<T: Default>() -> u32 { pub fn used_argument_closure<T: Default>() -> u32 {
let t: T = Default::default(); let t: T = Default::default();
let x = |_: T| 3; let x = |_: T| 3;
x(t) x(t)
} }
// Closure uses generic parameter as upvar. // Closure uses generic parameter as upvar.
#[rustc_polymorphize_error]
pub fn used_upvar<T: Default>() -> T { pub fn used_upvar<T: Default>() -> T {
let x: T = Default::default(); let x: T = Default::default();
let y = || x; let y = || x;
y() y()
} }
// Closure uses generic parameter in substitutions to another function. // Closure uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs<T>() -> u32 { pub fn used_substs<T>() -> u32 {
let x = || unused::<T>(); let x = || unused::<T>();
x() x()
@ -75,14 +87,16 @@ struct Foo<F>(F);
impl<F: Default> Foo<F> { impl<F: Default> Foo<F> {
// Function has an unused generic parameter from impl and fn. // Function has an unused generic parameter from impl and fn.
#[rustc_polymorphize_error]
pub fn unused_all<G: Default>() -> u32 { 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; let add_one = |x: u32| x + 1;
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
add_one(3) add_one(3)
} }
// Function uses generic parameter from impl and fn in closure. // Function uses generic parameter from impl and fn in closure.
#[rustc_polymorphize_error]
pub fn used_both<G: Default>() -> u32 { pub fn used_both<G: Default>() -> u32 {
let add_one = |x: u32| { let add_one = |x: u32| {
let _: F = Default::default(); let _: F = Default::default();
@ -94,10 +108,11 @@ impl<F: Default> Foo<F> {
} }
// Function uses generic parameter from fn in closure. // Function uses generic parameter from fn in closure.
#[rustc_polymorphize_error]
pub fn used_fn<G: Default>() -> u32 { pub fn used_fn<G: Default>() -> u32 {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let add_one = |x: u32| { let add_one = |x: u32| {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let _: G = Default::default(); let _: G = Default::default();
x + 1 x + 1
}; };
@ -106,10 +121,11 @@ impl<F: Default> Foo<F> {
} }
// Function uses generic parameter from impl in closure. // Function uses generic parameter from impl in closure.
#[rustc_polymorphize_error]
pub fn used_impl<G: Default>() -> u32 { pub fn used_impl<G: Default>() -> u32 {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let add_one = |x: u32| { let add_one = |x: u32| {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let _: F = Default::default(); let _: F = Default::default();
x + 1 x + 1
}; };
@ -118,6 +134,7 @@ impl<F: Default> Foo<F> {
} }
// Closure uses generic parameter in substitutions to another function. // Closure uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs() -> u32 { pub fn used_substs() -> u32 {
let x = || unused::<F>(); let x = || unused::<F>();
x() x()

View file

@ -1,20 +1,20 @@
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:15:19 --> $DIR/closures.rs:18:19
| |
LL | pub fn unused<T>() -> u32 { LL | pub fn unused<T>() -> u32 {
| - generic parameter `T` is unused | - generic parameter `T` is unused
LL | ...
LL | let add_one = |x: u32| x + 1; LL | let add_one = |x: u32| x + 1;
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:13:8 --> $DIR/closures.rs:15:8
| |
LL | pub fn unused<T>() -> u32 { LL | pub fn unused<T>() -> u32 {
| ^^^^^^ - generic parameter `T` is unused | ^^^^^^ - generic parameter `T` is unused
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:23:19 --> $DIR/closures.rs:27:19
| |
LL | pub fn used_parent<T: Default>() -> u32 { LL | pub fn used_parent<T: Default>() -> u32 {
| - generic parameter `T` is unused | - generic parameter `T` is unused
@ -23,11 +23,11 @@ LL | let add_one = |x: u32| x + 1;
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:80:23 --> $DIR/closures.rs:93:23
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused
LL | // Function has an unused generic parameter from impl and fn. ...
LL | pub fn unused_all<G: Default>() -> u32 { LL | pub fn unused_all<G: Default>() -> u32 {
| - generic parameter `G` is unused | - generic parameter `G` is unused
LL | LL |
@ -35,16 +35,16 @@ LL | let add_one = |x: u32| x + 1;
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:78:12 --> $DIR/closures.rs:91:12
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused
LL | // Function has an unused generic parameter from impl and fn. ...
LL | pub fn unused_all<G: Default>() -> u32 { LL | pub fn unused_all<G: Default>() -> u32 {
| ^^^^^^^^^^ - generic parameter `G` is unused | ^^^^^^^^^^ - generic parameter `G` is unused
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:111:23 --> $DIR/closures.rs:127:23
| |
LL | pub fn used_impl<G: Default>() -> u32 { LL | pub fn used_impl<G: Default>() -> u32 {
| - generic parameter `G` is unused | - generic parameter `G` is unused
@ -58,13 +58,13 @@ LL | | };
| |_________^ | |_________^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:109:12 --> $DIR/closures.rs:125:12
| |
LL | pub fn used_impl<G: Default>() -> u32 { LL | pub fn used_impl<G: Default>() -> u32 {
| ^^^^^^^^^ - generic parameter `G` is unused | ^^^^^^^^^ - generic parameter `G` is unused
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:99:23 --> $DIR/closures.rs:114:23
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused
@ -78,7 +78,7 @@ LL | | };
| |_________^ | |_________^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/closures.rs:97:12 --> $DIR/closures.rs:112:12
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused

View file

@ -1,32 +1,37 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(rustc_attrs)]
// This test checks that the polymorphization analysis correctly detects unused type // This test checks that the polymorphization analysis correctly detects unused type
// parameters in functions. // parameters in functions.
// Function doesn't have any generic parameters to be unused. // Function doesn't have any generic parameters to be unused.
#[rustc_polymorphize_error]
pub fn no_parameters() {} pub fn no_parameters() {}
// Function has an unused generic parameter. // Function has an unused generic parameter.
#[rustc_polymorphize_error]
pub fn unused<T>() { 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. // Function uses generic parameter in value of a binding.
#[rustc_polymorphize_error]
pub fn used_binding_value<T: Default>() { pub fn used_binding_value<T: Default>() {
let _: T = Default::default(); let _: T = Default::default();
} }
// Function uses generic parameter in generic of a binding. // Function uses generic parameter in generic of a binding.
#[rustc_polymorphize_error]
pub fn used_binding_generic<T>() { pub fn used_binding_generic<T>() {
let _: Option<T> = None; let _: Option<T> = None;
} }
// Function uses generic parameter in argument. // 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. // Function uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs<T>() { pub fn used_substs<T>() {
unused::<T>() unused::<T>()
} }
@ -35,33 +40,39 @@ struct Foo<F>(F);
impl<F: Default> Foo<F> { impl<F: Default> Foo<F> {
// Function has an unused generic parameter from impl. // Function has an unused generic parameter from impl.
#[rustc_polymorphize_error]
pub fn unused_impl() { 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. // Function has an unused generic parameter from impl and fn.
#[rustc_polymorphize_error]
pub fn unused_both<G: Default>() { pub fn unused_both<G: Default>() {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
} }
// Function uses generic parameter from impl. // Function uses generic parameter from impl.
#[rustc_polymorphize_error]
pub fn used_impl() { pub fn used_impl() {
let _: F = Default::default(); let _: F = Default::default();
} }
// Function uses generic parameter from impl. // Function uses generic parameter from impl.
#[rustc_polymorphize_error]
pub fn used_fn<G: Default>() { pub fn used_fn<G: Default>() {
//~^ ERROR item has unused generic parameters //~^ ERROR item has unused generic parameters
let _: G = Default::default(); let _: G = Default::default();
} }
// Function uses generic parameter from impl. // Function uses generic parameter from impl.
#[rustc_polymorphize_error]
pub fn used_both<G: Default>() { pub fn used_both<G: Default>() {
let _: F = Default::default(); let _: F = Default::default();
let _: G = Default::default(); let _: G = Default::default();
} }
// Function uses generic parameter in substitutions to another function. // Function uses generic parameter in substitutions to another function.
#[rustc_polymorphize_error]
pub fn used_substs() { pub fn used_substs() {
unused::<F>() unused::<F>()
} }

View file

@ -1,20 +1,20 @@
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/functions.rs:11:8 --> $DIR/functions.rs:13:8
| |
LL | pub fn unused<T>() { LL | pub fn unused<T>() {
| ^^^^^^ - generic parameter `T` is unused | ^^^^^^ - generic parameter `T` is unused
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/functions.rs:38:12 --> $DIR/functions.rs:44:12
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused
LL | // Function has an unused generic parameter from impl. ...
LL | pub fn unused_impl() { LL | pub fn unused_impl() {
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/functions.rs:43:12 --> $DIR/functions.rs:50:12
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused
@ -23,7 +23,7 @@ LL | pub fn unused_both<G: Default>() {
| ^^^^^^^^^^^ - generic parameter `G` is unused | ^^^^^^^^^^^ - generic parameter `G` is unused
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/functions.rs:53:12 --> $DIR/functions.rs:62:12
| |
LL | impl<F: Default> Foo<F> { LL | impl<F: Default> Foo<F> {
| - generic parameter `F` is unused | - generic parameter `F` is unused

View file

@ -1,10 +1,10 @@
// build-fail // build-fail
// compile-flags: -Zpolymorphize-errors #![feature(fn_traits, rustc_attrs, unboxed_closures)]
#![feature(fn_traits, unboxed_closures)]
// This test checks that the polymorphization analysis considers a closure // This test checks that the polymorphization analysis considers a closure
// as using all generic parameters if it does an unsizing cast. // as using all generic parameters if it does an unsizing cast.
#[rustc_polymorphize_error]
fn foo<T: Default>() { fn foo<T: Default>() {
let _: T = Default::default(); let _: T = Default::default();
(|| Box::new(|| {}) as Box<dyn Fn()>)(); (|| Box::new(|| {}) as Box<dyn Fn()>)();
@ -12,6 +12,7 @@ fn foo<T: Default>() {
//~^^ ERROR item has unused generic parameters //~^^ ERROR item has unused generic parameters
} }
#[rustc_polymorphize_error]
fn foo2<T: Default>() { fn foo2<T: Default>() {
let _: T = Default::default(); let _: T = Default::default();
(|| { (|| {

View file

@ -17,7 +17,7 @@ LL | (|| Box::new(|| {}) as Box<dyn Fn()>)();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: item has unused generic parameters error: item has unused generic parameters
--> $DIR/unsized_cast.rs:19:15 --> $DIR/unsized_cast.rs:20:15
| |
LL | fn foo2<T: Default>() { LL | fn foo2<T: Default>() {
| - generic parameter `T` is unused | - generic parameter `T` is unused