about summary refs log tree commit diff
diff options
context:
space:
mode:
authorb-naber <b_naber@gmx.de>2023-07-10 22:11:21 +0000
committerb-naber <b_naber@gmx.de>2023-07-17 22:06:32 +0000
commit65f92a52bfee3f2d989695b80c36906404fffeca (patch)
tree10cd78ae0ba25f4613c38c1f310581a92bde17df
parent1c217b6d8a55865535d06752a65ba2ae24f7b349 (diff)
downloadrust-65f92a52bfee3f2d989695b80c36906404fffeca.tar.gz
rust-65f92a52bfee3f2d989695b80c36906404fffeca.zip
address review
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs117
-rw-r--r--tests/ui/array-slice-vec/slice-pat-type-mismatches.rs5
-rw-r--r--tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr16
-rw-r--r--tests/ui/pattern/issue-76342.rs3
-rw-r--r--tests/ui/pattern/slice-pattern-refutable.rs2
-rw-r--r--tests/ui/pattern/slice-pattern-refutable.stderr6
8 files changed, 51 insertions, 102 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 2c1543ca1d5..70ae21d9b98 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1478,7 +1478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let pat_ty = self.node_ty(decl.pat.hir_id);
         self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty);
 
-        if let Some(blk) = decl.origin.try_get_els() {
+        if let Some(blk) = decl.origin.try_get_else() {
             let previous_diverges = self.diverges.get();
             let else_ty = self.check_block_with_expected(blk, NoExpectation);
             let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index b2b6ad0d101..ed4c63f171c 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -21,7 +21,7 @@ pub(super) enum DeclOrigin<'a> {
 }
 
 impl<'a> DeclOrigin<'a> {
-    pub(super) fn try_get_els(&self) -> Option<&'a hir::Block<'a>> {
+    pub(super) fn try_get_else(&self) -> Option<&'a hir::Block<'a>> {
         match self {
             Self::LocalDecl { els } => *els,
             Self::LetExpr => None,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 659223a377c..8e14212fd56 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -163,7 +163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Conversely, inside this module, `check_pat_top` should never be used.
     #[instrument(level = "debug", skip(self, pat_info))]
     fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) {
-        let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
+        let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
         let path_res = match &pat.kind {
             PatKind::Path(qpath) => {
                 Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
@@ -172,76 +172,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
         let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
+        let pat_info =
+            PatInfo { binding_mode: def_bm, top_info: ti, decl_origin: pat_info.decl_origin };
 
         let ty = match pat.kind {
             PatKind::Wild => expected,
             PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
             PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
-            PatKind::Binding(ba, var_id, _, sub) => self.check_pat_ident(
-                pat,
-                ba,
-                var_id,
-                sub,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
-            PatKind::TupleStruct(ref qpath, subpats, ddpos) => self.check_pat_tuple_struct(
-                pat,
-                qpath,
-                subpats,
-                ddpos,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
+            PatKind::Binding(ba, var_id, _, sub) => {
+                self.check_pat_ident(pat, ba, var_id, sub, expected, pat_info)
+            }
+            PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
+                self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info)
+            }
             PatKind::Path(ref qpath) => {
                 self.check_pat_path(pat, qpath, path_res.unwrap(), expected, ti)
             }
-            PatKind::Struct(ref qpath, fields, has_rest_pat) => self.check_pat_struct(
-                pat,
-                qpath,
-                fields,
-                has_rest_pat,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
+            PatKind::Struct(ref qpath, fields, has_rest_pat) => {
+                self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, pat_info)
+            }
             PatKind::Or(pats) => {
                 for pat in pats {
-                    self.check_pat(
-                        pat,
-                        expected,
-                        PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-                    );
+                    self.check_pat(pat, expected, pat_info);
                 }
                 expected
             }
-            PatKind::Tuple(elements, ddpos) => self.check_pat_tuple(
-                pat.span,
-                elements,
-                ddpos,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
-            PatKind::Box(inner) => self.check_pat_box(
-                pat.span,
-                inner,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
-            PatKind::Ref(inner, mutbl) => self.check_pat_ref(
-                pat,
-                inner,
-                mutbl,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
-            PatKind::Slice(before, slice, after) => self.check_pat_slice(
-                pat.span,
-                before,
-                slice,
-                after,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            ),
+            PatKind::Tuple(elements, ddpos) => {
+                self.check_pat_tuple(pat.span, elements, ddpos, expected, pat_info)
+            }
+            PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
+            PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
+            PatKind::Slice(before, slice, after) => {
+                self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
+            }
         };
 
         self.write_ty(pat.hir_id, ty);
@@ -624,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         pat_info: PatInfo<'tcx, '_>,
     ) -> Ty<'tcx> {
-        let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
+        let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info;
 
         // Determine the binding mode...
         let bm = match ba {
@@ -663,11 +626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if let Some(p) = sub {
-            self.check_pat(
-                p,
-                expected,
-                PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-            );
+            self.check_pat(p, expected, pat_info);
         }
 
         local_ty
@@ -892,37 +851,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         pat_info: PatInfo<'tcx, '_>,
     ) -> Ty<'tcx> {
-        let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info;
-
         // Resolve the path and check the definition for errors.
         let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
             Ok(data) => data,
             Err(guar) => {
                 let err = Ty::new_error(self.tcx, guar);
                 for field in fields {
-                    let ti = ti;
-                    self.check_pat(
-                        field.pat,
-                        err,
-                        PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-                    );
+                    self.check_pat(field.pat, err, pat_info);
                 }
                 return err;
             }
         };
 
         // Type-check the path.
-        self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
+        self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info);
 
         // Type-check subpatterns.
-        if self.check_struct_pat_fields(
-            pat_ty,
-            &pat,
-            variant,
-            fields,
-            has_rest_pat,
-            PatInfo { binding_mode: def_bm, top_info: ti, decl_origin },
-        ) {
+        if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, pat_info) {
             pat_ty
         } else {
             Ty::new_misc_error(self.tcx)
@@ -2144,11 +2089,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// If we're in an irrefutable pattern we prefer the array impl candidate given that
     /// the slice impl candidate would be be rejected anyway (if no ambiguity existed).
     fn pat_is_irrefutable(&self, decl_origin: Option<DeclOrigin<'_>>) -> bool {
-        if let Some(decl_origin) = decl_origin {
-            decl_origin.try_get_els().is_none()
-                && matches!(decl_origin, DeclOrigin::LocalDecl { .. })
-        } else {
-            false
+        match decl_origin {
+            Some(DeclOrigin::LocalDecl { els: None }) => true,
+            Some(DeclOrigin::LocalDecl { els: Some(_) } | DeclOrigin::LetExpr) | None => false,
         }
     }
 
@@ -2183,6 +2126,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let expected = self.structurally_resolve_type(span, expected);
+        debug!(?expected);
+
         let (element_ty, opt_slice_ty, inferred) = match *expected.kind() {
             // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
             ty::Array(element_ty, len) => {
diff --git a/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs b/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs
index 310c49701ed..03a1876fdc5 100644
--- a/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs
+++ b/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs
@@ -30,9 +30,8 @@ fn main() {
 }
 
 fn another_fn_to_avoid_suppression() {
-    match Default
-    //~^ ERROR expected value, found trait
-    {
+    match Default::default() {
         [] => {}
+        //~^ ERROR type annotations needed
     };
 }
diff --git a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr
index 6218bffd503..d1d042c4776 100644
--- a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr
+++ b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr
@@ -4,12 +4,6 @@ error[E0425]: cannot find value `does_not_exist` in this scope
 LL |     match does_not_exist {
    |           ^^^^^^^^^^^^^^ not found in this scope
 
-error[E0423]: expected value, found trait `Default`
-  --> $DIR/slice-pat-type-mismatches.rs:33:11
-   |
-LL |     match Default
-   |           ^^^^^^^ not a value
-
 error[E0529]: expected an array or slice, found `String`
   --> $DIR/slice-pat-type-mismatches.rs:3:9
    |
@@ -28,7 +22,13 @@ error[E0528]: pattern requires at least 4 elements but array has 3
 LL |         [0, 1, 2, 3, x @ ..] => {}
    |         ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
 
+error[E0282]: type annotations needed
+  --> $DIR/slice-pat-type-mismatches.rs:34:9
+   |
+LL |         [] => {}
+   |         ^^ cannot infer type
+
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0423, E0425, E0527, E0528, E0529.
-For more information about an error, try `rustc --explain E0423`.
+Some errors have detailed explanations: E0282, E0425, E0527, E0528, E0529.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/pattern/issue-76342.rs b/tests/ui/pattern/issue-76342.rs
index 0d066a12179..e4d3218104e 100644
--- a/tests/ui/pattern/issue-76342.rs
+++ b/tests/ui/pattern/issue-76342.rs
@@ -1,4 +1,7 @@
 // check-pass
+
+// Test that we infer the expected type of a pattern to an array of the given length.
+
 #![allow(unused_variables)]
 struct Zeroes;
 impl Into<[usize; 2]> for Zeroes {
diff --git a/tests/ui/pattern/slice-pattern-refutable.rs b/tests/ui/pattern/slice-pattern-refutable.rs
index 3961da3bf53..1be3c6ef82d 100644
--- a/tests/ui/pattern/slice-pattern-refutable.rs
+++ b/tests/ui/pattern/slice-pattern-refutable.rs
@@ -1,3 +1,5 @@
+// Test that we do not infer the expected types of patterns to an array
+// if we're in a refutable pattern.
 #![allow(unused_variables)]
 
 struct Zeroes;
diff --git a/tests/ui/pattern/slice-pattern-refutable.stderr b/tests/ui/pattern/slice-pattern-refutable.stderr
index cb5503bac39..df5b58d3e9c 100644
--- a/tests/ui/pattern/slice-pattern-refutable.stderr
+++ b/tests/ui/pattern/slice-pattern-refutable.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/slice-pattern-refutable.rs:12:9
+  --> $DIR/slice-pattern-refutable.rs:14:9
    |
 LL |     let [a, b, c] = Zeroes.into() else {
    |         ^^^^^^^^^
@@ -10,7 +10,7 @@ LL |     let [a, b, c]: /* Type */ = Zeroes.into() else {
    |                  ++++++++++++
 
 error[E0282]: type annotations needed
-  --> $DIR/slice-pattern-refutable.rs:19:31
+  --> $DIR/slice-pattern-refutable.rs:21:31
    |
 LL |     if let [a, b, c] = Zeroes.into() {
    |            ---------          ^^^^
@@ -23,7 +23,7 @@ LL |     if let [a, b, c] = <Zeroes as Into<T>>::into(Zeroes) {
    |                        ++++++++++++++++++++++++++      ~
 
 error[E0282]: type annotations needed
-  --> $DIR/slice-pattern-refutable.rs:26:31
+  --> $DIR/slice-pattern-refutable.rs:28:31
    |
 LL |     if let [a, b, c] = Zeroes.into() {
    |            ---------          ^^^^