Skip to content

Example trigger needless_arbitrary_self_type clippy lint #67

Description

@Cyrix126

Situation / Reproduction

Running the example from https://docs.rs/duplicate/latest/duplicate/#parameterized-substitution

struct VecWrap<T>(Vec<T>);

impl<T> VecWrap<T> {
  #[duplicate_item(
    method     reference(type);
    [get]      [& type];
    [get_mut]  [&mut type];
  )]
  pub fn method(self: reference([Self]), idx: usize) -> Option<reference([T])> {
    self.0.method(idx)
  }
}

Expected Behavior:

Find an example that doesn't trigger any clippy lint and produce the code displayed in the example:

struct VecWrap<T>(Vec<T>);

impl<T> VecWrap<T> {
  pub fn get(&self, idx: usize) -> Option<&T> {
    self.0.get(idx)
  }
  pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
    self.0.get_mut(idx)
  }
}

Actual Behavior:

The following clippy lint is produced
https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
Because it is producing

struct VecWrap<T>(Vec<T>);

impl<T> VecWrap<T> {
  pub fn get(self: &T, idx: usize) -> Option<&T> {
    self.0.get(idx)
  }
  pub fn get_mut(self: &mut T, idx: usize) -> Option<&mut T> {
    self.0.get_mut(idx)
  }
}

Affected Versions:

duplicate = "2.0.1"

Local Environment:

rustc 1.93.0-nightly (b33119ffd 2025-12-04)

Miscellaneous:

Obviously it is producing self: &T and self: &mut T instead of &self and &self mut T.

I tried editing the example to

use duplicate::duplicate_item;

struct VecWrap<T>(Vec<T>);

impl<T> VecWrap<T> {
    #[duplicate_item(
    method     reference(type);
    [get]      [& type];
    [get_mut]  [&mut type];
  )]
    pub fn method(reference([self]), idx: usize) -> Option<reference([T])> {
        self.0.method(idx)
    }
}

Although cargo expand produce a working result

#![feature(prelude_import)]
#[macro_use]
extern crate std;
#[prelude_import]
use std::prelude::rust_2024::*;
use duplicate::duplicate_item;
struct VecWrap<T>(Vec<T>);
impl<T> VecWrap<T> {
    pub fn get(&self, idx: usize) -> Option<&T> {
        self.0.get(idx)
    }
    pub fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
        self.0.get_mut(idx)
    }
}

cargo check will report an error (on the non expanded code)

error: expected one of `:` or `|`, found `,`
  --> src/lib.rs:11:36
   |
11 |     pub fn method(reference([self]), idx: usize) -> Option<reference([T])> {
   |                                    ^ expected one of `:` or `|`

Of course, disabling the lint is possible, but I would prefer to find the right syntax to use.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    D-acceptedA decision (D) has been made and the issue will be worked onI-documentationThis issue (I) regards the documentation of the projectT-acceptedTriage (T): Initial review accepted issue/PR as validgood first issueGood for newcomers

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions