From 7a378dd0fb2b383be75722666d8a3c761882af15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20A=2E=20Muci=C3=B1o?= Date: Sun, 27 Nov 2022 20:50:13 -0600 Subject: [PATCH] Avoid ICE if the Clone trait is not found while building error suggestions --- .../src/diagnostics/conflict_errors.rs | 16 +++++++------- .../missing-clone-for-suggestion.rs | 20 ++++++++++++++++++ .../missing-clone-for-suggestion.stderr | 21 +++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/lang-items/missing-clone-for-suggestion.rs create mode 100644 src/test/ui/lang-items/missing-clone-for-suggestion.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 5ec9c5f5c1b55..d221da5c17ed0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -732,13 +732,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); - if infcx - .type_implements_trait( - tcx.lang_items().clone_trait().unwrap(), - [tcx.erase_regions(ty)], - self.param_env, - ) - .must_apply_modulo_regions() + + if let Some(clone_trait_def) = tcx.lang_items().clone_trait() + && infcx + .type_implements_trait( + clone_trait_def, + [tcx.erase_regions(ty)], + self.param_env, + ) + .must_apply_modulo_regions() { err.span_suggestion_verbose( span.shrink_to_hi(), diff --git a/src/test/ui/lang-items/missing-clone-for-suggestion.rs b/src/test/ui/lang-items/missing-clone-for-suggestion.rs new file mode 100644 index 0000000000000..e8290c0098afd --- /dev/null +++ b/src/test/ui/lang-items/missing-clone-for-suggestion.rs @@ -0,0 +1,20 @@ +// Avoid panicking if the Clone trait is not found while building error suggestions +// See #104870 + +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +fn g(x: T) {} + +fn f(x: *mut u8) { + g(x); + g(x); //~ ERROR use of moved value: `x` +} + +fn main() {} diff --git a/src/test/ui/lang-items/missing-clone-for-suggestion.stderr b/src/test/ui/lang-items/missing-clone-for-suggestion.stderr new file mode 100644 index 0000000000000..35783a1be78ad --- /dev/null +++ b/src/test/ui/lang-items/missing-clone-for-suggestion.stderr @@ -0,0 +1,21 @@ +error[E0382]: use of moved value: `x` + --> $DIR/missing-clone-for-suggestion.rs:17:7 + | +LL | fn f(x: *mut u8) { + | - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait +LL | g(x); + | - value moved here +LL | g(x); + | ^ value used here after move + | +note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary + --> $DIR/missing-clone-for-suggestion.rs:13:12 + | +LL | fn g(x: T) {} + | - ^ this parameter takes ownership of the value + | | + | in this function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`.