about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-08-13 15:29:10 +0200
committerGitHub <noreply@github.com>2021-08-13 15:29:10 +0200
commit717f9e37696703670108f47c5dff261ca9d4d834 (patch)
treedb82c2b0f4ad7eeda588219d9b8feaf2c7a4cbd6
parent2fc3c69e5419292e92663a5f1e39203478925661 (diff)
parenta0bf7d2cd3751de2b49ec66701aaa7cc41345c35 (diff)
downloadrust-717f9e37696703670108f47c5dff261ca9d4d834.tar.gz
rust-717f9e37696703670108f47c5dff261ca9d4d834.zip
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.
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs19
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.fixed9
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.rs9
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.stderr13
4 files changed, 42 insertions, 8 deletions
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
index 2be23159bf5..66e06325fa9 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
@@ -1,4 +1,5 @@
 use rustc_errors::{Applicability, DiagnosticBuilder};
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::mir::*;
 use rustc_middle::ty;
 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(_))) {
             let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
-                Some(def_id) => type_known_to_meet_bound_modulo_regions(
-                    &self.infcx,
-                    self.param_env,
-                    self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty),
-                    def_id,
-                    DUMMY_SP,
-                ),
+                Some(def_id) => self.infcx.tcx.infer_ctxt().enter(|infcx| {
+                    type_known_to_meet_bound_modulo_regions(
+                        &infcx,
+                        self.param_env,
+                        infcx
+                            .tcx
+                            .mk_imm_ref(infcx.tcx.lifetimes.re_erased, infcx.tcx.erase_regions(ty)),
+                        def_id,
+                        DUMMY_SP,
+                    )
+                }),
                 _ => false,
             };
             if suggest {
diff --git a/src/test/ui/suggestions/for-i-in-vec.fixed b/src/test/ui/suggestions/for-i-in-vec.fixed
index 223ddf0f0ad..4f2007befff 100644
--- a/src/test/ui/suggestions/for-i-in-vec.fixed
+++ b/src/test/ui/suggestions/for-i-in-vec.fixed
@@ -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() {}
diff --git a/src/test/ui/suggestions/for-i-in-vec.rs b/src/test/ui/suggestions/for-i-in-vec.rs
index 7942698cc8e..55fc7ad4e37 100644
--- a/src/test/ui/suggestions/for-i-in-vec.rs
+++ b/src/test/ui/suggestions/for-i-in-vec.rs
@@ -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() {}
diff --git a/src/test/ui/suggestions/for-i-in-vec.stderr b/src/test/ui/suggestions/for-i-in-vec.stderr
index 49cee6abc4e..c39363f762b 100644
--- a/src/test/ui/suggestions/for-i-in-vec.stderr
+++ b/src/test/ui/suggestions/for-i-in-vec.stderr
@@ -20,6 +20,17 @@ help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
 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`.