From 9adb462e6c859cf2adf5948f9e32d706200b7b54 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 28 Feb 2021 22:20:15 +0900 Subject: [PATCH] Erase late bound regions to avoid ICE --- .../src/check/fn_ctxt/suggestions.rs | 3 +- .../issue-82612-return-mutable-reference.rs | 24 ++++++++++++++++ ...ssue-82612-return-mutable-reference.stderr | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/return/issue-82612-return-mutable-reference.rs create mode 100644 src/test/ui/return/issue-82612-return-mutable-reference.stderr diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 1f50ad5779e0f..9f15993e4718c 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -11,7 +11,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, ItemKind, Node}; use rustc_infer::infer; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Binder, Ty}; use rustc_span::symbol::kw; use std::iter; @@ -487,6 +487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let found = self.resolve_vars_with_obligations(found); if let hir::FnRetTy::Return(ty) = fn_decl.output { let ty = AstConv::ast_ty_to_ty(self, ty); + let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty)); let ty = self.normalize_associated_types_in(expr.span, ty); if self.can_coerce(found, ty) { err.multipart_suggestion( diff --git a/src/test/ui/return/issue-82612-return-mutable-reference.rs b/src/test/ui/return/issue-82612-return-mutable-reference.rs new file mode 100644 index 0000000000000..db0d08ddb915b --- /dev/null +++ b/src/test/ui/return/issue-82612-return-mutable-reference.rs @@ -0,0 +1,24 @@ +// Regression test for #82612. + +use std::marker::PhantomData; + +pub trait SparseSetIndex { + fn sparse_set_index(&self) -> usize; +} +pub struct SparseArray { + values: Vec>, + marker: PhantomData, +} + +impl SparseArray { + pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V { + let index = index.sparse_set_index(); + if index < self.values.len() { + let value = unsafe { self.values.get_unchecked_mut(index) }; + value.get_or_insert_with(func) //~ ERROR mismatched types + } + unsafe { self.values.get_unchecked_mut(index).as_mut().unwrap() } + } +} + +fn main() {} diff --git a/src/test/ui/return/issue-82612-return-mutable-reference.stderr b/src/test/ui/return/issue-82612-return-mutable-reference.stderr new file mode 100644 index 0000000000000..a8045e043ad89 --- /dev/null +++ b/src/test/ui/return/issue-82612-return-mutable-reference.stderr @@ -0,0 +1,28 @@ +error[E0308]: mismatched types + --> $DIR/issue-82612-return-mutable-reference.rs:18:13 + | +LL | / if index < self.values.len() { +LL | | let value = unsafe { self.values.get_unchecked_mut(index) }; +LL | | value.get_or_insert_with(func) + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&mut V` +LL | | } + | |_________- expected this to be `()` + | + = note: expected unit type `()` + found mutable reference `&mut V` +help: consider using a semicolon here + | +LL | value.get_or_insert_with(func); + | ^ +help: consider using a semicolon here + | +LL | }; + | ^ +help: you might have meant to return this value + | +LL | return value.get_or_insert_with(func); + | ^^^^^^ ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.