Skip to content

Example trigger needless_arbitrary_self_type clippy lint #67

@Cyrix126

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.

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