about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-03-02 21:23:20 +0900
committerGitHub <noreply@github.com>2021-03-02 21:23:20 +0900
commit2c40e13b849a76f8cae7c312216d43141e304dcf (patch)
tree63cf32a8156b54d3d884c803d4e6611f6d8d0074
parent43bcfdb0d027ad5eb702360b03f28c95bc899fe5 (diff)
parent9adb462e6c859cf2adf5948f9e32d706200b7b54 (diff)
downloadrust-2c40e13b849a76f8cae7c312216d43141e304dcf.tar.gz
rust-2c40e13b849a76f8cae7c312216d43141e304dcf.zip
Rollup merge of #82627 - JohnTitor:issue-82612, r=estebank
Erase late bound regions to avoid ICE

Fixes #82612, which is caused by #81769.

r? `@estebank`
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs3
-rw-r--r--src/test/ui/return/issue-82612-return-mutable-reference.rs24
-rw-r--r--src/test/ui/return/issue-82612-return-mutable-reference.stderr28
3 files changed, 54 insertions, 1 deletions
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 1f50ad5779e..9f15993e471 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 00000000000..db0d08ddb91
--- /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<I, V = I> {
+    values: Vec<Option<V>>,
+    marker: PhantomData<I>,
+}
+
+impl<I: SparseSetIndex, V> SparseArray<I, V> {
+    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 00000000000..a8045e043ad
--- /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`.