about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-20 02:19:58 +0000
committerbors <bors@rust-lang.org>2021-08-20 02:19:58 +0000
commit7611fe438dae91084d17022e705bf64374d5ba4b (patch)
tree03dcc117fc7b641555c17f2608d71c317687a239
parentebedfedcd82678d5b0592227ca5e6ca31a5afb8f (diff)
parent9c32b5b3ba4a139e26d30486513929ce16391eec (diff)
downloadrust-7611fe438dae91084d17022e705bf64374d5ba4b.tar.gz
rust-7611fe438dae91084d17022e705bf64374d5ba4b.zip
Auto merge of #88039 - sexxi-goose:fix-87987, r=nikomatsakis
RFC2229 Only compute place if upvars can be resolved

Closes https://github.com/rust-lang/rust/issues/87987

This PR fixes an ICE when trying to unwrap an Err. This error appears when trying to convert a PlaceBuilder into Place when upvars can't yet be resolved. We should only try to convert a PlaceBuilder into Place if upvars can be resolved.

r? `@nikomatsakis`
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs38
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs21
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-87987.rs30
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-87987.stderr24
4 files changed, 90 insertions, 23 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 13cfc3695cc..1feb8b0d7a0 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -155,12 +155,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ascription: thir::Ascription { variance, user_ty, user_ty_span },
             } => {
                 // Apply the type ascription to the value at `match_pair.place`, which is the
-                candidate.ascriptions.push(Ascription {
-                    span: user_ty_span,
-                    user_ty,
-                    source: match_pair.place.clone().into_place(self.tcx, self.typeck_results),
-                    variance,
-                });
+                if let Ok(place_resolved) =
+                    match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+                {
+                    candidate.ascriptions.push(Ascription {
+                        span: user_ty_span,
+                        user_ty,
+                        source: place_resolved.into_place(self.tcx, self.typeck_results),
+                        variance,
+                    });
+                }
 
                 candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern));
 
@@ -173,15 +177,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             PatKind::Binding { name, mutability, mode, var, ty, ref subpattern, is_primary: _ } => {
-                candidate.bindings.push(Binding {
-                    name,
-                    mutability,
-                    span: match_pair.pattern.span,
-                    source: match_pair.place.clone().into_place(self.tcx, self.typeck_results),
-                    var_id: var,
-                    var_ty: ty,
-                    binding_mode: mode,
-                });
+                if let Ok(place_resolved) =
+                    match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results)
+                {
+                    candidate.bindings.push(Binding {
+                        name,
+                        mutability,
+                        span: match_pair.pattern.span,
+                        source: place_resolved.into_place(self.tcx, self.typeck_results),
+                        var_id: var,
+                        var_ty: ty,
+                        binding_mode: mode,
+                    });
+                }
 
                 if let Some(subpattern) = subpattern.as_ref() {
                     // this is the `x @ P` case; have to keep matching against `P` now
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index 3cf8ae6efd9..88dd76e37c1 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -31,15 +31,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         suffix: &'pat [Pat<'tcx>],
     ) {
         let tcx = self.tcx;
-        let (min_length, exact_size) = match place
-            .clone()
-            .into_place(tcx, self.typeck_results)
-            .ty(&self.local_decls, tcx)
-            .ty
-            .kind()
+        let (min_length, exact_size) = if let Ok(place_resolved) =
+            place.clone().try_upvars_resolved(tcx, self.typeck_results)
         {
-            ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
-            _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
+            match place_resolved
+                .into_place(tcx, self.typeck_results)
+                .ty(&self.local_decls, tcx)
+                .ty
+                .kind()
+            {
+                ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
+                _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
+            }
+        } else {
+            ((prefix.len() + suffix.len()).try_into().unwrap(), false)
         };
 
         match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87987.rs b/src/test/ui/closures/2229_closure_analysis/issue-87987.rs
new file mode 100644
index 00000000000..5dc2cb7e710
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-87987.rs
@@ -0,0 +1,30 @@
+// run-pass
+// edition:2021
+
+struct Props {
+    field_1: u32, //~ WARNING: field is never read: `field_1`
+    field_2: u32, //~ WARNING: field is never read: `field_2`
+}
+
+fn main() {
+    // Test 1
+    let props_2 = Props { //~ WARNING: unused variable: `props_2`
+        field_1: 1,
+        field_2: 1,
+    };
+
+    let _ = || {
+        let _: Props = props_2;
+    };
+
+    // Test 2
+    let mut arr = [1, 3, 4, 5];
+
+    let mref = &mut arr;
+
+    let _c = || match arr {
+        [_, _, _, _] => println!("A")
+    };
+
+    println!("{:#?}", mref);
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87987.stderr b/src/test/ui/closures/2229_closure_analysis/issue-87987.stderr
new file mode 100644
index 00000000000..aa7012c3618
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-87987.stderr
@@ -0,0 +1,24 @@
+warning: unused variable: `props_2`
+  --> $DIR/issue-87987.rs:11:9
+   |
+LL |     let props_2 = Props {
+   |         ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_props_2`
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: field is never read: `field_1`
+  --> $DIR/issue-87987.rs:5:5
+   |
+LL |     field_1: u32,
+   |     ^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: field is never read: `field_2`
+  --> $DIR/issue-87987.rs:6:5
+   |
+LL |     field_2: u32,
+   |     ^^^^^^^^^^^^
+
+warning: 3 warnings emitted
+