From f74eee2fa6620ecb88070ed2eb2dfd7ba12e0b63 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Tue, 1 Aug 2023 16:57:43 -0700 Subject: [PATCH 1/4] [rustc_span][perf] Remove unnecessary string joins and allocs. Comparing vectors of string parts yields the same result but avoids unnecessary `join` and potential allocation for resulting `String`. This code is cold so it's unlikely to have any measurable impact, but considering but since it's also simpler, why not? :) --- compiler/rustc_span/src/edit_distance.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 259f423865480..0ce099387f416 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -247,9 +247,9 @@ fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option String { +fn sort_by_words(name: &str) -> Vec<&str> { let mut split_words: Vec<&str> = name.split('_').collect(); // We are sorting primitive &strs and can use unstable sort here. split_words.sort_unstable(); - split_words.join("_") + split_words } From 3635b48973ee17951c81769e4a62b0a4891a2501 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 22 Jul 2023 10:13:49 +0800 Subject: [PATCH 2/4] Fix wrong span for trait selection failure error reporting --- .../src/traits/error_reporting/mod.rs | 8 ++++++ tests/ui/dst/issue-113447.fixed | 25 +++++++++++++++++++ tests/ui/dst/issue-113447.rs | 25 +++++++++++++++++++ tests/ui/dst/issue-113447.stderr | 25 +++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 tests/ui/dst/issue-113447.fixed create mode 100644 tests/ui/dst/issue-113447.rs create mode 100644 tests/ui/dst/issue-113447.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index eae13eb630290..4d85e2b60893e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2987,6 +2987,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { unsatisfied_const: bool, ) { let body_def_id = obligation.cause.body_id; + let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } = + obligation.cause.code() + { + *rhs_span + } else { + span + }; + // Try to report a help message if is_fn_trait && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( diff --git a/tests/ui/dst/issue-113447.fixed b/tests/ui/dst/issue-113447.fixed new file mode 100644 index 0000000000000..536f680f697c7 --- /dev/null +++ b/tests/ui/dst/issue-113447.fixed @@ -0,0 +1,25 @@ +// run-rustfix + +pub struct Bytes; + +impl Bytes { + pub fn as_slice(&self) -> &[u8] { + todo!() + } +} + +impl PartialEq<[u8]> for Bytes { + fn eq(&self, other: &[u8]) -> bool { + self.as_slice() == other + } +} + +impl PartialEq for &[u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == **self + } +} + +fn main() { + let _ = &[0u8] == &[0xAA][..]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]` +} diff --git a/tests/ui/dst/issue-113447.rs b/tests/ui/dst/issue-113447.rs new file mode 100644 index 0000000000000..c10a4f2ff8ec4 --- /dev/null +++ b/tests/ui/dst/issue-113447.rs @@ -0,0 +1,25 @@ +// run-rustfix + +pub struct Bytes; + +impl Bytes { + pub fn as_slice(&self) -> &[u8] { + todo!() + } +} + +impl PartialEq<[u8]> for Bytes { + fn eq(&self, other: &[u8]) -> bool { + self.as_slice() == other + } +} + +impl PartialEq for &[u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == **self + } +} + +fn main() { + let _ = &[0u8] == [0xAA]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]` +} diff --git a/tests/ui/dst/issue-113447.stderr b/tests/ui/dst/issue-113447.stderr new file mode 100644 index 0000000000000..240553a675bfe --- /dev/null +++ b/tests/ui/dst/issue-113447.stderr @@ -0,0 +1,25 @@ +error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]` + --> $DIR/issue-113447.rs:24:20 + | +LL | let _ = &[0u8] == [0xAA]; + | ^^ no implementation for `&[u8; 1] == [{integer}; 1]` + | + = help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]` + = help: the following other types implement trait `PartialEq`: + <[A; N] as PartialEq<[B; N]>> + <[A; N] as PartialEq<[B]>> + <[A; N] as PartialEq<&[B]>> + <[A; N] as PartialEq<&mut [B]>> + <[T] as PartialEq>> + <[A] as PartialEq<[B]>> + <[B] as PartialEq<[A; N]>> + <&[u8] as PartialEq> + and 4 others +help: convert the array to a `&[u8]` slice instead + | +LL | let _ = &[0u8] == &[0xAA][..]; + | + ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From cde8f06503d06d254aa4191438588ba9b2a36b77 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Aug 2023 00:14:13 +0800 Subject: [PATCH 3/4] enable suggest convert to slice for binary operation --- .../src/traits/error_reporting/suggestions.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 46c31c77613ef..bde72c691dc99 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3953,9 +3953,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { candidate_impls: &[ImplCandidate<'tcx>], span: Span, ) { - // We can only suggest the slice coersion for function arguments since the suggestion - // would make no sense in turbofish or call - let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else { + // We can only suggest the slice coersion for function and binary operation arguments, + // since the suggestion would make no sense in turbofish or call + let (ObligationCauseCode::BinOp { .. } + | ObligationCauseCode::FunctionArgumentObligation { .. }) = obligation.cause.code() + else { return; }; From 97aa4ba171bc78ccbb96b72bd2eef056ad2ece73 Mon Sep 17 00:00:00 2001 From: Sebastian Toh Date: Fri, 4 Aug 2023 20:12:20 +0800 Subject: [PATCH 4/4] Fix unwrap on None --- .../src/fn_ctxt/suggestions.rs | 3 +- tests/ui/typeck/issue-114423.rs | 15 ++++++ tests/ui/typeck/issue-114423.stderr | 52 +++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/ui/typeck/issue-114423.rs create mode 100644 tests/ui/typeck/issue-114423.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index d4edd08d30246..89bbb4c22037e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1620,8 +1620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .enumerate() .filter(|x| x.1.hir_id == *hir_id) - .map(|(i, _)| init_tup.get(i).unwrap()) - .next() + .find_map(|(i, _)| init_tup.get(i)) { self.note_type_is_not_clone_inner_expr(init) } else { diff --git a/tests/ui/typeck/issue-114423.rs b/tests/ui/typeck/issue-114423.rs new file mode 100644 index 0000000000000..da2dae1c46b06 --- /dev/null +++ b/tests/ui/typeck/issue-114423.rs @@ -0,0 +1,15 @@ +struct RGB { + g: f64, + b: f64, +} + +fn main() { + let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + //~^ ERROR cannot find value `e` in this scope + //~| ERROR cannot find value `e` in this scope + //~| ERROR mismatched types + let _ = RGB { r, g, b }; + //~^ ERROR cannot find value `g` in this scope + //~| ERROR struct `RGB` has no field named `r` + //~| ERROR mismatched types +} diff --git a/tests/ui/typeck/issue-114423.stderr b/tests/ui/typeck/issue-114423.stderr new file mode 100644 index 0000000000000..c20a4391297a2 --- /dev/null +++ b/tests/ui/typeck/issue-114423.stderr @@ -0,0 +1,52 @@ +error[E0425]: cannot find value `e` in this scope + --> $DIR/issue-114423.rs:7:51 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | ^ not found in this scope + +error[E0425]: cannot find value `e` in this scope + --> $DIR/issue-114423.rs:7:62 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | ^ not found in this scope + +error[E0425]: cannot find value `g` in this scope + --> $DIR/issue-114423.rs:11:22 + | +LL | let _ = RGB { r, g, b }; + | ^ help: a local variable with a similar name exists: `b` + +error[E0308]: mismatched types + --> $DIR/issue-114423.rs:7:50 + | +LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); + | --------------- ^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements + | | + | expected due to this + | + = note: expected tuple `(f32, f32, f32)` + found tuple `(f32, f32)` + +error[E0560]: struct `RGB` has no field named `r` + --> $DIR/issue-114423.rs:11:19 + | +LL | let _ = RGB { r, g, b }; + | ^ `RGB` does not have this field + | + = note: all struct fields are already assigned + +error[E0308]: mismatched types + --> $DIR/issue-114423.rs:11:25 + | +LL | let _ = RGB { r, g, b }; + | ^ expected `f64`, found `f32` + | +help: you can convert an `f32` to an `f64` + | +LL | let _ = RGB { r, g, b: b.into() }; + | ++ +++++++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0425, E0560. +For more information about an error, try `rustc --explain E0308`.