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:
David Wood 2020-06-22 13:57:03 +01:00
parent 47756bb0fa
commit 2989fea88a
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
44 changed files with 1627 additions and 84 deletions

View 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>();
}

View file

@ -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

View 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>();
}

View file

@ -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