From c5c9f748296854c522395d917bbfc819f74f3a8a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Oct 2022 23:35:47 +0000 Subject: [PATCH] Erase regions before checking for default in uninitialized binding error --- .../src/diagnostics/conflict_errors.rs | 11 +++++- src/test/ui/borrowck/issue-103250.rs | 37 +++++++++++++++++++ src/test/ui/borrowck/issue-103250.stderr | 17 +++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/borrowck/issue-103250.rs create mode 100644 src/test/ui/borrowck/issue-103250.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2a8bd4d30ab..583bc2e281d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -492,10 +492,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { return false; }; + // Regions are already solved, so we must use a fresh InferCtxt, + // but the type has region variables, so erase those. tcx.infer_ctxt() .build() - .type_implements_trait(default_trait, ty, ty::List::empty(), param_env) - .may_apply() + .type_implements_trait( + default_trait, + tcx.erase_regions(ty), + ty::List::empty(), + param_env, + ) + .must_apply_modulo_regions() }; let assign_value = match ty.kind() { diff --git a/src/test/ui/borrowck/issue-103250.rs b/src/test/ui/borrowck/issue-103250.rs new file mode 100644 index 00000000000..46565f61ca9 --- /dev/null +++ b/src/test/ui/borrowck/issue-103250.rs @@ -0,0 +1,37 @@ +// edition:2021 + +type TranslateFn = Box String>; + +pub struct DeviceCluster { + devices: Vec, +} + +impl DeviceCluster { + pub async fn do_something(&mut self) -> Result> { + let mut last_error: Box; + + for device in &mut self.devices { + match device.do_something().await { + Ok(info) => { + return Ok(info); + } + Err(e) => {} + } + } + + Err(last_error) + //~^ ERROR used binding `last_error` isn't initialized + } +} + +pub struct Device { + translate_fn: Option, +} + +impl Device { + pub async fn do_something(&mut self) -> Result> { + Ok(String::from("")) + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-103250.stderr b/src/test/ui/borrowck/issue-103250.stderr new file mode 100644 index 00000000000..4a237835222 --- /dev/null +++ b/src/test/ui/borrowck/issue-103250.stderr @@ -0,0 +1,17 @@ +error[E0381]: used binding `last_error` isn't initialized + --> $DIR/issue-103250.rs:22:13 + | +LL | let mut last_error: Box; + | -------------- binding declared here but left uninitialized +... +LL | Err(last_error) + | ^^^^^^^^^^ `last_error` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let mut last_error: Box = todo!(); + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`.