Skip to content

Commit 9adb462

Browse files
committed
Erase late bound regions to avoid ICE
1 parent 6e2801c commit 9adb462

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

Diff for: compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{ExprKind, ItemKind, Node};
1212
use rustc_infer::infer;
1313
use rustc_middle::lint::in_external_macro;
14-
use rustc_middle::ty::{self, Ty};
14+
use rustc_middle::ty::{self, Binder, Ty};
1515
use rustc_span::symbol::kw;
1616

1717
use std::iter;
@@ -487,6 +487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
487487
let found = self.resolve_vars_with_obligations(found);
488488
if let hir::FnRetTy::Return(ty) = fn_decl.output {
489489
let ty = AstConv::ast_ty_to_ty(self, ty);
490+
let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty));
490491
let ty = self.normalize_associated_types_in(expr.span, ty);
491492
if self.can_coerce(found, ty) {
492493
err.multipart_suggestion(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Regression test for #82612.
2+
3+
use std::marker::PhantomData;
4+
5+
pub trait SparseSetIndex {
6+
fn sparse_set_index(&self) -> usize;
7+
}
8+
pub struct SparseArray<I, V = I> {
9+
values: Vec<Option<V>>,
10+
marker: PhantomData<I>,
11+
}
12+
13+
impl<I: SparseSetIndex, V> SparseArray<I, V> {
14+
pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
15+
let index = index.sparse_set_index();
16+
if index < self.values.len() {
17+
let value = unsafe { self.values.get_unchecked_mut(index) };
18+
value.get_or_insert_with(func) //~ ERROR mismatched types
19+
}
20+
unsafe { self.values.get_unchecked_mut(index).as_mut().unwrap() }
21+
}
22+
}
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-82612-return-mutable-reference.rs:18:13
3+
|
4+
LL | / if index < self.values.len() {
5+
LL | | let value = unsafe { self.values.get_unchecked_mut(index) };
6+
LL | | value.get_or_insert_with(func)
7+
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&mut V`
8+
LL | | }
9+
| |_________- expected this to be `()`
10+
|
11+
= note: expected unit type `()`
12+
found mutable reference `&mut V`
13+
help: consider using a semicolon here
14+
|
15+
LL | value.get_or_insert_with(func);
16+
| ^
17+
help: consider using a semicolon here
18+
|
19+
LL | };
20+
| ^
21+
help: you might have meant to return this value
22+
|
23+
LL | return value.get_or_insert_with(func);
24+
| ^^^^^^ ^
25+
26+
error: aborting due to previous error
27+
28+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)