mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #91544 - rukai:91492, r=wesleywiser
Fix duplicate derive clone suggestion closes https://github.com/rust-lang/rust/issues/91492 The addition of: ```rust derives.sort(); derives.dedup(); ``` is what actually solves the problem. The rest is just cleanup. I want to improve the diagnostic message to provide the suggestion as a proper diff but ran into some problems, so I'll attempt that again in a follow up PR.
This commit is contained in:
commit
d8bf974df5
@ -1195,11 +1195,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn suggest_derive(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
unsatisfied_predicates: &Vec<(
|
||||
unsatisfied_predicates: &[(
|
||||
ty::Predicate<'tcx>,
|
||||
Option<ty::Predicate<'tcx>>,
|
||||
Option<ObligationCause<'tcx>>,
|
||||
)>,
|
||||
)],
|
||||
) {
|
||||
let mut derives = Vec::<(String, Span, String)>::new();
|
||||
let mut traits = Vec::<Span>::new();
|
||||
@ -1236,23 +1236,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
traits.push(self.tcx.def_span(trait_pred.def_id()));
|
||||
}
|
||||
}
|
||||
derives.sort();
|
||||
let derives_grouped = derives.into_iter().fold(
|
||||
Vec::<(String, Span, String)>::new(),
|
||||
|mut acc, (self_name, self_span, trait_name)| {
|
||||
if let Some((acc_self_name, _, ref mut traits)) = acc.last_mut() {
|
||||
if acc_self_name == &self_name {
|
||||
traits.push_str(format!(", {}", trait_name).as_str());
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
acc.push((self_name, self_span, trait_name));
|
||||
acc
|
||||
},
|
||||
);
|
||||
traits.sort();
|
||||
traits.dedup();
|
||||
|
||||
derives.sort();
|
||||
derives.dedup();
|
||||
|
||||
let mut derives_grouped = Vec::<(String, Span, String)>::new();
|
||||
for (self_name, self_span, trait_name) in derives.into_iter() {
|
||||
if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
|
||||
{
|
||||
if last_self_name == &self_name {
|
||||
last_trait_names.push_str(format!(", {}", trait_name).as_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
derives_grouped.push((self_name, self_span, trait_name));
|
||||
}
|
||||
|
||||
let len = traits.len();
|
||||
if len > 0 {
|
||||
let span: MultiSpan = traits.into();
|
||||
|
25
src/test/ui/derives/issue-91492.rs
Normal file
25
src/test/ui/derives/issue-91492.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Reproduce the issue with vec
|
||||
pub struct NoDerives;
|
||||
fn fun1(foo: &mut Vec<NoDerives>, bar: &[NoDerives]) {
|
||||
foo.extend_from_slice(bar); //~ ERROR
|
||||
}
|
||||
|
||||
// Reproduce the issue with vec
|
||||
// and demonstrate that other derives are ignored in the suggested output
|
||||
#[derive(Default, PartialEq)]
|
||||
pub struct SomeDerives;
|
||||
fn fun2(foo: &mut Vec<SomeDerives>, bar: &[SomeDerives]) {
|
||||
foo.extend_from_slice(bar); //~ ERROR
|
||||
}
|
||||
|
||||
// Try and fail to reproduce the issue without vec.
|
||||
// No idea why it doesnt reproduce the issue but its still a useful test case.
|
||||
struct Object<T, A>(T, A);
|
||||
impl<T: Clone, A: Default> Object<T, A> {
|
||||
fn use_clone(&self) {}
|
||||
}
|
||||
fn fun3(foo: Object<NoDerives, SomeDerives>) {
|
||||
foo.use_clone(); //~ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
54
src/test/ui/derives/issue-91492.stderr
Normal file
54
src/test/ui/derives/issue-91492.stderr
Normal file
@ -0,0 +1,54 @@
|
||||
error[E0599]: the method `extend_from_slice` exists for mutable reference `&mut Vec<NoDerives>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-91492.rs:4:9
|
||||
|
|
||||
LL | pub struct NoDerives;
|
||||
| --------------------- doesn't satisfy `NoDerives: Clone`
|
||||
LL | fn fun1(foo: &mut Vec<NoDerives>, bar: &[NoDerives]) {
|
||||
LL | foo.extend_from_slice(bar);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`NoDerives: Clone`
|
||||
help: consider annotating `NoDerives` with `#[derive(Clone)]`
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
|
|
||||
|
||||
error[E0599]: the method `extend_from_slice` exists for mutable reference `&mut Vec<SomeDerives>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-91492.rs:12:9
|
||||
|
|
||||
LL | pub struct SomeDerives;
|
||||
| ----------------------- doesn't satisfy `SomeDerives: Clone`
|
||||
LL | fn fun2(foo: &mut Vec<SomeDerives>, bar: &[SomeDerives]) {
|
||||
LL | foo.extend_from_slice(bar);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`SomeDerives: Clone`
|
||||
help: consider annotating `SomeDerives` with `#[derive(Clone)]`
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
|
|
||||
|
||||
error[E0599]: the method `use_clone` exists for struct `Object<NoDerives, SomeDerives>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-91492.rs:22:9
|
||||
|
|
||||
LL | pub struct NoDerives;
|
||||
| --------------------- doesn't satisfy `NoDerives: Clone`
|
||||
...
|
||||
LL | struct Object<T, A>(T, A);
|
||||
| -------------------------- method `use_clone` not found for this
|
||||
...
|
||||
LL | foo.use_clone();
|
||||
| ^^^^^^^^^ method cannot be called on `Object<NoDerives, SomeDerives>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`NoDerives: Clone`
|
||||
help: consider annotating `NoDerives` with `#[derive(Clone)]`
|
||||
|
|
||||
LL | #[derive(Clone)]
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user