From 296f597eae3b94a4ade454244e81485cd1b6a96b 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, 42 insertions(+), 4 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 1143b9d33606a..a3751afe9f76d 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,14 @@ 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) + && hir::lang_items::OPERATORS + .iter() + .filter_map(|&op| self.tcx.lang_items().get(op)) + .any(|op| { + // Ensure we only run this code on operators + op == trait_pred.skip_binder().trait_ref.def_id + }) { // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible @@ -891,9 +899,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref: ty::TraitRef::new( self.tcx, inner.trait_ref.def_id, - self.tcx.mk_args( - &[&[l_ty.into(), r_ty.into()], &inner.trait_ref.args[2..]] - .concat(), + self.tcx.mk_args_trait( + l_ty, + iter::once(r_ty.into()) + .chain(inner.trait_ref.args.iter().skip(2)), ), ), ..inner 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`.