about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-08-12 20:16:25 +0100
committervarkor <github@varkor.com>2018-08-16 20:09:05 +0100
commit4aa929cf8b47840671bf2c9a84f70abaead70a85 (patch)
tree5e20ddbdd5e22729d27e8087f0caeea597457e8b
parentbfc0807b28fe51f71fcf30cd60ddc8a09e4f730d (diff)
downloadrust-4aa929cf8b47840671bf2c9a84f70abaead70a85.tar.gz
rust-4aa929cf8b47840671bf2c9a84f70abaead70a85.zip
Move witnesses inside push_wild_constructor
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs90
1 files changed, 41 insertions, 49 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 00f7da43291..065fbeda153 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -351,15 +351,38 @@ impl<'tcx> Witness<'tcx> {
         ty: Ty<'tcx>)
         -> Self
     {
-        let sub_pattern_tys = constructor_sub_pattern_tys(cx, ctor, ty);
-        self.0.extend(sub_pattern_tys.into_iter().map(|ty| {
-            Pattern {
-                ty,
-                span: DUMMY_SP,
-                kind: box PatternKind::Wild,
+        // If we've been trying to exhaustively match over the domain of values for a type,
+        // then we can construct witnesses directly corresponding to the missing ranges of values,
+        // giving far more precise diagnostics.
+        // `ConstantValue` and `ConstantRange` only occur in practice when doing exhaustive value
+        // matching (exhaustive_integer_patterns).
+        match ctor {
+            ConstantValue(value) => {
+                Witness(vec![Pattern {
+                    ty,
+                    span: DUMMY_SP,
+                    kind: box PatternKind::Constant { value },
+                }])
+            }
+            ConstantRange(lo, hi, end) => {
+                Witness(vec![Pattern {
+                    ty,
+                    span: DUMMY_SP,
+                    kind: box PatternKind::Range { lo, hi, end: *end },
+                }])
             }
-        }));
-        self.apply_constructor(cx, ctor, ty)
+            _ => {
+                let sub_pattern_tys = constructor_sub_pattern_tys(cx, ctor, ty);
+                self.0.extend(sub_pattern_tys.into_iter().map(|ty| {
+                    Pattern {
+                        ty,
+                        span: DUMMY_SP,
+                        kind: box PatternKind::Wild,
+                    }
+                }));
+                self.apply_constructor(cx, ctor, ty)
+            }
+        }
     }
 
 
@@ -976,7 +999,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                     // `used_ctors` is empty.
                     let new_witnesses = if is_non_exhaustive || used_ctors.is_empty() {
                         // All constructors are unused. Add wild patterns
-                        // rather than each individual constructor
+                        // rather than each individual constructor.
                         pats.into_iter().map(|mut witness| {
                             witness.0.push(Pattern {
                                 ty: pcx.ty,
@@ -986,46 +1009,15 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                             witness
                         }).collect()
                     } else {
-                        if consider_value_constructors {
-                            // If we've been trying to exhaustively match
-                            // over the domain of values for a type,
-                            // then we can provide better diagnostics
-                            // regarding which values were missing.
-                            missing_ctors.into_iter().map(|ctor| {
-                                match ctor {
-                                    // A constant range of length 1 is simply
-                                    // a constant value.
-                                    ConstantValue(value) => {
-                                        Witness(vec![Pattern {
-                                            ty: pcx.ty,
-                                            span: DUMMY_SP,
-                                            kind: box PatternKind::Constant { value },
-                                        }])
-                                    }
-                                    // We always report missing intervals
-                                    // in terms of inclusive ranges.
-                                    ConstantRange(lo, hi, end) => {
-                                        Witness(vec![Pattern {
-                                            ty: pcx.ty,
-                                            span: DUMMY_SP,
-                                            kind: box PatternKind::Range { lo, hi, end },
-                                        }])
-                                    },
-                                    _ => bug!("`ranges_subtract_pattern` should only produce \
-                                               `ConstantRange`s"),
-                                }
-                            }).collect()
-                        } else {
-                            pats.into_iter().flat_map(|witness| {
-                                missing_ctors.iter().map(move |ctor| {
-                                    // Extends the witness with a "wild" version of this
-                                    // constructor, that matches everything that can be built with
-                                    // it. For example, if `ctor` is a `Constructor::Variant` for
-                                    // `Option::Some`, this pushes the witness for `Some(_)`.
-                                    witness.clone().push_wild_constructor(cx, ctor, pcx.ty)
-                                })
-                            }).collect()
-                        }
+                        pats.into_iter().flat_map(|witness| {
+                            missing_ctors.iter().map(move |ctor| {
+                                // Extends the witness with a "wild" version of this
+                                // constructor, that matches everything that can be built with
+                                // it. For example, if `ctor` is a `Constructor::Variant` for
+                                // `Option::Some`, this pushes the witness for `Some(_)`.
+                                witness.clone().push_wild_constructor(cx, ctor, pcx.ty)
+                            })
+                        }).collect()
                     };
                     UsefulWithWitness(new_witnesses)
                 }