An unused generic parameter should be a warning at the definition site.
Consider the following code:
fn foo<F>(x: i32) -> i32 { x }
fn bar<'a>(x: i32) -> i32 { x }
fn main() {
bar(1);
bar(2);
foo::<f64>(3);
foo(4);
foo(5);
}
Currently, this causes a fatal compiler error at the invocation of foo(4) on line 9, of the form:
error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [--explain E0282]
--> <anon>:9:5
|>
9 |> foo(4);
|> ^^^
error: aborting due to previous error
The only way to ever successfully invoke foo is to feed it an explicit type (via the ::<_> syntax as illustrated on line 8).
I suspect in many cases of this error, the actual problem is that the definition of fn foo (and also fn bar) are faulty: since F and 'a are never referenced in the signature nor in the function body, they are irrelevant and should cause a warning via the compiler's linting system.
(A separate issue is that one cannot actually instantiate the 'a parameter to fn bar via the ::<_> syntax, so it seems that its formal lifetime parameter is truly unusable. But things may not remain that way forever, so I think its best to lump both of these cases into the same category.
I actually implemented this lint in #26684! At the time, @alexcrichton was against the lint.
Seo Sanghyeon at 2016-06-21 10:12:55
I am not sure this would be useful - lints only execute after errors are reported.
Ariel Ben-Yehuda at 2016-06-21 17:33:36
It looks like the compiler error only happens if the unused parameter is a type. If a lifetime is unused, there is no error or warning. For instance, https://is.gd/aFXcBf and https://play.rust-lang.org/?gist=5368c08fbdcba4efaa8c2e35aa59b429&version=stable&backtrace=0 really should trigger at least a warning.
Ixrec at 2016-09-20 22:49:29
Dredging up this issue again. I would have liked a lint for unused lifetime parameters to be around for a PR on one of my libraries that removed a lifetime parameter from a struct, but not all of the functions that created it. If the parameter is completely unused, i don't want it appearing in my public API, and thus i would like to have a lint for it so i can keep that from happening.
QuietMisdreavus at 2017-11-14 00:11:46
bumb This extends to const_generics.
In the following code, the fact that only
reality_checkcauses a warning (unused_variables) is BAD:#![allow(stable_features)] #![feature(min_const_generics)] fn foo<F>(x: i32) -> i32 { x } fn bar<'a>(x: i32) -> i32 { x } fn baz<const TOTO: i32>(x: i32) -> i32 { x } fn reality_check(x: i32, y: i64) -> i32 { x } fn main() { bar(1); foo::<f64>(3); baz::<5>(4); reality_check(99, -1); }Arthur Woimbée at 2021-01-27 19:07:47
We should only emit a warning if the generic parater has no bounds, as code like
fn is_send<T: Send>() { ... }can be useful.Aaron Hill at 2021-01-27 19:19:15
We need a more in-depth discussion on this, something like
fn is_send<T: Send>() { ... }could use something like#[allow(unused_generic)], just like I need#[allow(unused_variables)]to define drop myself:#[allow(unused_variables)] pub fn drop<T>(_x: T) {}Arthur Woimbée at 2021-01-27 19:42:58
The original report still errors, with a relatively good diagnostic (it could be better):
error[E0282]: type annotations needed --> f71.rs:9:5 | 9 | foo(4); | ^^^ cannot infer type of the type parameter `F` declared on the function `foo` | help: consider specifying the generic argument | 9 | foo::<F>(4); | +++++Esteban Kuber at 2023-08-14 13:43:38