Rollup merge of #87795 - estebank:erase-lifetimes-in-suggestion, r=oli-obk

Avoid ICE caused by suggestion

When suggesting dereferencing something that can be iterable in a `for`
loop, erase lifetimes and use a fresh `ty::ParamEnv` to avoid 'region
constraints already solved' panic.

Fix #87657, fix #87709, fix #87651.
This commit is contained in:
Guillaume Gomez 2021-08-13 15:29:10 +02:00 committed by GitHub
commit 717f9e3769
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 8 deletions

View File

@ -1,4 +1,5 @@
use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::source_map::DesugaringKind; use rustc_span::source_map::DesugaringKind;
@ -409,13 +410,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
); );
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) { } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) { let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
Some(def_id) => type_known_to_meet_bound_modulo_regions( Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
&self.infcx, type_known_to_meet_bound_modulo_regions(
self.param_env, &infcx,
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty), self.param_env,
def_id, infcx
DUMMY_SP, .tcx
), .mk_imm_ref(infcx.tcx.lifetimes.re_erased, infcx.tcx.erase_regions(ty)),
def_id,
DUMMY_SP,
)
}),
_ => false, _ => false,
}; };
if suggest { if suggest {

View File

@ -15,4 +15,13 @@ impl Foo {
} }
} }
const LOADERS: &Vec<&'static u8> = &Vec::new();
pub fn break_code() -> Option<&'static u8> {
for loader in &*LOADERS { //~ ERROR cannot move out of a shared reference
return Some(loader);
}
None
}
fn main() {} fn main() {}

View File

@ -15,4 +15,13 @@ impl Foo {
} }
} }
const LOADERS: &Vec<&'static u8> = &Vec::new();
pub fn break_code() -> Option<&'static u8> {
for loader in *LOADERS { //~ ERROR cannot move out of a shared reference
return Some(loader);
}
None
}
fn main() {} fn main() {}

View File

@ -20,6 +20,17 @@ help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
LL | for _ in &self.h { LL | for _ in &self.h {
| + | +
error: aborting due to 2 previous errors error[E0507]: cannot move out of a shared reference
--> $DIR/for-i-in-vec.rs:21:19
|
LL | for loader in *LOADERS {
| ^^^^^^^^ move occurs because value has type `Vec<&u8>`, which does not implement the `Copy` trait
|
help: consider iterating over a slice of the `Vec<&u8>`'s content
|
LL | for loader in &*LOADERS {
| +
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0507`. For more information about this error, try `rustc --explain E0507`.