mir: unused_generic_params query
This commit implements the `unused_generic_params` query, an initial version of polymorphization which detects when an item does not use generic parameters and is being needlessly monomorphized as a result. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
47756bb0fa
commit
2989fea88a
44 changed files with 1627 additions and 84 deletions
61
src/test/ui/polymorphization/const_parameters/closures.rs
Normal file
61
src/test/ui/polymorphization/const_parameters/closures.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(const_generics)]
|
||||
//~^ 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.
|
||||
pub fn no_parameters() {
|
||||
let _ = || {};
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in parent and closure.
|
||||
pub fn unused<const T: usize>() -> usize {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
let add_one = |x: usize| x + 1;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
add_one(3)
|
||||
}
|
||||
|
||||
// Function has an unused generic parameter in closure, but not in parent.
|
||||
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
|
||||
x + add_one(3)
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding in closure.
|
||||
pub fn used_binding<const T: usize>() -> usize {
|
||||
let x = || {
|
||||
let y: usize = T;
|
||||
y
|
||||
};
|
||||
|
||||
x()
|
||||
}
|
||||
|
||||
// Closure uses a value as an upvar, which used the generic parameter.
|
||||
pub fn unused_upvar<const T: usize>() -> usize {
|
||||
let x: usize = T;
|
||||
let y = || x;
|
||||
//~^ ERROR item has unused generic parameters
|
||||
y()
|
||||
}
|
||||
|
||||
// Closure uses generic parameter in substitutions to another function.
|
||||
pub fn used_substs<const T: usize>() -> usize {
|
||||
let x = || unused::<T>();
|
||||
x()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
no_parameters();
|
||||
let _ = unused::<1>();
|
||||
let _ = used_parent::<1>();
|
||||
let _ = used_binding::<1>();
|
||||
let _ = unused_upvar::<1>();
|
||||
let _ = used_substs::<1>();
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/closures.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | pub fn unused<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
LL |
|
||||
LL | let add_one = |x: usize| x + 1;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:15: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
|
||||
|
|
||||
LL | pub fn used_parent<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
LL | let x: usize = T;
|
||||
LL | let add_one = |x: usize| x + 1;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: item has unused generic parameters
|
||||
--> $DIR/closures.rs:43:13
|
||||
|
|
||||
LL | pub fn unused_upvar<const T: usize>() -> usize {
|
||||
| - generic parameter `T` is unused
|
||||
LL | let x: usize = T;
|
||||
LL | let y = || x;
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
33
src/test/ui/polymorphization/const_parameters/functions.rs
Normal file
33
src/test/ui/polymorphization/const_parameters/functions.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// build-fail
|
||||
// compile-flags: -Zpolymorphize-errors
|
||||
#![feature(const_generics)]
|
||||
//~^ 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.
|
||||
pub fn no_parameters() {}
|
||||
|
||||
// Function has an unused generic parameter.
|
||||
pub fn unused<const T: usize>() {
|
||||
//~^ ERROR item has unused generic parameters
|
||||
}
|
||||
|
||||
// Function uses generic parameter in value of a binding.
|
||||
pub fn used_binding<const T: usize>() -> usize {
|
||||
let x: usize = T;
|
||||
x
|
||||
}
|
||||
|
||||
// Function uses generic parameter in substitutions to another function.
|
||||
pub fn used_substs<const T: usize>() {
|
||||
unused::<T>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
no_parameters();
|
||||
unused::<1>();
|
||||
used_binding::<1>();
|
||||
used_substs::<1>();
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/functions.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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
|
||||
|
|
||||
LL | pub fn unused<const T: usize>() {
|
||||
| ^^^^^^ - generic parameter `T` is unused
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue