]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/pat.rs
fix most compiler/ doctests
[rust.git] / compiler / rustc_typeck / src / check / pat.rs
1 use crate::check::FnCtxt;
2 use rustc_ast as ast;
3
4 use rustc_data_structures::fx::FxHashMap;
5 use rustc_errors::{
6     pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
7     MultiSpan,
8 };
9 use rustc_hir as hir;
10 use rustc_hir::def::{CtorKind, DefKind, Res};
11 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
12 use rustc_hir::{HirId, Pat, PatKind};
13 use rustc_infer::infer;
14 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
15 use rustc_middle::middle::stability::EvalResult;
16 use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeFoldable};
17 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
18 use rustc_span::hygiene::DesugaringKind;
19 use rustc_span::lev_distance::find_best_match_for_name;
20 use rustc_span::source_map::{Span, Spanned};
21 use rustc_span::symbol::{kw, sym, Ident};
22 use rustc_span::{BytePos, DUMMY_SP};
23 use rustc_trait_selection::autoderef::Autoderef;
24 use rustc_trait_selection::traits::{ObligationCause, Pattern};
25 use ty::VariantDef;
26
27 use std::cmp;
28 use std::collections::hash_map::Entry::{Occupied, Vacant};
29
30 use super::report_unexpected_variant_res;
31
32 const CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ: &str = "\
33 This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
34 pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
35 this type has no compile-time size. Therefore, all accesses to trait types must be through \
36 pointers. If you encounter this error you should try to avoid dereferencing the pointer.
37
38 You can read more about trait objects in the Trait Objects section of the Reference: \
39 https://doc.rust-lang.org/reference/types.html#trait-objects";
40
41 /// Information about the expected type at the top level of type checking a pattern.
42 ///
43 /// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic!
44 #[derive(Copy, Clone)]
45 struct TopInfo<'tcx> {
46     /// The `expected` type at the top level of type checking a pattern.
47     expected: Ty<'tcx>,
48     /// Was the origin of the `span` from a scrutinee expression?
49     ///
50     /// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter.
51     origin_expr: bool,
52     /// The span giving rise to the `expected` type, if one could be provided.
53     ///
54     /// If `origin_expr` is `true`, then this is the span of the scrutinee as in:
55     ///
56     /// - `match scrutinee { ... }`
57     /// - `let _ = scrutinee;`
58     ///
59     /// This is used to point to add context in type errors.
60     /// In the following example, `span` corresponds to the `a + b` expression:
61     ///
62     /// ```text
63     /// error[E0308]: mismatched types
64     ///  --> src/main.rs:L:C
65     ///   |
66     /// L |    let temp: usize = match a + b {
67     ///   |                            ----- this expression has type `usize`
68     /// L |         Ok(num) => num,
69     ///   |         ^^^^^^^ expected `usize`, found enum `std::result::Result`
70     ///   |
71     ///   = note: expected type `usize`
72     ///              found type `std::result::Result<_, _>`
73     /// ```
74     span: Option<Span>,
75     /// This refers to the parent pattern. Used to provide extra diagnostic information on errors.
76     /// ```text
77     /// error[E0308]: mismatched types
78     ///   --> $DIR/const-in-struct-pat.rs:8:17
79     ///   |
80     /// L | struct f;
81     ///   | --------- unit struct defined here
82     /// ...
83     /// L |     let Thing { f } = t;
84     ///   |                 ^
85     ///   |                 |
86     ///   |                 expected struct `std::string::String`, found struct `f`
87     ///   |                 `f` is interpreted as a unit struct, not a new binding
88     ///   |                 help: bind the struct field to a different name instead: `f: other_f`
89     /// ```
90     parent_pat: Option<&'tcx Pat<'tcx>>,
91 }
92
93 impl<'tcx> FnCtxt<'_, 'tcx> {
94     fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
95         let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr };
96         self.cause(cause_span, code)
97     }
98
99     fn demand_eqtype_pat_diag(
100         &self,
101         cause_span: Span,
102         expected: Ty<'tcx>,
103         actual: Ty<'tcx>,
104         ti: TopInfo<'tcx>,
105     ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
106         self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
107     }
108
109     fn demand_eqtype_pat(
110         &self,
111         cause_span: Span,
112         expected: Ty<'tcx>,
113         actual: Ty<'tcx>,
114         ti: TopInfo<'tcx>,
115     ) {
116         if let Some(mut err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) {
117             err.emit();
118         }
119     }
120 }
121
122 const INITIAL_BM: BindingMode = BindingMode::BindByValue(hir::Mutability::Not);
123
124 /// Mode for adjusting the expected type and binding mode.
125 enum AdjustMode {
126     /// Peel off all immediate reference types.
127     Peel,
128     /// Reset binding mode to the initial mode.
129     Reset,
130     /// Pass on the input binding mode and expected type.
131     Pass,
132 }
133
134 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
135     /// Type check the given top level pattern against the `expected` type.
136     ///
137     /// If a `Some(span)` is provided and `origin_expr` holds,
138     /// then the `span` represents the scrutinee's span.
139     /// The scrutinee is found in e.g. `match scrutinee { ... }` and `let pat = scrutinee;`.
140     ///
141     /// Otherwise, `Some(span)` represents the span of a type expression
142     /// which originated the `expected` type.
143     pub fn check_pat_top(
144         &self,
145         pat: &'tcx Pat<'tcx>,
146         expected: Ty<'tcx>,
147         span: Option<Span>,
148         origin_expr: bool,
149     ) {
150         let info = TopInfo { expected, origin_expr, span, parent_pat: None };
151         self.check_pat(pat, expected, INITIAL_BM, info);
152     }
153
154     /// Type check the given `pat` against the `expected` type
155     /// with the provided `def_bm` (default binding mode).
156     ///
157     /// Outside of this module, `check_pat_top` should always be used.
158     /// Conversely, inside this module, `check_pat_top` should never be used.
159     #[instrument(level = "debug", skip(self, ti))]
160     fn check_pat(
161         &self,
162         pat: &'tcx Pat<'tcx>,
163         expected: Ty<'tcx>,
164         def_bm: BindingMode,
165         ti: TopInfo<'tcx>,
166     ) {
167         let path_res = match &pat.kind {
168             PatKind::Path(qpath) => {
169                 Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
170             }
171             _ => None,
172         };
173         let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
174         let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
175
176         let ty = match pat.kind {
177             PatKind::Wild => expected,
178             PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
179             PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
180             PatKind::Binding(ba, var_id, _, sub) => {
181                 self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, ti)
182             }
183             PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
184                 self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
185             }
186             PatKind::Path(_) => self.check_pat_path(pat, path_res.unwrap(), expected, ti),
187             PatKind::Struct(ref qpath, fields, has_rest_pat) => {
188                 self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
189             }
190             PatKind::Or(pats) => {
191                 let parent_pat = Some(pat);
192                 for pat in pats {
193                     self.check_pat(pat, expected, def_bm, TopInfo { parent_pat, ..ti });
194                 }
195                 expected
196             }
197             PatKind::Tuple(elements, ddpos) => {
198                 self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, ti)
199             }
200             PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, def_bm, ti),
201             PatKind::Ref(inner, mutbl) => {
202                 self.check_pat_ref(pat, inner, mutbl, expected, def_bm, ti)
203             }
204             PatKind::Slice(before, slice, after) => {
205                 self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, ti)
206             }
207         };
208
209         self.write_ty(pat.hir_id, ty);
210
211         // (note_1): In most of the cases where (note_1) is referenced
212         // (literals and constants being the exception), we relate types
213         // using strict equality, even though subtyping would be sufficient.
214         // There are a few reasons for this, some of which are fairly subtle
215         // and which cost me (nmatsakis) an hour or two debugging to remember,
216         // so I thought I'd write them down this time.
217         //
218         // 1. There is no loss of expressiveness here, though it does
219         // cause some inconvenience. What we are saying is that the type
220         // of `x` becomes *exactly* what is expected. This can cause unnecessary
221         // errors in some cases, such as this one:
222         //
223         // ```
224         // fn foo<'x>(x: &'x i32) {
225         //    let a = 1;
226         //    let mut z = x;
227         //    z = &a;
228         // }
229         // ```
230         //
231         // The reason we might get an error is that `z` might be
232         // assigned a type like `&'x i32`, and then we would have
233         // a problem when we try to assign `&a` to `z`, because
234         // the lifetime of `&a` (i.e., the enclosing block) is
235         // shorter than `'x`.
236         //
237         // HOWEVER, this code works fine. The reason is that the
238         // expected type here is whatever type the user wrote, not
239         // the initializer's type. In this case the user wrote
240         // nothing, so we are going to create a type variable `Z`.
241         // Then we will assign the type of the initializer (`&'x i32`)
242         // as a subtype of `Z`: `&'x i32 <: Z`. And hence we
243         // will instantiate `Z` as a type `&'0 i32` where `'0` is
244         // a fresh region variable, with the constraint that `'x : '0`.
245         // So basically we're all set.
246         //
247         // Note that there are two tests to check that this remains true
248         // (`regions-reassign-{match,let}-bound-pointer.rs`).
249         //
250         // 2. Things go horribly wrong if we use subtype. The reason for
251         // THIS is a fairly subtle case involving bound regions. See the
252         // `givens` field in `region_constraints`, as well as the test
253         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
254         // for details. Short version is that we must sometimes detect
255         // relationships between specific region variables and regions
256         // bound in a closure signature, and that detection gets thrown
257         // off when we substitute fresh region variables here to enable
258         // subtyping.
259     }
260
261     /// Compute the new expected type and default binding mode from the old ones
262     /// as well as the pattern form we are currently checking.
263     fn calc_default_binding_mode(
264         &self,
265         pat: &'tcx Pat<'tcx>,
266         expected: Ty<'tcx>,
267         def_bm: BindingMode,
268         adjust_mode: AdjustMode,
269     ) -> (Ty<'tcx>, BindingMode) {
270         match adjust_mode {
271             AdjustMode::Pass => (expected, def_bm),
272             AdjustMode::Reset => (expected, INITIAL_BM),
273             AdjustMode::Peel => self.peel_off_references(pat, expected, def_bm),
274         }
275     }
276
277     /// How should the binding mode and expected type be adjusted?
278     ///
279     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
280     fn calc_adjust_mode(&self, pat: &'tcx Pat<'tcx>, opt_path_res: Option<Res>) -> AdjustMode {
281         // When we perform destructuring assignment, we disable default match bindings, which are
282         // unintuitive in this context.
283         if !pat.default_binding_modes {
284             return AdjustMode::Reset;
285         }
286         match &pat.kind {
287             // Type checking these product-like types successfully always require
288             // that the expected type be of those types and not reference types.
289             PatKind::Struct(..)
290             | PatKind::TupleStruct(..)
291             | PatKind::Tuple(..)
292             | PatKind::Box(_)
293             | PatKind::Range(..)
294             | PatKind::Slice(..) => AdjustMode::Peel,
295             // String and byte-string literals result in types `&str` and `&[u8]` respectively.
296             // All other literals result in non-reference types.
297             // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo {}`.
298             //
299             // Call `resolve_vars_if_possible` here for inline const blocks.
300             PatKind::Lit(lt) => match self.resolve_vars_if_possible(self.check_expr(lt)).kind() {
301                 ty::Ref(..) => AdjustMode::Pass,
302                 _ => AdjustMode::Peel,
303             },
304             PatKind::Path(_) => match opt_path_res.unwrap() {
305                 // These constants can be of a reference type, e.g. `const X: &u8 = &0;`.
306                 // Peeling the reference types too early will cause type checking failures.
307                 // Although it would be possible to *also* peel the types of the constants too.
308                 Res::Def(DefKind::Const | DefKind::AssocConst, _) => AdjustMode::Pass,
309                 // In the `ValueNS`, we have `SelfCtor(..) | Ctor(_, Const), _)` remaining which
310                 // could successfully compile. The former being `Self` requires a unit struct.
311                 // In either case, and unlike constants, the pattern itself cannot be
312                 // a reference type wherefore peeling doesn't give up any expressiveness.
313                 _ => AdjustMode::Peel,
314             },
315             // When encountering a `& mut? pat` pattern, reset to "by value".
316             // This is so that `x` and `y` here are by value, as they appear to be:
317             //
318             // ```
319             // match &(&22, &44) {
320             //   (&x, &y) => ...
321             // }
322             // ```
323             //
324             // See issue #46688.
325             PatKind::Ref(..) => AdjustMode::Reset,
326             // A `_` pattern works with any expected type, so there's no need to do anything.
327             PatKind::Wild
328             // Bindings also work with whatever the expected type is,
329             // and moreover if we peel references off, that will give us the wrong binding type.
330             // Also, we can have a subpattern `binding @ pat`.
331             // Each side of the `@` should be treated independently (like with OR-patterns).
332             | PatKind::Binding(..)
333             // An OR-pattern just propagates to each individual alternative.
334             // This is maximally flexible, allowing e.g., `Some(mut x) | &Some(mut x)`.
335             // In that example, `Some(mut x)` results in `Peel` whereas `&Some(mut x)` in `Reset`.
336             | PatKind::Or(_) => AdjustMode::Pass,
337         }
338     }
339
340     /// Peel off as many immediately nested `& mut?` from the expected type as possible
341     /// and return the new expected type and binding default binding mode.
342     /// The adjustments vector, if non-empty is stored in a table.
343     fn peel_off_references(
344         &self,
345         pat: &'tcx Pat<'tcx>,
346         expected: Ty<'tcx>,
347         mut def_bm: BindingMode,
348     ) -> (Ty<'tcx>, BindingMode) {
349         let mut expected = self.resolve_vars_with_obligations(expected);
350
351         // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
352         // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
353         // the `Some(5)` which is not of type Ref.
354         //
355         // For each ampersand peeled off, update the binding mode and push the original
356         // type into the adjustments vector.
357         //
358         // See the examples in `ui/match-defbm*.rs`.
359         let mut pat_adjustments = vec![];
360         while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
361             debug!("inspecting {:?}", expected);
362
363             debug!("current discriminant is Ref, inserting implicit deref");
364             // Preserve the reference type. We'll need it later during THIR lowering.
365             pat_adjustments.push(expected);
366
367             expected = inner_ty;
368             def_bm = ty::BindByReference(match def_bm {
369                 // If default binding mode is by value, make it `ref` or `ref mut`
370                 // (depending on whether we observe `&` or `&mut`).
371                 ty::BindByValue(_) |
372                 // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
373                 ty::BindByReference(hir::Mutability::Mut) => inner_mutability,
374                 // Once a `ref`, always a `ref`.
375                 // This is because a `& &mut` cannot mutate the underlying value.
376                 ty::BindByReference(m @ hir::Mutability::Not) => m,
377             });
378         }
379
380         if !pat_adjustments.is_empty() {
381             debug!("default binding mode is now {:?}", def_bm);
382             self.inh
383                 .typeck_results
384                 .borrow_mut()
385                 .pat_adjustments_mut()
386                 .insert(pat.hir_id, pat_adjustments);
387         }
388
389         (expected, def_bm)
390     }
391
392     fn check_pat_lit(
393         &self,
394         span: Span,
395         lt: &hir::Expr<'tcx>,
396         expected: Ty<'tcx>,
397         ti: TopInfo<'tcx>,
398     ) -> Ty<'tcx> {
399         // We've already computed the type above (when checking for a non-ref pat),
400         // so avoid computing it again.
401         let ty = self.node_ty(lt.hir_id);
402
403         // Byte string patterns behave the same way as array patterns
404         // They can denote both statically and dynamically-sized byte arrays.
405         let mut pat_ty = ty;
406         if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
407             let expected = self.structurally_resolved_type(span, expected);
408             if let ty::Ref(_, inner_ty, _) = expected.kind()
409                 && matches!(inner_ty.kind(), ty::Slice(_))
410             {
411                 let tcx = self.tcx;
412                 trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
413                 self.typeck_results
414                     .borrow_mut()
415                     .treat_byte_string_as_slice
416                     .insert(lt.hir_id.local_id);
417                 pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
418             }
419         }
420
421         // Somewhat surprising: in this case, the subtyping relation goes the
422         // opposite way as the other cases. Actually what we really want is not
423         // a subtyping relation at all but rather that there exists a LUB
424         // (so that they can be compared). However, in practice, constants are
425         // always scalars or strings. For scalars subtyping is irrelevant,
426         // and for strings `ty` is type is `&'static str`, so if we say that
427         //
428         //     &'static str <: expected
429         //
430         // then that's equivalent to there existing a LUB.
431         let cause = self.pattern_cause(ti, span);
432         if let Some(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) {
433             err.emit_unless(
434                 ti.span
435                     .filter(|&s| {
436                         // In the case of `if`- and `while`-expressions we've already checked
437                         // that `scrutinee: bool`. We know that the pattern is `true`,
438                         // so an error here would be a duplicate and from the wrong POV.
439                         s.is_desugaring(DesugaringKind::CondTemporary)
440                     })
441                     .is_some(),
442             );
443         }
444
445         pat_ty
446     }
447
448     fn check_pat_range(
449         &self,
450         span: Span,
451         lhs: Option<&'tcx hir::Expr<'tcx>>,
452         rhs: Option<&'tcx hir::Expr<'tcx>>,
453         expected: Ty<'tcx>,
454         ti: TopInfo<'tcx>,
455     ) -> Ty<'tcx> {
456         let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr {
457             None => None,
458             Some(expr) => {
459                 let ty = self.check_expr(expr);
460                 // Check that the end-point is possibly of numeric or char type.
461                 // The early check here is not for correctness, but rather better
462                 // diagnostics (e.g. when `&str` is being matched, `expected` will
463                 // be peeled to `str` while ty here is still `&str`, if we don't
464                 // err early here, a rather confusing unification error will be
465                 // emitted instead).
466                 let fail =
467                     !(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
468                 Some((fail, ty, expr.span))
469             }
470         };
471         let mut lhs = calc_side(lhs);
472         let mut rhs = calc_side(rhs);
473
474         if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
475             // There exists a side that didn't meet our criteria that the end-point
476             // be of a numeric or char type, as checked in `calc_side` above.
477             self.emit_err_pat_range(span, lhs, rhs);
478             return self.tcx.ty_error();
479         }
480
481         // Unify each side with `expected`.
482         // Subtyping doesn't matter here, as the value is some kind of scalar.
483         let demand_eqtype = |x: &mut _, y| {
484             if let Some((ref mut fail, x_ty, x_span)) = *x
485                 && let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti)
486             {
487                 if let Some((_, y_ty, y_span)) = y {
488                     self.endpoint_has_type(&mut err, y_span, y_ty);
489                 }
490                 err.emit();
491                 *fail = true;
492             }
493         };
494         demand_eqtype(&mut lhs, rhs);
495         demand_eqtype(&mut rhs, lhs);
496
497         if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
498             return self.tcx.ty_error();
499         }
500
501         // Find the unified type and check if it's of numeric or char type again.
502         // This check is needed if both sides are inference variables.
503         // We require types to be resolved here so that we emit inference failure
504         // rather than "_ is not a char or numeric".
505         let ty = self.structurally_resolved_type(span, expected);
506         if !(ty.is_numeric() || ty.is_char() || ty.references_error()) {
507             if let Some((ref mut fail, _, _)) = lhs {
508                 *fail = true;
509             }
510             if let Some((ref mut fail, _, _)) = rhs {
511                 *fail = true;
512             }
513             self.emit_err_pat_range(span, lhs, rhs);
514             return self.tcx.ty_error();
515         }
516         ty
517     }
518
519     fn endpoint_has_type(&self, err: &mut Diagnostic, span: Span, ty: Ty<'_>) {
520         if !ty.references_error() {
521             err.span_label(span, &format!("this is of type `{}`", ty));
522         }
523     }
524
525     fn emit_err_pat_range(
526         &self,
527         span: Span,
528         lhs: Option<(bool, Ty<'tcx>, Span)>,
529         rhs: Option<(bool, Ty<'tcx>, Span)>,
530     ) {
531         let span = match (lhs, rhs) {
532             (Some((true, ..)), Some((true, ..))) => span,
533             (Some((true, _, sp)), _) => sp,
534             (_, Some((true, _, sp))) => sp,
535             _ => span_bug!(span, "emit_err_pat_range: no side failed or exists but still error?"),
536         };
537         let mut err = struct_span_err!(
538             self.tcx.sess,
539             span,
540             E0029,
541             "only `char` and numeric types are allowed in range patterns"
542         );
543         let msg = |ty| {
544             let ty = self.resolve_vars_if_possible(ty);
545             format!("this is of type `{}` but it should be `char` or numeric", ty)
546         };
547         let mut one_side_err = |first_span, first_ty, second: Option<(bool, Ty<'tcx>, Span)>| {
548             err.span_label(first_span, &msg(first_ty));
549             if let Some((_, ty, sp)) = second {
550                 let ty = self.resolve_vars_if_possible(ty);
551                 self.endpoint_has_type(&mut err, sp, ty);
552             }
553         };
554         match (lhs, rhs) {
555             (Some((true, lhs_ty, lhs_sp)), Some((true, rhs_ty, rhs_sp))) => {
556                 err.span_label(lhs_sp, &msg(lhs_ty));
557                 err.span_label(rhs_sp, &msg(rhs_ty));
558             }
559             (Some((true, lhs_ty, lhs_sp)), rhs) => one_side_err(lhs_sp, lhs_ty, rhs),
560             (lhs, Some((true, rhs_ty, rhs_sp))) => one_side_err(rhs_sp, rhs_ty, lhs),
561             _ => span_bug!(span, "Impossible, verified above."),
562         }
563         if self.tcx.sess.teach(&err.get_code().unwrap()) {
564             err.note(
565                 "In a match expression, only numbers and characters can be matched \
566                     against a range. This is because the compiler checks that the range \
567                     is non-empty at compile-time, and is unable to evaluate arbitrary \
568                     comparison functions. If you want to capture values of an orderable \
569                     type between two end-points, you can use a guard.",
570             );
571         }
572         err.emit();
573     }
574
575     fn check_pat_ident(
576         &self,
577         pat: &'tcx Pat<'tcx>,
578         ba: hir::BindingAnnotation,
579         var_id: HirId,
580         sub: Option<&'tcx Pat<'tcx>>,
581         expected: Ty<'tcx>,
582         def_bm: BindingMode,
583         ti: TopInfo<'tcx>,
584     ) -> Ty<'tcx> {
585         // Determine the binding mode...
586         let bm = match ba {
587             hir::BindingAnnotation::Unannotated => def_bm,
588             _ => BindingMode::convert(ba),
589         };
590         // ...and store it in a side table:
591         self.inh.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm);
592
593         debug!("check_pat_ident: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
594
595         let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
596         let eq_ty = match bm {
597             ty::BindByReference(mutbl) => {
598                 // If the binding is like `ref x | ref mut x`,
599                 // then `x` is assigned a value of type `&M T` where M is the
600                 // mutability and T is the expected type.
601                 //
602                 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
603                 // is required. However, we use equality, which is stronger.
604                 // See (note_1) for an explanation.
605                 self.new_ref_ty(pat.span, mutbl, expected)
606             }
607             // Otherwise, the type of x is the expected type `T`.
608             ty::BindByValue(_) => {
609                 // As above, `T <: typeof(x)` is required, but we use equality, see (note_1).
610                 expected
611             }
612         };
613         self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti);
614
615         // If there are multiple arms, make sure they all agree on
616         // what the type of the binding `x` ought to be.
617         if var_id != pat.hir_id {
618             self.check_binding_alt_eq_ty(pat.span, var_id, local_ty, ti);
619         }
620
621         if let Some(p) = sub {
622             self.check_pat(p, expected, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
623         }
624
625         local_ty
626     }
627
628     fn check_binding_alt_eq_ty(&self, span: Span, var_id: HirId, ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
629         let var_ty = self.local_ty(span, var_id).decl_ty;
630         if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
631             let hir = self.tcx.hir();
632             let var_ty = self.resolve_vars_with_obligations(var_ty);
633             let msg = format!("first introduced with type `{var_ty}` here");
634             err.span_label(hir.span(var_id), msg);
635             let in_match = hir.parent_iter(var_id).any(|(_, n)| {
636                 matches!(
637                     n,
638                     hir::Node::Expr(hir::Expr {
639                         kind: hir::ExprKind::Match(.., hir::MatchSource::Normal),
640                         ..
641                     })
642                 )
643             });
644             let pre = if in_match { "in the same arm, " } else { "" };
645             err.note(&format!("{}a binding must have the same type in all alternatives", pre));
646             // FIXME: check if `var_ty` and `ty` can be made the same type by adding or removing
647             // `ref` or `&` to the pattern.
648             err.emit();
649         }
650     }
651
652     fn borrow_pat_suggestion(
653         &self,
654         err: &mut Diagnostic,
655         pat: &Pat<'_>,
656         inner: &Pat<'_>,
657         expected: Ty<'tcx>,
658     ) {
659         let tcx = self.tcx;
660         if let PatKind::Binding(..) = inner.kind {
661             let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
662             let binding_parent = tcx.hir().get(binding_parent_id);
663             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
664             match binding_parent {
665                 hir::Node::Param(hir::Param { span, .. })
666                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) =>
667                 {
668                     err.span_suggestion(
669                         *span,
670                         &format!("did you mean `{snippet}`"),
671                         format!(" &{expected}"),
672                         Applicability::MachineApplicable,
673                     );
674                 }
675                 hir::Node::Arm(_) | hir::Node::Pat(_) => {
676                     // rely on match ergonomics or it might be nested `&&pat`
677                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
678                         err.span_suggestion(
679                             pat.span,
680                             "you can probably remove the explicit borrow",
681                             snippet,
682                             Applicability::MaybeIncorrect,
683                         );
684                     }
685                 }
686                 _ => {} // don't provide suggestions in other cases #55175
687             }
688         }
689     }
690
691     pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool {
692         if let PatKind::Binding(..) = inner.kind
693             && let Some(mt) = self.shallow_resolve(expected).builtin_deref(true)
694             && let ty::Dynamic(..) = mt.ty.kind()
695         {
696                     // This is "x = SomeTrait" being reduced from
697                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
698                     let type_str = self.ty_to_string(expected);
699                     let mut err = struct_span_err!(
700                         self.tcx.sess,
701                         span,
702                         E0033,
703                         "type `{}` cannot be dereferenced",
704                         type_str
705                     );
706                     err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
707                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
708                         err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
709                     }
710                     err.emit();
711                     return false;
712                 }
713         true
714     }
715
716     fn check_pat_struct(
717         &self,
718         pat: &'tcx Pat<'tcx>,
719         qpath: &hir::QPath<'_>,
720         fields: &'tcx [hir::PatField<'tcx>],
721         has_rest_pat: bool,
722         expected: Ty<'tcx>,
723         def_bm: BindingMode,
724         ti: TopInfo<'tcx>,
725     ) -> Ty<'tcx> {
726         // Resolve the path and check the definition for errors.
727         let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
728             let err = self.tcx.ty_error();
729             for field in fields {
730                 let ti = TopInfo { parent_pat: Some(pat), ..ti };
731                 self.check_pat(field.pat, err, def_bm, ti);
732             }
733             return err;
734         };
735
736         // Type-check the path.
737         self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
738
739         // Type-check subpatterns.
740         if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) {
741             pat_ty
742         } else {
743             self.tcx.ty_error()
744         }
745     }
746
747     fn check_pat_path<'b>(
748         &self,
749         pat: &Pat<'_>,
750         path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]),
751         expected: Ty<'tcx>,
752         ti: TopInfo<'tcx>,
753     ) -> Ty<'tcx> {
754         let tcx = self.tcx;
755
756         // We have already resolved the path.
757         let (res, opt_ty, segments) = path_resolution;
758         match res {
759             Res::Err => {
760                 self.set_tainted_by_errors();
761                 return tcx.ty_error();
762             }
763             Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
764                 report_unexpected_variant_res(tcx, res, pat.span);
765                 return tcx.ty_error();
766             }
767             Res::SelfCtor(..)
768             | Res::Def(
769                 DefKind::Ctor(_, CtorKind::Const)
770                 | DefKind::Const
771                 | DefKind::AssocConst
772                 | DefKind::ConstParam,
773                 _,
774             ) => {} // OK
775             _ => bug!("unexpected pattern resolution: {:?}", res),
776         }
777
778         // Type-check the path.
779         let (pat_ty, pat_res) =
780             self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
781         if let Some(err) =
782             self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
783         {
784             self.emit_bad_pat_path(err, pat.span, res, pat_res, pat_ty, segments, ti.parent_pat);
785         }
786         pat_ty
787     }
788
789     fn maybe_suggest_range_literal(
790         &self,
791         e: &mut Diagnostic,
792         opt_def_id: Option<hir::def_id::DefId>,
793         ident: Ident,
794     ) -> bool {
795         match opt_def_id {
796             Some(def_id) => match self.tcx.hir().get_if_local(def_id) {
797                 Some(hir::Node::Item(hir::Item {
798                     kind: hir::ItemKind::Const(_, body_id), ..
799                 })) => match self.tcx.hir().get(body_id.hir_id) {
800                     hir::Node::Expr(expr) => {
801                         if hir::is_range_literal(expr) {
802                             let span = self.tcx.hir().span(body_id.hir_id);
803                             if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) {
804                                 e.span_suggestion_verbose(
805                                     ident.span,
806                                     "you may want to move the range into the match block",
807                                     snip,
808                                     Applicability::MachineApplicable,
809                                 );
810                                 return true;
811                             }
812                         }
813                     }
814                     _ => (),
815                 },
816                 _ => (),
817             },
818             _ => (),
819         }
820         false
821     }
822
823     fn emit_bad_pat_path<'b>(
824         &self,
825         mut e: DiagnosticBuilder<'_, ErrorGuaranteed>,
826         pat_span: Span,
827         res: Res,
828         pat_res: Res,
829         pat_ty: Ty<'tcx>,
830         segments: &'b [hir::PathSegment<'b>],
831         parent_pat: Option<&Pat<'_>>,
832     ) {
833         if let Some(span) = self.tcx.hir().res_span(pat_res) {
834             e.span_label(span, &format!("{} defined here", res.descr()));
835             if let [hir::PathSegment { ident, .. }] = &*segments {
836                 e.span_label(
837                     pat_span,
838                     &format!(
839                         "`{}` is interpreted as {} {}, not a new binding",
840                         ident,
841                         res.article(),
842                         res.descr(),
843                     ),
844                 );
845                 match parent_pat {
846                     Some(Pat { kind: hir::PatKind::Struct(..), .. }) => {
847                         e.span_suggestion_verbose(
848                             ident.span.shrink_to_hi(),
849                             "bind the struct field to a different name instead",
850                             format!(": other_{}", ident.as_str().to_lowercase()),
851                             Applicability::HasPlaceholders,
852                         );
853                     }
854                     _ => {
855                         let (type_def_id, item_def_id) = match pat_ty.kind() {
856                             Adt(def, _) => match res {
857                                 Res::Def(DefKind::Const, def_id) => (Some(def.did()), Some(def_id)),
858                                 _ => (None, None),
859                             },
860                             _ => (None, None),
861                         };
862
863                         let ranges = &[
864                             self.tcx.lang_items().range_struct(),
865                             self.tcx.lang_items().range_from_struct(),
866                             self.tcx.lang_items().range_to_struct(),
867                             self.tcx.lang_items().range_full_struct(),
868                             self.tcx.lang_items().range_inclusive_struct(),
869                             self.tcx.lang_items().range_to_inclusive_struct(),
870                         ];
871                         if type_def_id != None && ranges.contains(&type_def_id) {
872                             if !self.maybe_suggest_range_literal(&mut e, item_def_id, *ident) {
873                                 let msg = "constants only support matching by type, \
874                                     if you meant to match against a range of values, \
875                                     consider using a range pattern like `min ..= max` in the match block";
876                                 e.note(msg);
877                             }
878                         } else {
879                             let msg = "introduce a new binding instead";
880                             let sugg = format!("other_{}", ident.as_str().to_lowercase());
881                             e.span_suggestion(
882                                 ident.span,
883                                 msg,
884                                 sugg,
885                                 Applicability::HasPlaceholders,
886                             );
887                         }
888                     }
889                 };
890             }
891         }
892         e.emit();
893     }
894
895     fn check_pat_tuple_struct(
896         &self,
897         pat: &'tcx Pat<'tcx>,
898         qpath: &'tcx hir::QPath<'tcx>,
899         subpats: &'tcx [Pat<'tcx>],
900         ddpos: Option<usize>,
901         expected: Ty<'tcx>,
902         def_bm: BindingMode,
903         ti: TopInfo<'tcx>,
904     ) -> Ty<'tcx> {
905         let tcx = self.tcx;
906         let on_error = || {
907             let parent_pat = Some(pat);
908             for pat in subpats {
909                 self.check_pat(pat, tcx.ty_error(), def_bm, TopInfo { parent_pat, ..ti });
910             }
911         };
912         let report_unexpected_res = |res: Res| {
913             let sm = tcx.sess.source_map();
914             let path_str = sm
915                 .span_to_snippet(sm.span_until_char(pat.span, '('))
916                 .map_or_else(|_| String::new(), |s| format!(" `{}`", s.trim_end()));
917             let msg = format!(
918                 "expected tuple struct or tuple variant, found {}{}",
919                 res.descr(),
920                 path_str
921             );
922
923             let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}");
924             match res {
925                 Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
926                     err.span_label(pat.span, "`fn` calls are not allowed in patterns");
927                     err.help(
928                         "for more information, visit \
929                               https://doc.rust-lang.org/book/ch18-00-patterns.html",
930                     );
931                 }
932                 _ => {
933                     err.span_label(pat.span, "not a tuple variant or struct");
934                 }
935             }
936             err.emit();
937             on_error();
938         };
939
940         // Resolve the path and check the definition for errors.
941         let (res, opt_ty, segments) =
942             self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
943         if res == Res::Err {
944             self.set_tainted_by_errors();
945             on_error();
946             return self.tcx.ty_error();
947         }
948
949         // Type-check the path.
950         let (pat_ty, res) =
951             self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
952         if !pat_ty.is_fn() {
953             report_unexpected_res(res);
954             return tcx.ty_error();
955         }
956
957         let variant = match res {
958             Res::Err => {
959                 self.set_tainted_by_errors();
960                 on_error();
961                 return tcx.ty_error();
962             }
963             Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
964                 report_unexpected_res(res);
965                 return tcx.ty_error();
966             }
967             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
968             _ => bug!("unexpected pattern resolution: {:?}", res),
969         };
970
971         // Replace constructor type with constructed type for tuple struct patterns.
972         let pat_ty = pat_ty.fn_sig(tcx).output();
973         let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
974
975         // Type-check the tuple struct pattern against the expected type.
976         let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
977         let had_err = if let Some(mut err) = diag {
978             err.emit();
979             true
980         } else {
981             false
982         };
983
984         // Type-check subpatterns.
985         if subpats.len() == variant.fields.len()
986             || subpats.len() < variant.fields.len() && ddpos.is_some()
987         {
988             let ty::Adt(_, substs) = pat_ty.kind() else {
989                 bug!("unexpected pattern type {:?}", pat_ty);
990             };
991             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
992                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
993                 self.check_pat(subpat, field_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
994
995                 self.tcx.check_stability(
996                     variant.fields[i].did,
997                     Some(pat.hir_id),
998                     subpat.span,
999                     None,
1000                 );
1001             }
1002         } else {
1003             // Pattern has wrong number of fields.
1004             self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
1005             on_error();
1006             return tcx.ty_error();
1007         }
1008         pat_ty
1009     }
1010
1011     fn e0023(
1012         &self,
1013         pat_span: Span,
1014         res: Res,
1015         qpath: &hir::QPath<'_>,
1016         subpats: &'tcx [Pat<'tcx>],
1017         fields: &'tcx [ty::FieldDef],
1018         expected: Ty<'tcx>,
1019         had_err: bool,
1020     ) {
1021         let subpats_ending = pluralize!(subpats.len());
1022         let fields_ending = pluralize!(fields.len());
1023
1024         let subpat_spans = if subpats.is_empty() {
1025             vec![pat_span]
1026         } else {
1027             subpats.iter().map(|p| p.span).collect()
1028         };
1029         let last_subpat_span = *subpat_spans.last().unwrap();
1030         let res_span = self.tcx.def_span(res.def_id());
1031         let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span);
1032         let field_def_spans = if fields.is_empty() {
1033             vec![res_span]
1034         } else {
1035             fields.iter().map(|f| f.ident(self.tcx).span).collect()
1036         };
1037         let last_field_def_span = *field_def_spans.last().unwrap();
1038
1039         let mut err = struct_span_err!(
1040             self.tcx.sess,
1041             MultiSpan::from_spans(subpat_spans),
1042             E0023,
1043             "this pattern has {} field{}, but the corresponding {} has {} field{}",
1044             subpats.len(),
1045             subpats_ending,
1046             res.descr(),
1047             fields.len(),
1048             fields_ending,
1049         );
1050         err.span_label(
1051             last_subpat_span,
1052             &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()),
1053         );
1054         if self.tcx.sess.source_map().is_multiline(qpath.span().between(last_subpat_span)) {
1055             err.span_label(qpath.span(), "");
1056         }
1057         if self.tcx.sess.source_map().is_multiline(def_ident_span.between(last_field_def_span)) {
1058             err.span_label(def_ident_span, format!("{} defined here", res.descr()));
1059         }
1060         for span in &field_def_spans[..field_def_spans.len() - 1] {
1061             err.span_label(*span, "");
1062         }
1063         err.span_label(
1064             last_field_def_span,
1065             &format!("{} has {} field{}", res.descr(), fields.len(), fields_ending),
1066         );
1067
1068         // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`.
1069         // More generally, the expected type wants a tuple variant with one field of an
1070         // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
1071         // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
1072         let missing_parentheses = match (&expected.kind(), fields, had_err) {
1073             // #67037: only do this if we could successfully type-check the expected type against
1074             // the tuple struct pattern. Otherwise the substs could get out of range on e.g.,
1075             // `let P() = U;` where `P != U` with `struct P<T>(T);`.
1076             (ty::Adt(_, substs), [field], false) => {
1077                 let field_ty = self.field_ty(pat_span, field, substs);
1078                 match field_ty.kind() {
1079                     ty::Tuple(fields) => fields.len() == subpats.len(),
1080                     _ => false,
1081                 }
1082             }
1083             _ => false,
1084         };
1085         if missing_parentheses {
1086             let (left, right) = match subpats {
1087                 // This is the zero case; we aim to get the "hi" part of the `QPath`'s
1088                 // span as the "lo" and then the "hi" part of the pattern's span as the "hi".
1089                 // This looks like:
1090                 //
1091                 // help: missing parentheses
1092                 //   |
1093                 // L |     let A(()) = A(());
1094                 //   |          ^  ^
1095                 [] => (qpath.span().shrink_to_hi(), pat_span),
1096                 // Easy case. Just take the "lo" of the first sub-pattern and the "hi" of the
1097                 // last sub-pattern. In the case of `A(x)` the first and last may coincide.
1098                 // This looks like:
1099                 //
1100                 // help: missing parentheses
1101                 //   |
1102                 // L |     let A((x, y)) = A((1, 2));
1103                 //   |           ^    ^
1104                 [first, ..] => (first.span.shrink_to_lo(), subpats.last().unwrap().span),
1105             };
1106             err.multipart_suggestion(
1107                 "missing parentheses",
1108                 vec![(left, "(".to_string()), (right.shrink_to_hi(), ")".to_string())],
1109                 Applicability::MachineApplicable,
1110             );
1111         } else if fields.len() > subpats.len() && pat_span != DUMMY_SP {
1112             let after_fields_span = pat_span.with_hi(pat_span.hi() - BytePos(1)).shrink_to_hi();
1113             let all_fields_span = match subpats {
1114                 [] => after_fields_span,
1115                 [field] => field.span,
1116                 [first, .., last] => first.span.to(last.span),
1117             };
1118
1119             // Check if all the fields in the pattern are wildcards.
1120             let all_wildcards = subpats.iter().all(|pat| matches!(pat.kind, PatKind::Wild));
1121             let first_tail_wildcard =
1122                 subpats.iter().enumerate().fold(None, |acc, (pos, pat)| match (acc, &pat.kind) {
1123                     (None, PatKind::Wild) => Some(pos),
1124                     (Some(_), PatKind::Wild) => acc,
1125                     _ => None,
1126                 });
1127             let tail_span = match first_tail_wildcard {
1128                 None => after_fields_span,
1129                 Some(0) => subpats[0].span.to(after_fields_span),
1130                 Some(pos) => subpats[pos - 1].span.shrink_to_hi().to(after_fields_span),
1131             };
1132
1133             // FIXME: heuristic-based suggestion to check current types for where to add `_`.
1134             let mut wildcard_sugg = vec!["_"; fields.len() - subpats.len()].join(", ");
1135             if !subpats.is_empty() {
1136                 wildcard_sugg = String::from(", ") + &wildcard_sugg;
1137             }
1138
1139             err.span_suggestion_verbose(
1140                 after_fields_span,
1141                 "use `_` to explicitly ignore each field",
1142                 wildcard_sugg,
1143                 Applicability::MaybeIncorrect,
1144             );
1145
1146             // Only suggest `..` if more than one field is missing
1147             // or the pattern consists of all wildcards.
1148             if fields.len() - subpats.len() > 1 || all_wildcards {
1149                 if subpats.is_empty() || all_wildcards {
1150                     err.span_suggestion_verbose(
1151                         all_fields_span,
1152                         "use `..` to ignore all fields",
1153                         String::from(".."),
1154                         Applicability::MaybeIncorrect,
1155                     );
1156                 } else {
1157                     err.span_suggestion_verbose(
1158                         tail_span,
1159                         "use `..` to ignore the rest of the fields",
1160                         String::from(", .."),
1161                         Applicability::MaybeIncorrect,
1162                     );
1163                 }
1164             }
1165         }
1166
1167         err.emit();
1168     }
1169
1170     fn check_pat_tuple(
1171         &self,
1172         span: Span,
1173         elements: &'tcx [Pat<'tcx>],
1174         ddpos: Option<usize>,
1175         expected: Ty<'tcx>,
1176         def_bm: BindingMode,
1177         ti: TopInfo<'tcx>,
1178     ) -> Ty<'tcx> {
1179         let tcx = self.tcx;
1180         let mut expected_len = elements.len();
1181         if ddpos.is_some() {
1182             // Require known type only when `..` is present.
1183             if let ty::Tuple(tys) = self.structurally_resolved_type(span, expected).kind() {
1184                 expected_len = tys.len();
1185             }
1186         }
1187         let max_len = cmp::max(expected_len, elements.len());
1188
1189         let element_tys_iter = (0..max_len).map(|_| {
1190             self.next_ty_var(
1191                 // FIXME: `MiscVariable` for now -- obtaining the span and name information
1192                 // from all tuple elements isn't trivial.
1193                 TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span },
1194             )
1195         });
1196         let element_tys = tcx.mk_type_list(element_tys_iter);
1197         let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
1198         if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
1199             err.emit();
1200             // Walk subpatterns with an expected type of `err` in this case to silence
1201             // further errors being emitted when using the bindings. #50333
1202             let element_tys_iter = (0..max_len).map(|_| tcx.ty_error());
1203             for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
1204                 self.check_pat(elem, tcx.ty_error(), def_bm, ti);
1205             }
1206             tcx.mk_tup(element_tys_iter)
1207         } else {
1208             for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
1209                 self.check_pat(elem, element_tys[i], def_bm, ti);
1210             }
1211             pat_ty
1212         }
1213     }
1214
1215     fn check_struct_pat_fields(
1216         &self,
1217         adt_ty: Ty<'tcx>,
1218         pat: &'tcx Pat<'tcx>,
1219         variant: &'tcx ty::VariantDef,
1220         fields: &'tcx [hir::PatField<'tcx>],
1221         has_rest_pat: bool,
1222         def_bm: BindingMode,
1223         ti: TopInfo<'tcx>,
1224     ) -> bool {
1225         let tcx = self.tcx;
1226
1227         let ty::Adt(adt, substs) = adt_ty.kind() else {
1228             span_bug!(pat.span, "struct pattern is not an ADT");
1229         };
1230
1231         // Index the struct fields' types.
1232         let field_map = variant
1233             .fields
1234             .iter()
1235             .enumerate()
1236             .map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field)))
1237             .collect::<FxHashMap<_, _>>();
1238
1239         // Keep track of which fields have already appeared in the pattern.
1240         let mut used_fields = FxHashMap::default();
1241         let mut no_field_errors = true;
1242
1243         let mut inexistent_fields = vec![];
1244         // Typecheck each field.
1245         for field in fields {
1246             let span = field.span;
1247             let ident = tcx.adjust_ident(field.ident, variant.def_id);
1248             let field_ty = match used_fields.entry(ident) {
1249                 Occupied(occupied) => {
1250                     self.error_field_already_bound(span, field.ident, *occupied.get());
1251                     no_field_errors = false;
1252                     tcx.ty_error()
1253                 }
1254                 Vacant(vacant) => {
1255                     vacant.insert(span);
1256                     field_map
1257                         .get(&ident)
1258                         .map(|(i, f)| {
1259                             self.write_field_index(field.hir_id, *i);
1260                             self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
1261                             self.field_ty(span, f, substs)
1262                         })
1263                         .unwrap_or_else(|| {
1264                             inexistent_fields.push(field);
1265                             no_field_errors = false;
1266                             tcx.ty_error()
1267                         })
1268                 }
1269             };
1270
1271             self.check_pat(field.pat, field_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
1272         }
1273
1274         let mut unmentioned_fields = variant
1275             .fields
1276             .iter()
1277             .map(|field| (field, field.ident(self.tcx).normalize_to_macros_2_0()))
1278             .filter(|(_, ident)| !used_fields.contains_key(ident))
1279             .collect::<Vec<_>>();
1280
1281         let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered())
1282             && !inexistent_fields.iter().any(|field| field.ident.name == kw::Underscore)
1283         {
1284             Some(self.error_inexistent_fields(
1285                 adt.variant_descr(),
1286                 &inexistent_fields,
1287                 &mut unmentioned_fields,
1288                 variant,
1289                 substs,
1290             ))
1291         } else {
1292             None
1293         };
1294
1295         // Require `..` if struct has non_exhaustive attribute.
1296         let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
1297         if non_exhaustive && !has_rest_pat {
1298             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
1299         }
1300
1301         let mut unmentioned_err = None;
1302         // Report an error if an incorrect number of fields was specified.
1303         if adt.is_union() {
1304             if fields.len() != 1 {
1305                 tcx.sess
1306                     .struct_span_err(pat.span, "union patterns should have exactly one field")
1307                     .emit();
1308             }
1309             if has_rest_pat {
1310                 tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
1311             }
1312         } else if !unmentioned_fields.is_empty() {
1313             let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
1314                 .iter()
1315                 .copied()
1316                 .filter(|(field, _)| {
1317                     field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
1318                         && !matches!(
1319                             tcx.eval_stability(field.did, None, DUMMY_SP, None),
1320                             EvalResult::Deny { .. }
1321                         )
1322                         // We only want to report the error if it is hidden and not local
1323                         && !(tcx.is_doc_hidden(field.did) && !field.did.is_local())
1324                 })
1325                 .collect();
1326
1327             if !has_rest_pat {
1328                 if accessible_unmentioned_fields.is_empty() {
1329                     unmentioned_err = Some(self.error_no_accessible_fields(pat, fields));
1330                 } else {
1331                     unmentioned_err = Some(self.error_unmentioned_fields(
1332                         pat,
1333                         &accessible_unmentioned_fields,
1334                         accessible_unmentioned_fields.len() != unmentioned_fields.len(),
1335                         fields,
1336                     ));
1337                 }
1338             } else if non_exhaustive && !accessible_unmentioned_fields.is_empty() {
1339                 self.lint_non_exhaustive_omitted_patterns(
1340                     pat,
1341                     &accessible_unmentioned_fields,
1342                     adt_ty,
1343                 )
1344             }
1345         }
1346         match (inexistent_fields_err, unmentioned_err) {
1347             (Some(mut i), Some(mut u)) => {
1348                 if let Some(mut e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) {
1349                     // We don't want to show the nonexistent fields error when this was
1350                     // `Foo { a, b }` when it should have been `Foo(a, b)`.
1351                     i.delay_as_bug();
1352                     u.delay_as_bug();
1353                     e.emit();
1354                 } else {
1355                     i.emit();
1356                     u.emit();
1357                 }
1358             }
1359             (None, Some(mut u)) => {
1360                 if let Some(mut e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) {
1361                     u.delay_as_bug();
1362                     e.emit();
1363                 } else {
1364                     u.emit();
1365                 }
1366             }
1367             (Some(mut err), None) => {
1368                 err.emit();
1369             }
1370             (None, None) if let Some(mut err) =
1371                     self.error_tuple_variant_index_shorthand(variant, pat, fields) =>
1372             {
1373                 err.emit();
1374             }
1375             (None, None) => {}
1376         }
1377         no_field_errors
1378     }
1379
1380     fn error_tuple_variant_index_shorthand(
1381         &self,
1382         variant: &VariantDef,
1383         pat: &'_ Pat<'_>,
1384         fields: &[hir::PatField<'_>],
1385     ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
1386         // if this is a tuple struct, then all field names will be numbers
1387         // so if any fields in a struct pattern use shorthand syntax, they will
1388         // be invalid identifiers (for example, Foo { 0, 1 }).
1389         if let (CtorKind::Fn, PatKind::Struct(qpath, field_patterns, ..)) =
1390             (variant.ctor_kind, &pat.kind)
1391         {
1392             let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand);
1393             if has_shorthand_field_name {
1394                 let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
1395                     s.print_qpath(qpath, false)
1396                 });
1397                 let mut err = struct_span_err!(
1398                     self.tcx.sess,
1399                     pat.span,
1400                     E0769,
1401                     "tuple variant `{path}` written as struct variant",
1402                 );
1403                 err.span_suggestion_verbose(
1404                     qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()),
1405                     "use the tuple variant pattern syntax instead",
1406                     format!("({})", self.get_suggested_tuple_struct_pattern(fields, variant)),
1407                     Applicability::MaybeIncorrect,
1408                 );
1409                 return Some(err);
1410             }
1411         }
1412         None
1413     }
1414
1415     fn error_foreign_non_exhaustive_spat(&self, pat: &Pat<'_>, descr: &str, no_fields: bool) {
1416         let sess = self.tcx.sess;
1417         let sm = sess.source_map();
1418         let sp_brace = sm.end_point(pat.span);
1419         let sp_comma = sm.end_point(pat.span.with_hi(sp_brace.hi()));
1420         let sugg = if no_fields || sp_brace != sp_comma { ".. }" } else { ", .. }" };
1421
1422         let mut err = struct_span_err!(
1423             sess,
1424             pat.span,
1425             E0638,
1426             "`..` required with {descr} marked as non-exhaustive",
1427         );
1428         err.span_suggestion_verbose(
1429             sp_comma,
1430             "add `..` at the end of the field list to ignore all other fields",
1431             sugg.to_string(),
1432             Applicability::MachineApplicable,
1433         );
1434         err.emit();
1435     }
1436
1437     fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) {
1438         struct_span_err!(
1439             self.tcx.sess,
1440             span,
1441             E0025,
1442             "field `{}` bound multiple times in the pattern",
1443             ident
1444         )
1445         .span_label(span, format!("multiple uses of `{ident}` in pattern"))
1446         .span_label(other_field, format!("first use of `{ident}`"))
1447         .emit();
1448     }
1449
1450     fn error_inexistent_fields(
1451         &self,
1452         kind_name: &str,
1453         inexistent_fields: &[&hir::PatField<'tcx>],
1454         unmentioned_fields: &mut Vec<(&'tcx ty::FieldDef, Ident)>,
1455         variant: &ty::VariantDef,
1456         substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
1457     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
1458         let tcx = self.tcx;
1459         let (field_names, t, plural) = if inexistent_fields.len() == 1 {
1460             (format!("a field named `{}`", inexistent_fields[0].ident), "this", "")
1461         } else {
1462             (
1463                 format!(
1464                     "fields named {}",
1465                     inexistent_fields
1466                         .iter()
1467                         .map(|field| format!("`{}`", field.ident))
1468                         .collect::<Vec<String>>()
1469                         .join(", ")
1470                 ),
1471                 "these",
1472                 "s",
1473             )
1474         };
1475         let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::<Vec<_>>();
1476         let mut err = struct_span_err!(
1477             tcx.sess,
1478             spans,
1479             E0026,
1480             "{} `{}` does not have {}",
1481             kind_name,
1482             tcx.def_path_str(variant.def_id),
1483             field_names
1484         );
1485         if let Some(pat_field) = inexistent_fields.last() {
1486             err.span_label(
1487                 pat_field.ident.span,
1488                 format!(
1489                     "{} `{}` does not have {} field{}",
1490                     kind_name,
1491                     tcx.def_path_str(variant.def_id),
1492                     t,
1493                     plural
1494                 ),
1495             );
1496
1497             if unmentioned_fields.len() == 1 {
1498                 let input =
1499                     unmentioned_fields.iter().map(|(_, field)| field.name).collect::<Vec<_>>();
1500                 let suggested_name = find_best_match_for_name(&input, pat_field.ident.name, None);
1501                 if let Some(suggested_name) = suggested_name {
1502                     err.span_suggestion(
1503                         pat_field.ident.span,
1504                         "a field with a similar name exists",
1505                         suggested_name.to_string(),
1506                         Applicability::MaybeIncorrect,
1507                     );
1508
1509                     // When we have a tuple struct used with struct we don't want to suggest using
1510                     // the (valid) struct syntax with numeric field names. Instead we want to
1511                     // suggest the expected syntax. We infer that this is the case by parsing the
1512                     // `Ident` into an unsized integer. The suggestion will be emitted elsewhere in
1513                     // `smart_resolve_context_dependent_help`.
1514                     if suggested_name.to_ident_string().parse::<usize>().is_err() {
1515                         // We don't want to throw `E0027` in case we have thrown `E0026` for them.
1516                         unmentioned_fields.retain(|&(_, x)| x.name != suggested_name);
1517                     }
1518                 } else if inexistent_fields.len() == 1 {
1519                     match pat_field.pat.kind {
1520                         PatKind::Lit(expr)
1521                             if !self.can_coerce(
1522                                 self.typeck_results.borrow().expr_ty(expr),
1523                                 self.field_ty(
1524                                     unmentioned_fields[0].1.span,
1525                                     unmentioned_fields[0].0,
1526                                     substs,
1527                                 ),
1528                             ) => {}
1529                         _ => {
1530                             let unmentioned_field = unmentioned_fields[0].1.name;
1531                             err.span_suggestion_short(
1532                                 pat_field.ident.span,
1533                                 &format!(
1534                                     "`{}` has a field named `{}`",
1535                                     tcx.def_path_str(variant.def_id),
1536                                     unmentioned_field
1537                                 ),
1538                                 unmentioned_field.to_string(),
1539                                 Applicability::MaybeIncorrect,
1540                             );
1541                         }
1542                     }
1543                 }
1544             }
1545         }
1546         if tcx.sess.teach(&err.get_code().unwrap()) {
1547             err.note(
1548                 "This error indicates that a struct pattern attempted to \
1549                  extract a non-existent field from a struct. Struct fields \
1550                  are identified by the name used before the colon : so struct \
1551                  patterns should resemble the declaration of the struct type \
1552                  being matched.\n\n\
1553                  If you are using shorthand field patterns but want to refer \
1554                  to the struct field by a different name, you should rename \
1555                  it explicitly.",
1556             );
1557         }
1558         err
1559     }
1560
1561     fn error_tuple_variant_as_struct_pat(
1562         &self,
1563         pat: &Pat<'_>,
1564         fields: &'tcx [hir::PatField<'tcx>],
1565         variant: &ty::VariantDef,
1566     ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
1567         if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) {
1568             let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
1569                 s.print_qpath(qpath, false)
1570             });
1571             let mut err = struct_span_err!(
1572                 self.tcx.sess,
1573                 pat.span,
1574                 E0769,
1575                 "tuple variant `{}` written as struct variant",
1576                 path
1577             );
1578             let (sugg, appl) = if fields.len() == variant.fields.len() {
1579                 (
1580                     self.get_suggested_tuple_struct_pattern(fields, variant),
1581                     Applicability::MachineApplicable,
1582                 )
1583             } else {
1584                 (
1585                     variant.fields.iter().map(|_| "_").collect::<Vec<&str>>().join(", "),
1586                     Applicability::MaybeIncorrect,
1587                 )
1588             };
1589             err.span_suggestion_verbose(
1590                 qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()),
1591                 "use the tuple variant pattern syntax instead",
1592                 format!("({})", sugg),
1593                 appl,
1594             );
1595             return Some(err);
1596         }
1597         None
1598     }
1599
1600     fn get_suggested_tuple_struct_pattern(
1601         &self,
1602         fields: &[hir::PatField<'_>],
1603         variant: &VariantDef,
1604     ) -> String {
1605         let variant_field_idents =
1606             variant.fields.iter().map(|f| f.ident(self.tcx)).collect::<Vec<Ident>>();
1607         fields
1608             .iter()
1609             .map(|field| {
1610                 match self.tcx.sess.source_map().span_to_snippet(field.pat.span) {
1611                     Ok(f) => {
1612                         // Field names are numbers, but numbers
1613                         // are not valid identifiers
1614                         if variant_field_idents.contains(&field.ident) {
1615                             String::from("_")
1616                         } else {
1617                             f
1618                         }
1619                     }
1620                     Err(_) => rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
1621                         s.print_pat(field.pat)
1622                     }),
1623                 }
1624             })
1625             .collect::<Vec<String>>()
1626             .join(", ")
1627     }
1628
1629     /// Returns a diagnostic reporting a struct pattern which is missing an `..` due to
1630     /// inaccessible fields.
1631     ///
1632     /// ```text
1633     /// error: pattern requires `..` due to inaccessible fields
1634     ///   --> src/main.rs:10:9
1635     ///    |
1636     /// LL |     let foo::Foo {} = foo::Foo::default();
1637     ///    |         ^^^^^^^^^^^
1638     ///    |
1639     /// help: add a `..`
1640     ///    |
1641     /// LL |     let foo::Foo { .. } = foo::Foo::default();
1642     ///    |                  ^^^^^^
1643     /// ```
1644     fn error_no_accessible_fields(
1645         &self,
1646         pat: &Pat<'_>,
1647         fields: &'tcx [hir::PatField<'tcx>],
1648     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
1649         let mut err = self
1650             .tcx
1651             .sess
1652             .struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields");
1653
1654         if let Some(field) = fields.last() {
1655             err.span_suggestion_verbose(
1656                 field.span.shrink_to_hi(),
1657                 "ignore the inaccessible and unused fields",
1658                 ", ..".to_string(),
1659                 Applicability::MachineApplicable,
1660             );
1661         } else {
1662             let qpath_span = if let PatKind::Struct(qpath, ..) = &pat.kind {
1663                 qpath.span()
1664             } else {
1665                 bug!("`error_no_accessible_fields` called on non-struct pattern");
1666             };
1667
1668             // Shrink the span to exclude the `foo:Foo` in `foo::Foo { }`.
1669             let span = pat.span.with_lo(qpath_span.shrink_to_hi().hi());
1670             err.span_suggestion_verbose(
1671                 span,
1672                 "ignore the inaccessible and unused fields",
1673                 " { .. }".to_string(),
1674                 Applicability::MachineApplicable,
1675             );
1676         }
1677         err
1678     }
1679
1680     /// Report that a pattern for a `#[non_exhaustive]` struct marked with `non_exhaustive_omitted_patterns`
1681     /// is not exhaustive enough.
1682     ///
1683     /// Nb: the partner lint for enums lives in `compiler/rustc_mir_build/src/thir/pattern/usefulness.rs`.
1684     fn lint_non_exhaustive_omitted_patterns(
1685         &self,
1686         pat: &Pat<'_>,
1687         unmentioned_fields: &[(&ty::FieldDef, Ident)],
1688         ty: Ty<'tcx>,
1689     ) {
1690         fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String {
1691             const LIMIT: usize = 3;
1692             match witnesses {
1693                 [] => bug!(),
1694                 [witness] => format!("`{}`", witness),
1695                 [head @ .., tail] if head.len() < LIMIT => {
1696                     let head: Vec<_> = head.iter().map(<_>::to_string).collect();
1697                     format!("`{}` and `{}`", head.join("`, `"), tail)
1698                 }
1699                 _ => {
1700                     let (head, tail) = witnesses.split_at(LIMIT);
1701                     let head: Vec<_> = head.iter().map(<_>::to_string).collect();
1702                     format!("`{}` and {} more", head.join("`, `"), tail.len())
1703                 }
1704             }
1705         }
1706         let joined_patterns = joined_uncovered_patterns(
1707             &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(),
1708         );
1709
1710         self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |build| {
1711         let mut lint = build.build("some fields are not explicitly listed");
1712         lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns));
1713
1714         lint.help(
1715             "ensure that all fields are mentioned explicitly by adding the suggested fields",
1716         );
1717         lint.note(&format!(
1718             "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
1719             ty,
1720         ));
1721         lint.emit();
1722     });
1723     }
1724
1725     /// Returns a diagnostic reporting a struct pattern which does not mention some fields.
1726     ///
1727     /// ```text
1728     /// error[E0027]: pattern does not mention field `bar`
1729     ///   --> src/main.rs:15:9
1730     ///    |
1731     /// LL |     let foo::Foo {} = foo::Foo::new();
1732     ///    |         ^^^^^^^^^^^ missing field `bar`
1733     /// ```
1734     fn error_unmentioned_fields(
1735         &self,
1736         pat: &Pat<'_>,
1737         unmentioned_fields: &[(&ty::FieldDef, Ident)],
1738         have_inaccessible_fields: bool,
1739         fields: &'tcx [hir::PatField<'tcx>],
1740     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
1741         let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
1742         let field_names = if unmentioned_fields.len() == 1 {
1743             format!("field `{}`{}", unmentioned_fields[0].1, inaccessible)
1744         } else {
1745             let fields = unmentioned_fields
1746                 .iter()
1747                 .map(|(_, name)| format!("`{}`", name))
1748                 .collect::<Vec<String>>()
1749                 .join(", ");
1750             format!("fields {}{}", fields, inaccessible)
1751         };
1752         let mut err = struct_span_err!(
1753             self.tcx.sess,
1754             pat.span,
1755             E0027,
1756             "pattern does not mention {}",
1757             field_names
1758         );
1759         err.span_label(pat.span, format!("missing {}", field_names));
1760         let len = unmentioned_fields.len();
1761         let (prefix, postfix, sp) = match fields {
1762             [] => match &pat.kind {
1763                 PatKind::Struct(path, [], false) => {
1764                     (" { ", " }", path.span().shrink_to_hi().until(pat.span.shrink_to_hi()))
1765                 }
1766                 _ => return err,
1767             },
1768             [.., field] => {
1769                 // Account for last field having a trailing comma or parse recovery at the tail of
1770                 // the pattern to avoid invalid suggestion (#78511).
1771                 let tail = field.span.shrink_to_hi().with_hi(pat.span.hi());
1772                 match &pat.kind {
1773                     PatKind::Struct(..) => (", ", " }", tail),
1774                     _ => return err,
1775                 }
1776             }
1777         };
1778         err.span_suggestion(
1779             sp,
1780             &format!(
1781                 "include the missing field{} in the pattern{}",
1782                 pluralize!(len),
1783                 if have_inaccessible_fields { " and ignore the inaccessible fields" } else { "" }
1784             ),
1785             format!(
1786                 "{}{}{}{}",
1787                 prefix,
1788                 unmentioned_fields
1789                     .iter()
1790                     .map(|(_, name)| name.to_string())
1791                     .collect::<Vec<_>>()
1792                     .join(", "),
1793                 if have_inaccessible_fields { ", .." } else { "" },
1794                 postfix,
1795             ),
1796             Applicability::MachineApplicable,
1797         );
1798         err.span_suggestion(
1799             sp,
1800             &format!(
1801                 "if you don't care about {these} missing field{s}, you can explicitly ignore {them}",
1802                 these = pluralize!("this", len),
1803                 s = pluralize!(len),
1804                 them = if len == 1 { "it" } else { "them" },
1805             ),
1806             format!("{}..{}", prefix, postfix),
1807             Applicability::MachineApplicable,
1808         );
1809         err
1810     }
1811
1812     fn check_pat_box(
1813         &self,
1814         span: Span,
1815         inner: &'tcx Pat<'tcx>,
1816         expected: Ty<'tcx>,
1817         def_bm: BindingMode,
1818         ti: TopInfo<'tcx>,
1819     ) -> Ty<'tcx> {
1820         let tcx = self.tcx;
1821         let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, inner) {
1822             // Here, `demand::subtype` is good enough, but I don't
1823             // think any errors can be introduced by using `demand::eqtype`.
1824             let inner_ty = self.next_ty_var(TypeVariableOrigin {
1825                 kind: TypeVariableOriginKind::TypeInference,
1826                 span: inner.span,
1827             });
1828             let box_ty = tcx.mk_box(inner_ty);
1829             self.demand_eqtype_pat(span, expected, box_ty, ti);
1830             (box_ty, inner_ty)
1831         } else {
1832             let err = tcx.ty_error();
1833             (err, err)
1834         };
1835         self.check_pat(inner, inner_ty, def_bm, ti);
1836         box_ty
1837     }
1838
1839     fn check_pat_ref(
1840         &self,
1841         pat: &'tcx Pat<'tcx>,
1842         inner: &'tcx Pat<'tcx>,
1843         mutbl: hir::Mutability,
1844         expected: Ty<'tcx>,
1845         def_bm: BindingMode,
1846         ti: TopInfo<'tcx>,
1847     ) -> Ty<'tcx> {
1848         let tcx = self.tcx;
1849         let expected = self.shallow_resolve(expected);
1850         let (rptr_ty, inner_ty) = if self.check_dereferenceable(pat.span, expected, inner) {
1851             // `demand::subtype` would be good enough, but using `eqtype` turns
1852             // out to be equally general. See (note_1) for details.
1853
1854             // Take region, inner-type from expected type if we can,
1855             // to avoid creating needless variables. This also helps with
1856             // the bad  interactions of the given hack detailed in (note_1).
1857             debug!("check_pat_ref: expected={:?}", expected);
1858             match *expected.kind() {
1859                 ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
1860                 _ => {
1861                     let inner_ty = self.next_ty_var(TypeVariableOrigin {
1862                         kind: TypeVariableOriginKind::TypeInference,
1863                         span: inner.span,
1864                     });
1865                     let rptr_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
1866                     debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
1867                     let err = self.demand_eqtype_pat_diag(pat.span, expected, rptr_ty, ti);
1868
1869                     // Look for a case like `fn foo(&foo: u32)` and suggest
1870                     // `fn foo(foo: &u32)`
1871                     if let Some(mut err) = err {
1872                         self.borrow_pat_suggestion(&mut err, pat, inner, expected);
1873                         err.emit();
1874                     }
1875                     (rptr_ty, inner_ty)
1876                 }
1877             }
1878         } else {
1879             let err = tcx.ty_error();
1880             (err, err)
1881         };
1882         self.check_pat(inner, inner_ty, def_bm, TopInfo { parent_pat: Some(pat), ..ti });
1883         rptr_ty
1884     }
1885
1886     /// Create a reference type with a fresh region variable.
1887     fn new_ref_ty(&self, span: Span, mutbl: hir::Mutability, ty: Ty<'tcx>) -> Ty<'tcx> {
1888         let region = self.next_region_var(infer::PatternRegion(span));
1889         let mt = ty::TypeAndMut { ty, mutbl };
1890         self.tcx.mk_ref(region, mt)
1891     }
1892
1893     /// Type check a slice pattern.
1894     ///
1895     /// Syntactically, these look like `[pat_0, ..., pat_n]`.
1896     /// Semantically, we are type checking a pattern with structure:
1897     /// ```ignore (not-rust)
1898     /// [before_0, ..., before_n, (slice, after_0, ... after_n)?]
1899     /// ```
1900     /// The type of `slice`, if it is present, depends on the `expected` type.
1901     /// If `slice` is missing, then so is `after_i`.
1902     /// If `slice` is present, it can still represent 0 elements.
1903     fn check_pat_slice(
1904         &self,
1905         span: Span,
1906         before: &'tcx [Pat<'tcx>],
1907         slice: Option<&'tcx Pat<'tcx>>,
1908         after: &'tcx [Pat<'tcx>],
1909         expected: Ty<'tcx>,
1910         def_bm: BindingMode,
1911         ti: TopInfo<'tcx>,
1912     ) -> Ty<'tcx> {
1913         let expected = self.structurally_resolved_type(span, expected);
1914         let (element_ty, opt_slice_ty, inferred) = match *expected.kind() {
1915             // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
1916             ty::Array(element_ty, len) => {
1917                 let min = before.len() as u64 + after.len() as u64;
1918                 let (opt_slice_ty, expected) =
1919                     self.check_array_pat_len(span, element_ty, expected, slice, len, min);
1920                 // `opt_slice_ty.is_none()` => `slice.is_none()`.
1921                 // Note, though, that opt_slice_ty could be `Some(error_ty)`.
1922                 assert!(opt_slice_ty.is_some() || slice.is_none());
1923                 (element_ty, opt_slice_ty, expected)
1924             }
1925             ty::Slice(element_ty) => (element_ty, Some(expected), expected),
1926             // The expected type must be an array or slice, but was neither, so error.
1927             _ => {
1928                 if !expected.references_error() {
1929                     self.error_expected_array_or_slice(span, expected, ti);
1930                 }
1931                 let err = self.tcx.ty_error();
1932                 (err, Some(err), err)
1933             }
1934         };
1935
1936         // Type check all the patterns before `slice`.
1937         for elt in before {
1938             self.check_pat(elt, element_ty, def_bm, ti);
1939         }
1940         // Type check the `slice`, if present, against its expected type.
1941         if let Some(slice) = slice {
1942             self.check_pat(slice, opt_slice_ty.unwrap(), def_bm, ti);
1943         }
1944         // Type check the elements after `slice`, if present.
1945         for elt in after {
1946             self.check_pat(elt, element_ty, def_bm, ti);
1947         }
1948         inferred
1949     }
1950
1951     /// Type check the length of an array pattern.
1952     ///
1953     /// Returns both the type of the variable length pattern (or `None`), and the potentially
1954     /// inferred array type. We only return `None` for the slice type if `slice.is_none()`.
1955     fn check_array_pat_len(
1956         &self,
1957         span: Span,
1958         element_ty: Ty<'tcx>,
1959         arr_ty: Ty<'tcx>,
1960         slice: Option<&'tcx Pat<'tcx>>,
1961         len: ty::Const<'tcx>,
1962         min_len: u64,
1963     ) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
1964         if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) {
1965             // Now we know the length...
1966             if slice.is_none() {
1967                 // ...and since there is no variable-length pattern,
1968                 // we require an exact match between the number of elements
1969                 // in the array pattern and as provided by the matched type.
1970                 if min_len == len {
1971                     return (None, arr_ty);
1972                 }
1973
1974                 self.error_scrutinee_inconsistent_length(span, min_len, len);
1975             } else if let Some(pat_len) = len.checked_sub(min_len) {
1976                 // The variable-length pattern was there,
1977                 // so it has an array type with the remaining elements left as its size...
1978                 return (Some(self.tcx.mk_array(element_ty, pat_len)), arr_ty);
1979             } else {
1980                 // ...however, in this case, there were no remaining elements.
1981                 // That is, the slice pattern requires more than the array type offers.
1982                 self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
1983             }
1984         } else if slice.is_none() {
1985             // We have a pattern with a fixed length,
1986             // which we can use to infer the length of the array.
1987             let updated_arr_ty = self.tcx.mk_array(element_ty, min_len);
1988             self.demand_eqtype(span, updated_arr_ty, arr_ty);
1989             return (None, updated_arr_ty);
1990         } else {
1991             // We have a variable-length pattern and don't know the array length.
1992             // This happens if we have e.g.,
1993             // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
1994             self.error_scrutinee_unfixed_length(span);
1995         }
1996
1997         // If we get here, we must have emitted an error.
1998         (Some(self.tcx.ty_error()), arr_ty)
1999     }
2000
2001     fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
2002         struct_span_err!(
2003             self.tcx.sess,
2004             span,
2005             E0527,
2006             "pattern requires {} element{} but array has {}",
2007             min_len,
2008             pluralize!(min_len),
2009             size,
2010         )
2011         .span_label(span, format!("expected {} element{}", size, pluralize!(size)))
2012         .emit();
2013     }
2014
2015     fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
2016         struct_span_err!(
2017             self.tcx.sess,
2018             span,
2019             E0528,
2020             "pattern requires at least {} element{} but array has {}",
2021             min_len,
2022             pluralize!(min_len),
2023             size,
2024         )
2025         .span_label(
2026             span,
2027             format!("pattern cannot match array of {} element{}", size, pluralize!(size),),
2028         )
2029         .emit();
2030     }
2031
2032     fn error_scrutinee_unfixed_length(&self, span: Span) {
2033         struct_span_err!(
2034             self.tcx.sess,
2035             span,
2036             E0730,
2037             "cannot pattern-match on an array without a fixed length",
2038         )
2039         .emit();
2040     }
2041
2042     fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
2043         let mut err = struct_span_err!(
2044             self.tcx.sess,
2045             span,
2046             E0529,
2047             "expected an array or slice, found `{expected_ty}`"
2048         );
2049         if let ty::Ref(_, ty, _) = expected_ty.kind()
2050             && let ty::Array(..) | ty::Slice(..) = ty.kind()
2051         {
2052             err.help("the semantics of slice patterns changed recently; see issue #62254");
2053         } else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
2054             .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
2055             && let (Some(span), true) = (ti.span, ti.origin_expr)
2056             && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
2057         {
2058             let ty = self.resolve_vars_if_possible(ti.expected);
2059             let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(&mut err, snippet.clone(), ty);
2060             match is_slice_or_array_or_vector.1.kind() {
2061                 ty::Adt(adt_def, _)
2062                     if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
2063                         || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
2064                 {
2065                     // Slicing won't work here, but `.as_deref()` might (issue #91328).
2066                     err.span_suggestion(
2067                         span,
2068                         "consider using `as_deref` here",
2069                         format!("{snippet}.as_deref()"),
2070                         Applicability::MaybeIncorrect,
2071                     );
2072                 }
2073                 _ => ()
2074             }
2075             if is_slice_or_array_or_vector.0 {
2076                 err.span_suggestion(
2077                     span,
2078                     "consider slicing here",
2079                     format!("{snippet}[..]"),
2080                     Applicability::MachineApplicable,
2081                 );
2082             }
2083         }
2084         err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`"));
2085         err.emit();
2086     }
2087
2088     fn is_slice_or_array_or_vector(
2089         &self,
2090         err: &mut Diagnostic,
2091         snippet: String,
2092         ty: Ty<'tcx>,
2093     ) -> (bool, Ty<'tcx>) {
2094         match ty.kind() {
2095             ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => {
2096                 (true, ty)
2097             }
2098             ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(err, snippet, *ty),
2099             ty::Slice(..) | ty::Array(..) => (true, ty),
2100             _ => (false, ty),
2101         }
2102     }
2103 }