Skip to content

clippy --fix generates broken code for new_without_default when Foo::new has type bounds #16255

@swwu

Description

@swwu

Summary

As title; when clippy --fix is run against code containing an arg-less Foo::new() method with generic type bounds, it flags the new_without_default lint, and attempts to fix by emitting an unbounded Default impl (which fails to typecheck).

Obviously this isn't a huge deal because I can just add the bound myself trivially.

Reproducer

Code:

use std::marker::PhantomData;

pub struct Foo<T> {
    marker: PhantomData<T>
}

impl<T> Foo<T> {
    pub fn new() -> Self
        where T: Clone
    {
        Self { marker: PhantomData }
    }
}

fn main() {
    Foo::<u64>::new();
    println!("Hello, world!");
}

Current output:

➜  clippyprob git:(master) 251218000110> cargo clippy --fix
    Checking clippyprob v0.1.0 (/Users/swwu/clippyprob)
warning: failed to automatically apply fixes suggested by rustc to crate `clippyprob`

after fixes were automatically applied the compiler reported errors within these files:

  * src/main.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0277]: the trait bound `T: std::clone::Clone` is not satisfied
  --> src/main.rs:9:9
   |
 9 |         Self::new()
   |         ^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `T`
   |
note: required by a bound in `Foo::<T>::new`
  --> src/main.rs:15:18
   |
14 |     pub fn new() -> Self
   |            --- required by a bound in this associated function
15 |         where T: Clone
   |                  ^^^^^ required by this bound in `Foo::<T>::new`
help: consider restricting type parameter `T` with trait `Clone`
   |
 7 | impl<T: std::clone::Clone> Default for Foo<T> {
   |       +++++++++++++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original diagnostics will follow.

warning: you should consider adding a `Default` implementation for `Foo<T>`
  --> src/main.rs:8:5
   |
 8 | /     pub fn new() -> Self
 9 | |         where T: Clone
10 | |     {
11 | |         Self { marker: PhantomData }
12 | |     }
   | |_____^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#new_without_default
   = note: `#[warn(clippy::new_without_default)]` on by default
help: try adding this
   |
 7 + impl<T> Default for Foo<T> {
 8 +     fn default() -> Self {
 9 +         Self::new()
10 +     }
11 + }
   |

warning: `clippyprob` (bin "clippyprob") generated 1 warning (run `cargo clippy --fix --bin "clippyprob" -p clippyprob` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.56s

According to --broken-code, clippy attempts to add the following diff:

 7 + impl<T> Default for Foo<T> {
 8 +     fn default() -> Self {
 9 +         Self::new()
10 +     }
11 + }

Desired output:
Clippy fixes it and doesn't exit with compiler errors and a message telling me to open a bug report. Presumably it should be emitting something like this instead:

 7 + impl<T> Default for Foo<T> where T: Clone {
 8 +     fn default() -> Self {
 9 +         Self::new()
10 +     }
11 + }

Version

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: aarch64-apple-darwin
release: 1.92.0
LLVM version: 21.1.3

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thing

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions