From c29b565eba44383d46f86635c43aca0d035d0c63 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Wed, 27 Dec 2023 12:48:33 -0800 Subject: [PATCH] Fix ICE when suggesting dereferencing binop operands --- .../src/traits/error_reporting/suggestions.rs | 15 ++++++++++++ tests/ui/binop/binary-op-suggest-deref.rs | 8 +++++++ tests/ui/binop/binary-op-suggest-deref.stderr | 23 ++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) 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 1143b9d33606a..bd4991d34ef01 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -860,6 +860,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && let hir::Node::Expr(lhs) = self.tcx.hir_node(*lhs_hir_id) && let hir::Node::Expr(rhs) = self.tcx.hir_node(*rhs_hir_id) && let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) + && let trait_pred = predicate.unwrap_or(trait_pred) + // Only run this code on binary operators + && hir::lang_items::OPERATORS + .iter() + .filter_map(|&op| + (!matches!( + op, + LangItem::Neg | LangItem::Not | LangItem::Index | LangItem::IndexMut + )) + .then_some(self.tcx.lang_items().get(op)) + .flatten() + ) + .any(|op| { + op == trait_pred.skip_binder().trait_ref.def_id + }) { // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible diff --git a/tests/ui/binop/binary-op-suggest-deref.rs b/tests/ui/binop/binary-op-suggest-deref.rs index 57f24a4c28ed4..ae442a0d0b481 100644 --- a/tests/ui/binop/binary-op-suggest-deref.rs +++ b/tests/ui/binop/binary-op-suggest-deref.rs @@ -72,4 +72,12 @@ fn baz() { //~^ERROR can't compare `str` with `&String` [E0277] } +fn qux() { + // Issue #119352 + const FOO: i32 = 42; + let _ = FOO & (*"Sized".to_string().into_boxed_str()); + //~^ ERROR the size for values of type `str` cannot be known at compilation time + //~| ERROR no implementation for `i32 & str` [E0277] +} + fn main() {} diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr index f5de64e3ab1ae..289a821758795 100644 --- a/tests/ui/binop/binary-op-suggest-deref.stderr +++ b/tests/ui/binop/binary-op-suggest-deref.stderr @@ -300,7 +300,28 @@ help: consider dereferencing here LL | _ = partial[..3] == *string_ref; | + -error: aborting due to 22 previous errors +error[E0277]: no implementation for `i32 & str` + --> $DIR/binary-op-suggest-deref.rs:78:17 + | +LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); + | ^ no implementation for `i32 & str` + | + = help: the trait `BitAnd` is not implemented for `i32` + = help: the following other types implement trait `BitAnd`: + + > + <&'a i32 as BitAnd> + <&i32 as BitAnd<&i32>> + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/binary-op-suggest-deref.rs:78:17 + | +LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + +error: aborting due to 24 previous errors Some errors have detailed explanations: E0277, E0308, E0369. For more information about an error, try `rustc --explain E0277`.