]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #66129 - Nadrieril:refactor-slice-pat-usefulness, r=varkor
authorbors <bors@rust-lang.org>
Tue, 12 Nov 2019 04:44:30 +0000 (04:44 +0000)
committerbors <bors@rust-lang.org>
Tue, 12 Nov 2019 04:44:30 +0000 (04:44 +0000)
Refactor slice pattern usefulness checking

As a follow up to https://github.com/rust-lang/rust/pull/65874, this PR changes how variable-length slice patterns are handled in usefulness checking. The objectives are: cleaning up that code to make it easier to understand, and paving the way to handling fixed-length slices more cleverly too, for https://github.com/rust-lang/rust/issues/53820.

Before this, variable-length slice patterns were eagerly expanded into a union of fixed-length slices. Now they have their own special constructor, which allows expanding them a bit more lazily.
As a nice side-effect, this improves diagnostics.

This PR shows a slight performance improvement, mostly due to https://github.com/rust-lang/rust/pull/66129/commits/149792b6080f40875c0072aae378a0eb31d23df0. This will probably have to be reverted in some way when we implement or-patterns.

1  2 
src/librustc_mir/hair/pattern/check_match.rs
src/librustc_mir/hair/pattern/mod.rs

index 52af8c13e78bedfc4aa633f100650c3be4fef223,a63a9a687d8d3a419f083ccf52adad885c615373..ffb3ae44ae1e95a16238459b74d429b73ead8755
@@@ -18,7 -18,7 +18,7 @@@ use rustc::hir::{self, Pat}
  
  use std::slice;
  
- use syntax_pos::{MultiSpan, Span, DUMMY_SP};
+ use syntax_pos::{MultiSpan, Span};
  
  crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
      let body_id = match tcx.hir().as_local_hir_id(def_id) {
@@@ -351,7 -351,7 +351,7 @@@ fn check_for_bindings_named_same_as_var
      pat.walk(|p| {
          if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
              if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
 -                if bm != ty::BindByValue(hir::MutImmutable) {
 +                if bm != ty::BindByValue(hir::Mutability::Immutable) {
                      // Nothing to check.
                      return true;
                  }
@@@ -491,7 -491,7 +491,7 @@@ fn check_not_useful
      matrix: &Matrix<'_, 'tcx>,
      hir_id: HirId,
  ) -> Result<(), Vec<super::Pat<'tcx>>> {
-     let wild_pattern = super::Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild };
+     let wild_pattern = super::Pat::wildcard_from_ty(ty);
      match is_useful(cx, matrix, &PatStack::from_pattern(&wild_pattern), ConstructWitness, hir_id) {
          NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
          UsefulWithWitness(pats) => Err(if pats.is_empty() {
@@@ -548,7 -548,7 +548,7 @@@ fn joined_uncovered_patterns(witnesses
  }
  
  fn pattern_not_covered_label(witnesses: &[super::Pat<'_>], joined_patterns: &str) -> String {
 -    format!("pattern{} {} not covered", rustc_errors::pluralise!(witnesses.len()), joined_patterns)
 +    format!("pattern{} {} not covered", rustc_errors::pluralize!(witnesses.len()), joined_patterns)
  }
  
  /// Point at the definition of non-covered `enum` variants.
index 0885c9578294d82030bfd39543582759d324ea0a,9e9f5f8fa90946fec1f8258a717b8c88c37395bc..f613f6f4b99b90a840fb19fe03cbd44adc0bb8f3
@@@ -26,7 -26,7 +26,7 @@@ use rustc_index::vec::Idx
  use std::cmp::Ordering;
  use std::fmt;
  use syntax::ast;
- use syntax_pos::Span;
+ use syntax_pos::{Span, DUMMY_SP};
  
  #[derive(Clone, Debug)]
  pub enum PatternError {
@@@ -55,6 -55,11 +55,11 @@@ pub struct Pat<'tcx> 
      pub kind: Box<PatKind<'tcx>>,
  }
  
+ impl<'tcx> Pat<'tcx> {
+     pub(crate) fn wildcard_from_ty(ty: Ty<'tcx>) -> Self {
+         Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) }
+     }
+ }
  
  #[derive(Copy, Clone, Debug, PartialEq)]
  pub struct PatTyProj<'tcx> {
@@@ -293,7 -298,10 +298,7 @@@ impl<'tcx> fmt::Display for Pat<'tcx> 
                  match self.ty.kind {
                      ty::Adt(def, _) if def.is_box() => write!(f, "box ")?,
                      ty::Ref(_, _, mutbl) => {
 -                        write!(f, "&")?;
 -                        if mutbl == hir::MutMutable {
 -                            write!(f, "mut ")?;
 -                        }
 +                        write!(f, "&{}", mutbl.prefix_str())?;
                      }
                      _ => bug!("{} is a bad Deref pattern type", self.ty)
                  }
@@@ -591,14 -599,14 +596,14 @@@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> 
                  let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
                                                           .expect("missing binding mode");
                  let (mutability, mode) = match bm {
 -                    ty::BindByValue(hir::MutMutable) =>
 +                    ty::BindByValue(hir::Mutability::Mutable) =>
                          (Mutability::Mut, BindingMode::ByValue),
 -                    ty::BindByValue(hir::MutImmutable) =>
 +                    ty::BindByValue(hir::Mutability::Immutable) =>
                          (Mutability::Not, BindingMode::ByValue),
 -                    ty::BindByReference(hir::MutMutable) =>
 +                    ty::BindByReference(hir::Mutability::Mutable) =>
                          (Mutability::Not, BindingMode::ByRef(
                              BorrowKind::Mut { allow_two_phase_borrow: false })),
 -                    ty::BindByReference(hir::MutImmutable) =>
 +                    ty::BindByReference(hir::Mutability::Immutable) =>
                          (Mutability::Not, BindingMode::ByRef(
                              BorrowKind::Shared)),
                  };