Add impl_trait_param
lint
As this is a lint about "style", and a purely cosmetical choice (using `<A: Trait>` over `impl Trait`), a lot of other files needed to be allowed this lint.
This commit is contained in:
parent
5b6795f50b
commit
8ec9543f13
@ -4430,6 +4430,7 @@ Released 2018-09-13
|
||||
[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else
|
||||
[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
|
||||
[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond
|
||||
[`impl_trait_param`]: https://rust-lang.github.io/rust-clippy/master/index.html#impl_trait_param
|
||||
[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone
|
||||
[`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher
|
||||
[`implicit_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_return
|
||||
|
@ -179,6 +179,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||
crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,
|
||||
crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,
|
||||
crate::functions::DOUBLE_MUST_USE_INFO,
|
||||
crate::functions::IMPL_TRAIT_PARAM_INFO,
|
||||
crate::functions::MISNAMED_GETTERS_INFO,
|
||||
crate::functions::MUST_USE_CANDIDATE_INFO,
|
||||
crate::functions::MUST_USE_UNIT_INFO,
|
||||
|
88
clippy_lints/src/functions/impl_trait_param.rs
Normal file
88
clippy_lints/src/functions/impl_trait_param.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use clippy_utils::{diagnostics::span_lint_and_then, is_in_test_function};
|
||||
|
||||
use rustc_hir::{intravisit::FnKind, Body, Generics, HirId};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::IMPL_TRAIT_PARAM;
|
||||
|
||||
pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) {
|
||||
if cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() && !is_in_test_function(cx.tcx, hir_id)
|
||||
{
|
||||
if let FnKind::ItemFn(ident, generics, _) = kind {
|
||||
for param in generics.params {
|
||||
if param.is_impl_trait()
|
||||
&& !param.name.ident().as_str().contains('<')
|
||||
&& !param.name.ident().as_str().contains('(')
|
||||
{
|
||||
// No generics with nested generics, and no generics like FnMut(x)
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
IMPL_TRAIT_PARAM,
|
||||
param.span,
|
||||
&format!("'{}' in the function's parameters", param.name.ident().as_str()),
|
||||
|diag| {
|
||||
let next_letter = next_valid_letter(generics);
|
||||
if let Some(gen_span) = generics.span_for_param_suggestion() {
|
||||
diag.span_suggestion_with_style(
|
||||
gen_span,
|
||||
format!(
|
||||
"create a generic type here and replace that `{}` with `{}`",
|
||||
param.name.ident().as_str(),
|
||||
next_letter
|
||||
),
|
||||
", T: Trait",
|
||||
rustc_errors::Applicability::MaybeIncorrect,
|
||||
rustc_errors::SuggestionStyle::ShowAlways,
|
||||
);
|
||||
} else {
|
||||
// multispan.push_span_label(param.span, format!("Replace this with `{}`",
|
||||
// next_letter));
|
||||
|
||||
diag.span_suggestion_with_style(
|
||||
Span::new(
|
||||
body.params[0].span.lo() - rustc_span::BytePos(1),
|
||||
ident.span.hi(),
|
||||
ident.span.ctxt(),
|
||||
ident.span.parent(),
|
||||
),
|
||||
format!(
|
||||
"create a generic type here and replace that '{}' with `{}`",
|
||||
param.name.ident().as_str(),
|
||||
next_letter
|
||||
),
|
||||
"<T: Trait>",
|
||||
rustc_errors::Applicability::MaybeIncorrect,
|
||||
rustc_errors::SuggestionStyle::ShowAlways,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_valid_letter(generics: &Generics<'_>) -> char {
|
||||
let mut generics_names = Vec::new();
|
||||
|
||||
generics.params.iter().for_each(|param| {
|
||||
generics_names.push(param.name.ident().as_str().to_owned());
|
||||
});
|
||||
|
||||
// If T exists, try with U, then with V, and so on...
|
||||
let mut current_letter = 84u32; // ASCII code for "T"
|
||||
while generics_names.contains(&String::from(char::from_u32(current_letter).unwrap())) {
|
||||
current_letter += 1;
|
||||
if current_letter == 91 {
|
||||
// ASCII code for "Z"
|
||||
current_letter = 65;
|
||||
} else if current_letter == 83 {
|
||||
// ASCII "S"
|
||||
current_letter = 97; // "a"
|
||||
};
|
||||
}
|
||||
|
||||
char::from_u32(current_letter).unwrap()
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
mod impl_trait_param;
|
||||
mod misnamed_getters;
|
||||
mod must_use;
|
||||
mod not_unsafe_ptr_arg_deref;
|
||||
@ -327,6 +328,32 @@ declare_clippy_lint! {
|
||||
"getter method returning the wrong field"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Lints when `impl Trait` is being used in a function's paremeters.
|
||||
/// ### Why is this bad?
|
||||
/// Turbofish syntax (`::<>`) cannot be used when `impl Trait` is being used, making `impl Trait` less powerful. Readability may also be a factor.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// trait MyTrait {}
|
||||
/// fn foo(a: impl MyTrait) {
|
||||
/// // [...]
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// trait MyTrait {}
|
||||
/// fn foo<T: A>(a: A) {
|
||||
/// // [...]
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.68.0"]
|
||||
pub IMPL_TRAIT_PARAM,
|
||||
style,
|
||||
"`impl Trait` is used in the function's parameters"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Functions {
|
||||
too_many_arguments_threshold: u64,
|
||||
@ -354,6 +381,7 @@ impl_lint_pass!(Functions => [
|
||||
RESULT_UNIT_ERR,
|
||||
RESULT_LARGE_ERR,
|
||||
MISNAMED_GETTERS,
|
||||
IMPL_TRAIT_PARAM,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Functions {
|
||||
@ -371,6 +399,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
|
||||
too_many_lines::check_fn(cx, kind, span, body, self.too_many_lines_threshold);
|
||||
not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);
|
||||
misnamed_getters::check_fn(cx, kind, decl, body, span);
|
||||
impl_trait_param::check_fn(cx, &kind, body, hir_id);
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
|
@ -2,7 +2,12 @@
|
||||
//!
|
||||
//! - The `eq_foobar` functions test for semantic equality but ignores `NodeId`s and `Span`s.
|
||||
|
||||
#![allow(clippy::similar_names, clippy::wildcard_imports, clippy::enum_glob_use)]
|
||||
#![allow(
|
||||
clippy::similar_names,
|
||||
clippy::wildcard_imports,
|
||||
clippy::enum_glob_use,
|
||||
clippy::impl_trait_param
|
||||
)]
|
||||
|
||||
use crate::{both, over};
|
||||
use rustc_ast::ptr::P;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![allow(clippy::impl_trait_param)]
|
||||
//! This module handles checking if the span given is from a proc-macro or not.
|
||||
//!
|
||||
//! Proc-macros are capable of setting the span of every token they output to a few possible spans.
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![allow(clippy::impl_trait_param)]
|
||||
use crate::consts::constant_simple;
|
||||
use crate::macros::macro_backtrace;
|
||||
use crate::source::snippet_opt;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![allow(clippy::similar_names)] // `expr` and `expn`
|
||||
#![allow(clippy::similar_names, clippy::impl_trait_param)] // `expr` and `expn`
|
||||
|
||||
use crate::source::snippet_opt;
|
||||
use crate::visitors::{for_each_expr, Descend};
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Utils for extracting, inspecting or transforming source code
|
||||
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
#![allow(clippy::module_name_repetitions, clippy::impl_trait_param)]
|
||||
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![deny(clippy::borrowed_box)]
|
||||
#![allow(dead_code, unused_variables)]
|
||||
#![allow(clippy::uninlined_format_args, clippy::disallowed_names)]
|
||||
#![allow(clippy::uninlined_format_args, clippy::disallowed_names, clippy::impl_trait_param)]
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
|
@ -7,7 +7,8 @@
|
||||
clippy::no_effect,
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::uninlined_format_args
|
||||
clippy::uninlined_format_args,
|
||||
clippy::impl_trait_param
|
||||
)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -7,7 +7,8 @@
|
||||
clippy::no_effect,
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::uninlined_format_args
|
||||
clippy::uninlined_format_args,
|
||||
clippy::impl_trait_param
|
||||
)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:28:27
|
||||
--> $DIR/eta.rs:29:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| foo(a));
|
||||
| ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
|
||||
@ -7,31 +7,31 @@ LL | let a = Some(1u8).map(|a| foo(a));
|
||||
= note: `-D clippy::redundant-closure` implied by `-D warnings`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:32:40
|
||||
--> $DIR/eta.rs:33:40
|
||||
|
|
||||
LL | let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
|
||||
| ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:33:35
|
||||
--> $DIR/eta.rs:34:35
|
||||
|
|
||||
LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
|
||||
| ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:34:26
|
||||
--> $DIR/eta.rs:35:26
|
||||
|
|
||||
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
|
||||
| ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:41:27
|
||||
--> $DIR/eta.rs:42:27
|
||||
|
|
||||
LL | let e = Some(1u8).map(|a| generic(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:87:51
|
||||
--> $DIR/eta.rs:88:51
|
||||
|
|
||||
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
|
||||
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
|
||||
@ -39,121 +39,121 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
|
||||
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:88:51
|
||||
--> $DIR/eta.rs:89:51
|
||||
|
|
||||
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:90:42
|
||||
--> $DIR/eta.rs:91:42
|
||||
|
|
||||
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
|
||||
| ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:94:29
|
||||
--> $DIR/eta.rs:95:29
|
||||
|
|
||||
LL | let e = Some("str").map(|s| s.to_string());
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:95:27
|
||||
--> $DIR/eta.rs:96:27
|
||||
|
|
||||
LL | let e = Some('a').map(|s| s.to_uppercase());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:97:65
|
||||
--> $DIR/eta.rs:98:65
|
||||
|
|
||||
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:160:22
|
||||
--> $DIR/eta.rs:161:22
|
||||
|
|
||||
LL | requires_fn_once(|| x());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `x`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:167:27
|
||||
--> $DIR/eta.rs:168:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| foo_ptr(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:172:27
|
||||
--> $DIR/eta.rs:173:27
|
||||
|
|
||||
LL | let a = Some(1u8).map(|a| closure(a));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:204:28
|
||||
--> $DIR/eta.rs:205:28
|
||||
|
|
||||
LL | x.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:205:28
|
||||
--> $DIR/eta.rs:206:28
|
||||
|
|
||||
LL | y.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:206:28
|
||||
--> $DIR/eta.rs:207:28
|
||||
|
|
||||
LL | z.into_iter().for_each(|x| add_to_res(x));
|
||||
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:213:21
|
||||
--> $DIR/eta.rs:214:21
|
||||
|
|
||||
LL | Some(1).map(|n| closure(n));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:217:21
|
||||
--> $DIR/eta.rs:218:21
|
||||
|
|
||||
LL | Some(1).map(|n| in_loop(n));
|
||||
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:310:18
|
||||
--> $DIR/eta.rs:311:18
|
||||
|
|
||||
LL | takes_fn_mut(|| f());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:313:19
|
||||
--> $DIR/eta.rs:314:19
|
||||
|
|
||||
LL | takes_fn_once(|| f());
|
||||
| ^^^^^^ help: replace the closure with the function itself: `&mut f`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:317:26
|
||||
--> $DIR/eta.rs:318:26
|
||||
|
|
||||
LL | move || takes_fn_mut(|| f_used_once())
|
||||
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:329:19
|
||||
--> $DIR/eta.rs:330:19
|
||||
|
|
||||
LL | array_opt.map(|a| a.as_slice());
|
||||
| ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:332:19
|
||||
--> $DIR/eta.rs:333:19
|
||||
|
|
||||
LL | slice_opt.map(|s| s.len());
|
||||
| ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:335:17
|
||||
--> $DIR/eta.rs:336:17
|
||||
|
|
||||
LL | ptr_opt.map(|p| p.is_null());
|
||||
| ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
|
||||
|
||||
error: redundant closure
|
||||
--> $DIR/eta.rs:339:17
|
||||
--> $DIR/eta.rs:340:17
|
||||
|
|
||||
LL | dyn_opt.map(|d| d.method_on_dyn());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
|
||||
|
15
tests/ui/impl_trait_param.rs
Normal file
15
tests/ui/impl_trait_param.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![allow(unused)]
|
||||
#![warn(clippy::impl_trait_param)]
|
||||
|
||||
pub trait Trait {}
|
||||
|
||||
// Should warn
|
||||
pub fn a(_: impl Trait) {}
|
||||
pub fn c<C: Trait>(_: C, _: impl Trait) {}
|
||||
|
||||
// Shouldn't warn
|
||||
|
||||
pub fn b<B: Trait>(_: B) {}
|
||||
fn d<D: Trait>(_: D, _: impl Trait) {}
|
||||
|
||||
fn main() {}
|
25
tests/ui/impl_trait_param.stderr
Normal file
25
tests/ui/impl_trait_param.stderr
Normal file
@ -0,0 +1,25 @@
|
||||
error: 'impl Trait' in the function's parameters
|
||||
--> $DIR/impl_trait_param.rs:7:13
|
||||
|
|
||||
LL | pub fn a(_: impl Trait) {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::impl-trait-param` implied by `-D warnings`
|
||||
help: create a generic type here and replace that 'impl Trait' with `T`
|
||||
|
|
||||
LL | pub fn a<T: Trait>(_: impl Trait) {}
|
||||
| ++++++++++
|
||||
|
||||
error: 'impl Trait' in the function's parameters
|
||||
--> $DIR/impl_trait_param.rs:8:29
|
||||
|
|
||||
LL | pub fn c<C: Trait>(_: C, _: impl Trait) {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: create a generic type here and replace that `impl Trait` with `T`
|
||||
|
|
||||
LL | pub fn c<C: Trait, T: Trait>(_: C, _: impl Trait) {}
|
||||
| ++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,5 +1,6 @@
|
||||
// run-rustfix
|
||||
#![deny(clippy::trait_duplication_in_bounds)]
|
||||
#![allow(clippy::impl_trait_param)]
|
||||
#![allow(unused)]
|
||||
|
||||
fn bad_foo<T: Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
// run-rustfix
|
||||
#![deny(clippy::trait_duplication_in_bounds)]
|
||||
#![allow(clippy::impl_trait_param)]
|
||||
#![allow(unused)]
|
||||
|
||||
fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: these bounds contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:5:15
|
||||
--> $DIR/trait_duplication_in_bounds.rs:6:15
|
||||
|
|
||||
LL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
||||
@ -11,43 +11,43 @@ LL | #![deny(clippy::trait_duplication_in_bounds)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: these where clauses contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:11:8
|
||||
--> $DIR/trait_duplication_in_bounds.rs:12:8
|
||||
|
|
||||
LL | T: Clone + Clone + Clone + Copy,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
||||
|
||||
error: these bounds contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:39:26
|
||||
--> $DIR/trait_duplication_in_bounds.rs:40:26
|
||||
|
|
||||
LL | trait BadSelfTraitBound: Clone + Clone + Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
|
||||
|
||||
error: these where clauses contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:46:15
|
||||
--> $DIR/trait_duplication_in_bounds.rs:47:15
|
||||
|
|
||||
LL | Self: Clone + Clone + Clone;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`
|
||||
|
||||
error: these bounds contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:60:24
|
||||
--> $DIR/trait_duplication_in_bounds.rs:61:24
|
||||
|
|
||||
LL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
||||
|
||||
error: these where clauses contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:67:12
|
||||
--> $DIR/trait_duplication_in_bounds.rs:68:12
|
||||
|
|
||||
LL | T: Clone + Clone + Clone + Copy,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`
|
||||
|
||||
error: these bounds contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:100:19
|
||||
--> $DIR/trait_duplication_in_bounds.rs:101:19
|
||||
|
|
||||
LL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u64> + GenericTrait<u32>`
|
||||
|
||||
error: these bounds contain repeated elements
|
||||
--> $DIR/trait_duplication_in_bounds.rs:108:22
|
||||
--> $DIR/trait_duplication_in_bounds.rs:109:22
|
||||
|
|
||||
LL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone`
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![deny(clippy::trait_duplication_in_bounds)]
|
||||
#![allow(clippy::impl_trait_param)]
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: this trait bound is already specified in the where clause
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:7:15
|
||||
|
|
||||
LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
|
||||
| ^^^^^
|
||||
@ -12,7 +12,7 @@ LL | #![deny(clippy::trait_duplication_in_bounds)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this trait bound is already specified in the where clause
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:7:23
|
||||
|
|
||||
LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
|
||||
| ^^^^^^^
|
||||
@ -20,7 +20,7 @@ LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:35:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:36:15
|
||||
|
|
||||
LL | Self: Default;
|
||||
| ^^^^^^^
|
||||
@ -28,7 +28,7 @@ LL | Self: Default;
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:49:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:50:15
|
||||
|
|
||||
LL | Self: Default + Clone;
|
||||
| ^^^^^^^
|
||||
@ -36,7 +36,7 @@ LL | Self: Default + Clone;
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:55:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:56:15
|
||||
|
|
||||
LL | Self: Default + Clone;
|
||||
| ^^^^^^^
|
||||
@ -44,7 +44,7 @@ LL | Self: Default + Clone;
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:55:25
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:56:25
|
||||
|
|
||||
LL | Self: Default + Clone;
|
||||
| ^^^^^
|
||||
@ -52,7 +52,7 @@ LL | Self: Default + Clone;
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:58:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:59:15
|
||||
|
|
||||
LL | Self: Default;
|
||||
| ^^^^^^^
|
||||
@ -60,7 +60,7 @@ LL | Self: Default;
|
||||
= help: consider removing this trait bound
|
||||
|
||||
error: this trait bound is already specified in trait declaration
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:93:15
|
||||
--> $DIR/trait_duplication_in_bounds_unfixable.rs:94:15
|
||||
|
|
||||
LL | Self: Iterator<Item = Foo>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user