Skip to content

Inconsistent type-parameter order #7147

Closed
@lukaslueg

Description

@lukaslueg

What it does

Warn if type parameters are named identically but ordered inconsistently in type definitions and impl-blocks. This is a cousin to the new inconsistent_struct_constructor lint. With literal constructors, the order of variables does not matter (Foo { a, b } is the same as Foo { b, a }). Type parameters, on the other hand, are never referred to by name, but only by position, which is exactly reversed to the behavior of struct constructors. For example:

struct Foo<A, B> {
    a: A,
    b: B,
}

// Potential warning: `B` does not refer to `B` in the struct-definition, because of position.
impl<B, A> Foo<B, A> {
    fn type_names(&self) {
        let name_a = std::any::type_name::<A>();
        let name_b = std::any::type_name::<B>();
        println!("A: {}, B: {}", name_a, name_b);
    }

    fn values(&self)
    where
        A: std::fmt::Debug,
        B: std::fmt::Debug,
    {
        println!("a: {:?}, b: {:?}", self.a, self.b);
    }
}

fn main() {
    let foo = Foo { a: 0, b: "foo" };

    // Prints 'A: &str, B: i32'
    foo.type_names();

    // Prints 'a: 0, b: "foo"'
    foo.values();

    // Wait, what? A `i32` valued as "foo" ?
}

Categories (optional)

  • Kind: Possibly clippy::correctness, because getting this wrong may cause you to refer to the wrong type parameter.

What is the advantage of the recommended code over the original code

  • Naming the type parameters consistently avoids confusion between type definition and type implementation.

Drawbacks

None.

Example

// Note::
struct Foo<A, B> {
// ...

impl<B, A> Foo<B, A> {
//   ^--|- This type parameter refers to `Foo::A`, but is named `B`.
//      ^- This type parameter refers to `Foo::B`, but is named `A`

Could be written as:

impl<A, B> Foo<A, B> {

Metadata

Metadata

Assignees

Labels

A-lintArea: New lintsgood first issueThese issues are a good way to get started with Clippy

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions