]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/_match.rs
Rollup merge of #61499 - varkor:issue-53457, r=oli-obk
[rust.git] / src / librustc_typeck / check / _match.rs
1 use crate::check::{FnCtxt, Expectation, Diverges, Needs};
2 use crate::check::coercion::CoerceMany;
3 use crate::util::nodemap::FxHashMap;
4 use errors::{Applicability, DiagnosticBuilder};
5 use rustc::hir::{self, PatKind, Pat, ExprKind};
6 use rustc::hir::def::{Res, DefKind, CtorKind};
7 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
8 use rustc::infer;
9 use rustc::infer::type_variable::TypeVariableOrigin;
10 use rustc::traits::{ObligationCause, ObligationCauseCode};
11 use rustc::ty::{self, Ty, TypeFoldable};
12 use rustc::ty::subst::Kind;
13 use syntax::ast;
14 use syntax::source_map::Spanned;
15 use syntax::ptr::P;
16 use syntax::util::lev_distance::find_best_match_for_name;
17 use syntax_pos::Span;
18 use syntax_pos::hygiene::CompilerDesugaringKind;
19
20 use std::collections::hash_map::Entry::{Occupied, Vacant};
21 use std::cmp;
22
23 use super::report_unexpected_variant_res;
24
25 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26     /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
27     /// expression arm guard, and it points to the match discriminant to add context in type errors.
28     /// In the following example, `discrim_span` corresponds to the `a + b` expression:
29     ///
30     /// ```text
31     /// error[E0308]: mismatched types
32     ///  --> src/main.rs:5:9
33     ///   |
34     /// 4 |    let temp: usize = match a + b {
35     ///   |                            ----- this expression has type `usize`
36     /// 5 |         Ok(num) => num,
37     ///   |         ^^^^^^^ expected usize, found enum `std::result::Result`
38     ///   |
39     ///   = note: expected type `usize`
40     ///              found type `std::result::Result<_, _>`
41     /// ```
42     pub fn check_pat_walk(
43         &self,
44         pat: &'gcx hir::Pat,
45         mut expected: Ty<'tcx>,
46         mut def_bm: ty::BindingMode,
47         discrim_span: Option<Span>,
48     ) {
49         let tcx = self.tcx;
50
51         debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
52
53         let is_non_ref_pat = match pat.node {
54             PatKind::Struct(..) |
55             PatKind::TupleStruct(..) |
56             PatKind::Tuple(..) |
57             PatKind::Box(_) |
58             PatKind::Range(..) |
59             PatKind::Slice(..) => true,
60             PatKind::Lit(ref lt) => {
61                 let ty = self.check_expr(lt);
62                 match ty.sty {
63                     ty::Ref(..) => false,
64                     _ => true,
65                 }
66             }
67             PatKind::Path(ref qpath) => {
68                 let (def, _, _) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
69                 match def {
70                     Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
71                     _ => true,
72                 }
73             }
74             PatKind::Wild |
75             PatKind::Binding(..) |
76             PatKind::Ref(..) => false,
77         };
78         if is_non_ref_pat {
79             debug!("pattern is non reference pattern");
80             let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
81
82             // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
83             // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
84             // the `Some(5)` which is not of type Ref.
85             //
86             // For each ampersand peeled off, update the binding mode and push the original
87             // type into the adjustments vector.
88             //
89             // See the examples in `run-pass/match-defbm*.rs`.
90             let mut pat_adjustments = vec![];
91             while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
92                 debug!("inspecting {:?}", exp_ty);
93
94                 debug!("current discriminant is Ref, inserting implicit deref");
95                 // Preserve the reference type. We'll need it later during HAIR lowering.
96                 pat_adjustments.push(exp_ty);
97
98                 exp_ty = inner_ty;
99                 def_bm = match def_bm {
100                     // If default binding mode is by value, make it `ref` or `ref mut`
101                     // (depending on whether we observe `&` or `&mut`).
102                     ty::BindByValue(_) =>
103                         ty::BindByReference(inner_mutability),
104
105                     // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
106                     // the underlying value.
107                     ty::BindByReference(hir::Mutability::MutImmutable) =>
108                         ty::BindByReference(hir::Mutability::MutImmutable),
109
110                     // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
111                     // (on `&`).
112                     ty::BindByReference(hir::Mutability::MutMutable) =>
113                         ty::BindByReference(inner_mutability),
114                 };
115             }
116             expected = exp_ty;
117
118             if pat_adjustments.len() > 0 {
119                 debug!("default binding mode is now {:?}", def_bm);
120                 self.inh.tables.borrow_mut()
121                     .pat_adjustments_mut()
122                     .insert(pat.hir_id, pat_adjustments);
123             }
124         } else if let PatKind::Ref(..) = pat.node {
125             // When you encounter a `&pat` pattern, reset to "by
126             // value". This is so that `x` and `y` here are by value,
127             // as they appear to be:
128             //
129             // ```
130             // match &(&22, &44) {
131             //   (&x, &y) => ...
132             // }
133             // ```
134             //
135             // cc #46688
136             def_bm = ty::BindByValue(hir::MutImmutable);
137         }
138
139         // Lose mutability now that we know binding mode and discriminant type.
140         let def_bm = def_bm;
141         let expected = expected;
142
143         let ty = match pat.node {
144             PatKind::Wild => {
145                 expected
146             }
147             PatKind::Lit(ref lt) => {
148                 // We've already computed the type above (when checking for a non-ref pat), so
149                 // avoid computing it again.
150                 let ty = self.node_ty(lt.hir_id);
151
152                 // Byte string patterns behave the same way as array patterns
153                 // They can denote both statically and dynamically sized byte arrays
154                 let mut pat_ty = ty;
155                 if let hir::ExprKind::Lit(ref lt) = lt.node {
156                     if let ast::LitKind::ByteStr(_) = lt.node {
157                         let expected_ty = self.structurally_resolved_type(pat.span, expected);
158                         if let ty::Ref(_, r_ty, _) = expected_ty.sty {
159                             if let ty::Slice(_) = r_ty.sty {
160                                 pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
161                                                         tcx.mk_slice(tcx.types.u8))
162                             }
163                         }
164                     }
165                 }
166
167                 // somewhat surprising: in this case, the subtyping
168                 // relation goes the opposite way as the other
169                 // cases. Actually what we really want is not a subtyping
170                 // relation at all but rather that there exists a LUB (so
171                 // that they can be compared). However, in practice,
172                 // constants are always scalars or strings.  For scalars
173                 // subtyping is irrelevant, and for strings `ty` is
174                 // type is `&'static str`, so if we say that
175                 //
176                 //     &'static str <: expected
177                 //
178                 // that's equivalent to there existing a LUB.
179                 if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
180                     err.emit_unless(discrim_span
181                         .filter(|&s| s.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary))
182                         .is_some());
183                 }
184
185                 pat_ty
186             }
187             PatKind::Range(ref begin, ref end, _) => {
188                 let lhs_ty = self.check_expr(begin);
189                 let rhs_ty = self.check_expr(end);
190
191                 // Check that both end-points are of numeric or char type.
192                 let numeric_or_char = |ty: Ty<'_>| ty.is_numeric() || ty.is_char();
193                 let lhs_compat = numeric_or_char(lhs_ty);
194                 let rhs_compat = numeric_or_char(rhs_ty);
195
196                 if !lhs_compat || !rhs_compat {
197                     let span = if !lhs_compat && !rhs_compat {
198                         pat.span
199                     } else if !lhs_compat {
200                         begin.span
201                     } else {
202                         end.span
203                     };
204
205                     let mut err = struct_span_err!(
206                         tcx.sess,
207                         span,
208                         E0029,
209                         "only char and numeric types are allowed in range patterns"
210                     );
211                     err.span_label(span, "ranges require char or numeric types");
212                     err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
213                     err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
214                     if tcx.sess.teach(&err.get_code().unwrap()) {
215                         err.note(
216                             "In a match expression, only numbers and characters can be matched \
217                              against a range. This is because the compiler checks that the range \
218                              is non-empty at compile-time, and is unable to evaluate arbitrary \
219                              comparison functions. If you want to capture values of an orderable \
220                              type between two end-points, you can use a guard."
221                          );
222                     }
223                     err.emit();
224                     return;
225                 }
226
227                 // Now that we know the types can be unified we find the unified type and use
228                 // it to type the entire expression.
229                 let common_type = self.resolve_vars_if_possible(&lhs_ty);
230
231                 // subtyping doesn't matter here, as the value is some kind of scalar
232                 self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
233                 self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span);
234                 common_type
235             }
236             PatKind::Binding(ba, var_id, _, ref sub) => {
237                 let bm = if ba == hir::BindingAnnotation::Unannotated {
238                     def_bm
239                 } else {
240                     ty::BindingMode::convert(ba)
241                 };
242                 self.inh
243                     .tables
244                     .borrow_mut()
245                     .pat_binding_modes_mut()
246                     .insert(pat.hir_id, bm);
247                 debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
248                 let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
249                 match bm {
250                     ty::BindByReference(mutbl) => {
251                         // if the binding is like
252                         //    ref x | ref const x | ref mut x
253                         // then `x` is assigned a value of type `&M T` where M is the mutability
254                         // and T is the expected type.
255                         let region_var = self.next_region_var(infer::PatternRegion(pat.span));
256                         let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
257                         let region_ty = tcx.mk_ref(region_var, mt);
258
259                         // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
260                         // required. However, we use equality, which is stronger. See (*) for
261                         // an explanation.
262                         self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span);
263                     }
264                     // otherwise the type of x is the expected type T
265                     ty::BindByValue(_) => {
266                         // As above, `T <: typeof(x)` is required but we
267                         // use equality, see (*) below.
268                         self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span);
269                     }
270                 }
271
272                 // if there are multiple arms, make sure they all agree on
273                 // what the type of the binding `x` ought to be
274                 if var_id != pat.hir_id {
275                     let vt = self.local_ty(pat.span, var_id).decl_ty;
276                     self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
277                 }
278
279                 if let Some(ref p) = *sub {
280                     self.check_pat_walk(&p, expected, def_bm, discrim_span);
281                 }
282
283                 local_ty
284             }
285             PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
286                 self.check_pat_tuple_struct(
287                     pat,
288                     qpath,
289                     &subpats,
290                     ddpos,
291                     expected,
292                     def_bm,
293                     discrim_span,
294                 )
295             }
296             PatKind::Path(ref qpath) => {
297                 self.check_pat_path(pat, qpath, expected)
298             }
299             PatKind::Struct(ref qpath, ref fields, etc) => {
300                 self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
301             }
302             PatKind::Tuple(ref elements, ddpos) => {
303                 let mut expected_len = elements.len();
304                 if ddpos.is_some() {
305                     // Require known type only when `..` is present.
306                     if let ty::Tuple(ref tys) =
307                             self.structurally_resolved_type(pat.span, expected).sty {
308                         expected_len = tys.len();
309                     }
310                 }
311                 let max_len = cmp::max(expected_len, elements.len());
312
313                 let element_tys_iter = (0..max_len).map(|_| {
314                     // FIXME: `MiscVariable` for now -- obtaining the span and name information
315                     // from all tuple elements isn't trivial.
316                     Kind::from(self.next_ty_var(TypeVariableOrigin::TypeInference(pat.span)))
317                 });
318                 let element_tys = tcx.mk_substs(element_tys_iter);
319                 let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
320                 if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
321                     err.emit();
322                     // Walk subpatterns with an expected type of `err` in this case to silence
323                     // further errors being emitted when using the bindings. #50333
324                     let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
325                     for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
326                         self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
327                     }
328                     tcx.mk_tup(element_tys_iter)
329                 } else {
330                     for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
331                         self.check_pat_walk(
332                             elem,
333                             &element_tys[i].expect_ty(),
334                             def_bm,
335                             discrim_span,
336                         );
337                     }
338                     pat_ty
339                 }
340             }
341             PatKind::Box(ref inner) => {
342                 let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));
343                 let uniq_ty = tcx.mk_box(inner_ty);
344
345                 if self.check_dereferencable(pat.span, expected, &inner) {
346                     // Here, `demand::subtype` is good enough, but I don't
347                     // think any errors can be introduced by using
348                     // `demand::eqtype`.
349                     self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
350                     self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
351                     uniq_ty
352                 } else {
353                     self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
354                     tcx.types.err
355                 }
356             }
357             PatKind::Ref(ref inner, mutbl) => {
358                 let expected = self.shallow_resolve(expected);
359                 if self.check_dereferencable(pat.span, expected, &inner) {
360                     // `demand::subtype` would be good enough, but using
361                     // `eqtype` turns out to be equally general. See (*)
362                     // below for details.
363
364                     // Take region, inner-type from expected type if we
365                     // can, to avoid creating needless variables.  This
366                     // also helps with the bad interactions of the given
367                     // hack detailed in (*) below.
368                     debug!("check_pat_walk: expected={:?}", expected);
369                     let (rptr_ty, inner_ty) = match expected.sty {
370                         ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
371                             (expected, r_ty)
372                         }
373                         _ => {
374                             let inner_ty = self.next_ty_var(
375                                 TypeVariableOrigin::TypeInference(inner.span));
376                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
377                             let region = self.next_region_var(infer::PatternRegion(pat.span));
378                             let rptr_ty = tcx.mk_ref(region, mt);
379                             debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
380                             let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
381
382                             // Look for a case like `fn foo(&foo: u32)` and suggest
383                             // `fn foo(foo: &u32)`
384                             if let Some(mut err) = err {
385                                 self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
386                                 err.emit();
387                             }
388                             (rptr_ty, inner_ty)
389                         }
390                     };
391
392                     self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
393                     rptr_ty
394                 } else {
395                     self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
396                     tcx.types.err
397                 }
398             }
399             PatKind::Slice(ref before, ref slice, ref after) => {
400                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
401                 let (inner_ty, slice_ty) = match expected_ty.sty {
402                     ty::Array(inner_ty, size) => {
403                         if let Some(size) = size.assert_usize(tcx) {
404                             let min_len = before.len() as u64 + after.len() as u64;
405                             if slice.is_none() {
406                                 if min_len != size {
407                                     struct_span_err!(
408                                         tcx.sess, pat.span, E0527,
409                                         "pattern requires {} elements but array has {}",
410                                         min_len, size)
411                                         .span_label(pat.span, format!("expected {} elements", size))
412                                         .emit();
413                                 }
414                                 (inner_ty, tcx.types.err)
415                             } else if let Some(rest) = size.checked_sub(min_len) {
416                                 (inner_ty, tcx.mk_array(inner_ty, rest))
417                             } else {
418                                 struct_span_err!(tcx.sess, pat.span, E0528,
419                                         "pattern requires at least {} elements but array has {}",
420                                         min_len, size)
421                                     .span_label(pat.span,
422                                         format!("pattern cannot match array of {} elements", size))
423                                     .emit();
424                                 (inner_ty, tcx.types.err)
425                             }
426                         } else {
427                             struct_span_err!(
428                                 tcx.sess,
429                                 pat.span,
430                                 E0730,
431                                 "cannot pattern-match on an array without a fixed length",
432                             ).emit();
433                             (inner_ty, tcx.types.err)
434                         }
435                     }
436                     ty::Slice(inner_ty) => (inner_ty, expected_ty),
437                     _ => {
438                         if !expected_ty.references_error() {
439                             let mut err = struct_span_err!(
440                                 tcx.sess, pat.span, E0529,
441                                 "expected an array or slice, found `{}`",
442                                 expected_ty);
443                             if let ty::Ref(_, ty, _) = expected_ty.sty {
444                                 match ty.sty {
445                                     ty::Array(..) | ty::Slice(..) => {
446                                         err.help("the semantics of slice patterns changed \
447                                                   recently; see issue #23121");
448                                     }
449                                     _ => {}
450                                 }
451                             }
452
453                             err.span_label( pat.span,
454                                 format!("pattern cannot match with input type `{}`", expected_ty)
455                             ).emit();
456                         }
457                         (tcx.types.err, tcx.types.err)
458                     }
459                 };
460
461                 for elt in before {
462                     self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
463                 }
464                 if let Some(ref slice) = *slice {
465                     self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
466                 }
467                 for elt in after {
468                     self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
469                 }
470                 expected_ty
471             }
472         };
473
474         self.write_ty(pat.hir_id, ty);
475
476         // (*) In most of the cases above (literals and constants being
477         // the exception), we relate types using strict equality, even
478         // though subtyping would be sufficient. There are a few reasons
479         // for this, some of which are fairly subtle and which cost me
480         // (nmatsakis) an hour or two debugging to remember, so I thought
481         // I'd write them down this time.
482         //
483         // 1. There is no loss of expressiveness here, though it does
484         // cause some inconvenience. What we are saying is that the type
485         // of `x` becomes *exactly* what is expected. This can cause unnecessary
486         // errors in some cases, such as this one:
487         //
488         // ```
489         // fn foo<'x>(x: &'x int) {
490         //    let a = 1;
491         //    let mut z = x;
492         //    z = &a;
493         // }
494         // ```
495         //
496         // The reason we might get an error is that `z` might be
497         // assigned a type like `&'x int`, and then we would have
498         // a problem when we try to assign `&a` to `z`, because
499         // the lifetime of `&a` (i.e., the enclosing block) is
500         // shorter than `'x`.
501         //
502         // HOWEVER, this code works fine. The reason is that the
503         // expected type here is whatever type the user wrote, not
504         // the initializer's type. In this case the user wrote
505         // nothing, so we are going to create a type variable `Z`.
506         // Then we will assign the type of the initializer (`&'x
507         // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
508         // will instantiate `Z` as a type `&'0 int` where `'0` is
509         // a fresh region variable, with the constraint that `'x :
510         // '0`.  So basically we're all set.
511         //
512         // Note that there are two tests to check that this remains true
513         // (`regions-reassign-{match,let}-bound-pointer.rs`).
514         //
515         // 2. Things go horribly wrong if we use subtype. The reason for
516         // THIS is a fairly subtle case involving bound regions. See the
517         // `givens` field in `region_constraints`, as well as the test
518         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
519         // for details. Short version is that we must sometimes detect
520         // relationships between specific region variables and regions
521         // bound in a closure signature, and that detection gets thrown
522         // off when we substitute fresh region variables here to enable
523         // subtyping.
524     }
525
526     fn borrow_pat_suggestion(
527         &self,
528         err: &mut DiagnosticBuilder<'_>,
529         pat: &Pat,
530         inner: &Pat,
531         expected: Ty<'tcx>,
532     ) {
533         let tcx = self.tcx;
534         if let PatKind::Binding(..) = inner.node {
535             let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
536             let parent = tcx.hir().get_by_hir_id(parent_id);
537             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
538             match parent {
539                 hir::Node::Item(hir::Item { node: hir::ItemKind::Fn(..), .. }) |
540                 hir::Node::ForeignItem(hir::ForeignItem {
541                     node: hir::ForeignItemKind::Fn(..), ..
542                 }) |
543                 hir::Node::TraitItem(hir::TraitItem { node: hir::TraitItemKind::Method(..), .. }) |
544                 hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => {
545                     // this pat is likely an argument
546                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
547                         // FIXME: turn into structured suggestion, will need a span that also
548                         // includes the the arg's type.
549                         err.help(&format!("did you mean `{}: &{}`?", snippet, expected));
550                     }
551                 }
552                 hir::Node::Arm(_) |
553                 hir::Node::Pat(_) => {
554                     // rely on match ergonomics or it might be nested `&&pat`
555                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
556                         err.span_suggestion(
557                             pat.span,
558                             "you can probably remove the explicit borrow",
559                             snippet,
560                             Applicability::MaybeIncorrect,
561                         );
562                     }
563                 }
564                 _ => {} // don't provide suggestions in other cases #55175
565             }
566         }
567     }
568
569     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
570         if let PatKind::Binding(..) = inner.node {
571             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
572                 if let ty::Dynamic(..) = mt.ty.sty {
573                     // This is "x = SomeTrait" being reduced from
574                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
575                     let type_str = self.ty_to_string(expected);
576                     let mut err = struct_span_err!(
577                         self.tcx.sess,
578                         span,
579                         E0033,
580                         "type `{}` cannot be dereferenced",
581                         type_str
582                     );
583                     err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
584                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
585                         err.note("\
586 This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
587 pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
588 this type has no compile-time size. Therefore, all accesses to trait types must be through \
589 pointers. If you encounter this error you should try to avoid dereferencing the pointer.
590
591 You can read more about trait objects in the Trait Objects section of the Reference: \
592 https://doc.rust-lang.org/reference/types.html#trait-objects");
593                     }
594                     err.emit();
595                     return false
596                 }
597             }
598         }
599         true
600     }
601
602     pub fn check_match(
603         &self,
604         expr: &'gcx hir::Expr,
605         discrim: &'gcx hir::Expr,
606         arms: &'gcx [hir::Arm],
607         expected: Expectation<'tcx>,
608         match_src: hir::MatchSource,
609     ) -> Ty<'tcx> {
610         let tcx = self.tcx;
611
612         use hir::MatchSource::*;
613         let (source_if, if_no_else, if_desugar) = match match_src {
614             IfDesugar { contains_else_clause } => (true, !contains_else_clause, true),
615             IfLetDesugar { contains_else_clause } => (true, !contains_else_clause, false),
616             _ => (false, false, false),
617         };
618
619         // Type check the descriminant and get its type.
620         let discrim_ty = if if_desugar {
621             // Here we want to ensure:
622             //
623             // 1. That default match bindings are *not* accepted in the condition of an
624             //    `if` expression. E.g. given `fn foo() -> &bool;` we reject `if foo() { .. }`.
625             //
626             // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
627             //
628             // FIXME(60707): Consider removing hack with principled solution.
629             self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
630         } else {
631             self.demand_discriminant_type(arms, discrim)
632         };
633
634         // If there are no arms, that is a diverging match; a special case.
635         if arms.is_empty() {
636             self.diverges.set(self.diverges.get() | Diverges::Always);
637             return tcx.types.never;
638         }
639
640         self.warn_arms_when_scrutinee_diverges(arms, source_if);
641
642         // Otherwise, we have to union together the types that the
643         // arms produce and so forth.
644         let discrim_diverges = self.diverges.get();
645         self.diverges.set(Diverges::Maybe);
646
647         // rust-lang/rust#55810: Typecheck patterns first (via eager
648         // collection into `Vec`), so we get types for all bindings.
649         let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
650             let mut all_pats_diverge = Diverges::WarnedAlways;
651             for p in &arm.pats {
652                 self.diverges.set(Diverges::Maybe);
653                 let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
654                 self.check_pat_walk(&p, discrim_ty, binding_mode, Some(discrim.span));
655                 all_pats_diverge &= self.diverges.get();
656             }
657
658             // As discussed with @eddyb, this is for disabling unreachable_code
659             // warnings on patterns (they're now subsumed by unreachable_patterns
660             // warnings).
661             match all_pats_diverge {
662                 Diverges::Maybe => Diverges::Maybe,
663                 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
664             }
665         }).collect();
666
667         // Now typecheck the blocks.
668         //
669         // The result of the match is the common supertype of all the
670         // arms. Start out the value as bottom, since it's the, well,
671         // bottom the type lattice, and we'll be moving up the lattice as
672         // we process each arm. (Note that any match with 0 arms is matching
673         // on any empty type and is therefore unreachable; should the flow
674         // of execution reach it, we will panic, so bottom is an appropriate
675         // type in that case)
676         let mut all_arms_diverge = Diverges::WarnedAlways;
677
678         let expected = expected.adjust_for_branches(self);
679
680         let mut coercion = {
681             let coerce_first = match expected {
682                 // We don't coerce to `()` so that if the match expression is a
683                 // statement it's branches can have any consistent type. That allows
684                 // us to give better error messages (pointing to a usually better
685                 // arm for inconsistent arms or to the whole match when a `()` type
686                 // is required).
687                 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety,
688                 _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
689             };
690             CoerceMany::with_coercion_sites(coerce_first, arms)
691         };
692
693         let mut other_arms = vec![];  // used only for diagnostics
694         let mut prior_arm_ty = None;
695         for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
696             if let Some(g) = &arm.guard {
697                 self.diverges.set(pats_diverge);
698                 match g {
699                     hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
700                 };
701             }
702
703             self.diverges.set(pats_diverge);
704             let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
705             all_arms_diverge &= self.diverges.get();
706
707             let span = expr.span;
708
709             if source_if {
710                 let then_expr = &arms[0].body;
711                 match (i, if_no_else) {
712                     (0, _) => coercion.coerce(self, &self.misc(span), then_expr, arm_ty),
713                     (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
714                     (_, _) => {
715                         let then_ty = prior_arm_ty.unwrap();
716                         let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
717                         coercion.coerce(self, &cause, &arm.body, arm_ty);
718                     }
719                 }
720             } else {
721                 let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node {
722                     // Point at the block expr instead of the entire block
723                     blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span)
724                 } else {
725                     arm.body.span
726                 };
727                 let (span, code) = match i {
728                     // The reason for the first arm to fail is not that the match arms diverge,
729                     // but rather that there's a prior obligation that doesn't hold.
730                     0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
731                     _ => (span, ObligationCauseCode::MatchExpressionArm {
732                         arm_span,
733                         source: match_src,
734                         prior_arms: other_arms.clone(),
735                         last_ty: prior_arm_ty.unwrap(),
736                         discrim_hir_id: discrim.hir_id,
737                     }),
738                 };
739                 let cause = self.cause(span, code);
740                 coercion.coerce(self, &cause, &arm.body, arm_ty);
741                 other_arms.push(arm_span);
742                 if other_arms.len() > 5 {
743                     other_arms.remove(0);
744                 }
745             }
746             prior_arm_ty = Some(arm_ty);
747         }
748
749         // We won't diverge unless the discriminant or all arms diverge.
750         self.diverges.set(discrim_diverges | all_arms_diverge);
751
752         coercion.complete(self)
753     }
754
755     /// When the previously checked expression (the scrutinee) diverges,
756     /// warn the user about the match arms being unreachable.
757     fn warn_arms_when_scrutinee_diverges(&self, arms: &'gcx [hir::Arm], source_if: bool) {
758         if self.diverges.get().always() {
759             let msg = if source_if { "block in `if` expression" } else { "arm" };
760             for arm in arms {
761                 self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg);
762             }
763         }
764     }
765
766     /// Handle the fallback arm of a desugared if(-let) like a missing else.
767     fn if_fallback_coercion(
768         &self,
769         span: Span,
770         then_expr: &'gcx hir::Expr,
771         coercion: &mut CoerceMany<'gcx, 'tcx, '_, rustc::hir::Arm>,
772     ) {
773         // If this `if` expr is the parent's function return expr,
774         // the cause of the type coercion is the return type, point at it. (#25228)
775         let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
776         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
777         coercion.coerce_forced_unit(self, &cause, &mut |err| {
778             if let Some((span, msg)) = &ret_reason {
779                 err.span_label(*span, msg.as_str());
780             } else if let ExprKind::Block(block, _) = &then_expr.node {
781                 if let Some(expr) = &block.expr {
782                     err.span_label(expr.span, "found here".to_string());
783                 }
784             }
785             err.note("`if` expressions without `else` evaluate to `()`");
786             err.help("consider adding an `else` block that evaluates to the expected type");
787         }, ret_reason.is_none());
788     }
789
790     fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
791         use hir::Node::{Block, Item, Local};
792
793         let hir = self.tcx.hir();
794         let arm_id = hir.get_parent_node_by_hir_id(hir_id);
795         let match_id = hir.get_parent_node_by_hir_id(arm_id);
796         let containing_id = hir.get_parent_node_by_hir_id(match_id);
797
798         let node = hir.get_by_hir_id(containing_id);
799         if let Block(block) = node {
800             // check that the body's parent is an fn
801             let parent = hir.get_by_hir_id(
802                 hir.get_parent_node_by_hir_id(
803                     hir.get_parent_node_by_hir_id(block.hir_id),
804                 ),
805             );
806             if let (Some(expr), Item(hir::Item {
807                 node: hir::ItemKind::Fn(..), ..
808             })) = (&block.expr, parent) {
809                 // check that the `if` expr without `else` is the fn body's expr
810                 if expr.span == span {
811                     return self.get_fn_decl(hir_id).map(|(fn_decl, _)| (
812                         fn_decl.output.span(),
813                         format!("expected `{}` because of this return type", fn_decl.output),
814                     ));
815                 }
816             }
817         }
818         if let Local(hir::Local { ty: Some(_), pat, .. }) = node {
819             return Some((pat.span, "expected because of this assignment".to_string()));
820         }
821         None
822     }
823
824     fn if_cause(
825         &self,
826         span: Span,
827         then_expr: &'gcx hir::Expr,
828         else_expr: &'gcx hir::Expr,
829         then_ty: Ty<'tcx>,
830         else_ty: Ty<'tcx>,
831     ) -> ObligationCause<'tcx> {
832         let mut outer_sp = if self.tcx.sess.source_map().is_multiline(span) {
833             // The `if`/`else` isn't in one line in the output, include some context to make it
834             // clear it is an if/else expression:
835             // ```
836             // LL |      let x = if true {
837             //    | _____________-
838             // LL ||         10i32
839             //    ||         ----- expected because of this
840             // LL ||     } else {
841             // LL ||         10u32
842             //    ||         ^^^^^ expected i32, found u32
843             // LL ||     };
844             //    ||_____- if and else have incompatible types
845             // ```
846             Some(span)
847         } else {
848             // The entire expression is in one line, only point at the arms
849             // ```
850             // LL |     let x = if true { 10i32 } else { 10u32 };
851             //    |                       -----          ^^^^^ expected i32, found u32
852             //    |                       |
853             //    |                       expected because of this
854             // ```
855             None
856         };
857
858         let mut remove_semicolon = None;
859         let error_sp = if let ExprKind::Block(block, _) = &else_expr.node {
860             if let Some(expr) = &block.expr {
861                 expr.span
862             } else if let Some(stmt) = block.stmts.last() {
863                 // possibly incorrect trailing `;` in the else arm
864                 remove_semicolon = self.could_remove_semicolon(block, then_ty);
865                 stmt.span
866             } else {  // empty block, point at its entirety
867                 // Avoid overlapping spans that aren't as readable:
868                 // ```
869                 // 2 |        let x = if true {
870                 //   |   _____________-
871                 // 3 |  |         3
872                 //   |  |         - expected because of this
873                 // 4 |  |     } else {
874                 //   |  |____________^
875                 // 5 | ||
876                 // 6 | ||     };
877                 //   | ||     ^
878                 //   | ||_____|
879                 //   | |______if and else have incompatible types
880                 //   |        expected integer, found ()
881                 // ```
882                 // by not pointing at the entire expression:
883                 // ```
884                 // 2 |       let x = if true {
885                 //   |               ------- if and else have incompatible types
886                 // 3 |           3
887                 //   |           - expected because of this
888                 // 4 |       } else {
889                 //   |  ____________^
890                 // 5 | |
891                 // 6 | |     };
892                 //   | |_____^ expected integer, found ()
893                 // ```
894                 if outer_sp.is_some() {
895                     outer_sp = Some(self.tcx.sess.source_map().def_span(span));
896                 }
897                 else_expr.span
898             }
899         } else { // shouldn't happen unless the parser has done something weird
900             else_expr.span
901         };
902
903         // Compute `Span` of `then` part of `if`-expression:
904         let then_sp = if let ExprKind::Block(block, _) = &then_expr.node {
905             if let Some(expr) = &block.expr {
906                 expr.span
907             } else if let Some(stmt) = block.stmts.last() {
908                 // possibly incorrect trailing `;` in the else arm
909                 remove_semicolon = remove_semicolon.or(self.could_remove_semicolon(block, else_ty));
910                 stmt.span
911             } else {  // empty block, point at its entirety
912                 outer_sp = None;  // same as in `error_sp`, cleanup output
913                 then_expr.span
914             }
915         } else {  // shouldn't happen unless the parser has done something weird
916             then_expr.span
917         };
918
919         // Finally construct the cause:
920         self.cause(error_sp, ObligationCauseCode::IfExpression {
921             then: then_sp,
922             outer: outer_sp,
923             semicolon: remove_semicolon,
924         })
925     }
926
927     fn demand_discriminant_type(
928         &self,
929         arms: &'gcx [hir::Arm],
930         discrim: &'gcx hir::Expr,
931     ) -> Ty<'tcx> {
932         // Not entirely obvious: if matches may create ref bindings, we want to
933         // use the *precise* type of the discriminant, *not* some supertype, as
934         // the "discriminant type" (issue #23116).
935         //
936         // arielb1 [writes here in this comment thread][c] that there
937         // is certainly *some* potential danger, e.g., for an example
938         // like:
939         //
940         // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
941         //
942         // ```
943         // let Foo(x) = f()[0];
944         // ```
945         //
946         // Then if the pattern matches by reference, we want to match
947         // `f()[0]` as a lexpr, so we can't allow it to be
948         // coerced. But if the pattern matches by value, `f()[0]` is
949         // still syntactically a lexpr, but we *do* want to allow
950         // coercions.
951         //
952         // However, *likely* we are ok with allowing coercions to
953         // happen if there are no explicit ref mut patterns - all
954         // implicit ref mut patterns must occur behind a reference, so
955         // they will have the "correct" variance and lifetime.
956         //
957         // This does mean that the following pattern would be legal:
958         //
959         // ```
960         // struct Foo(Bar);
961         // struct Bar(u32);
962         // impl Deref for Foo {
963         //     type Target = Bar;
964         //     fn deref(&self) -> &Bar { &self.0 }
965         // }
966         // impl DerefMut for Foo {
967         //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
968         // }
969         // fn foo(x: &mut Foo) {
970         //     {
971         //         let Bar(z): &mut Bar = x;
972         //         *z = 42;
973         //     }
974         //     assert_eq!(foo.0.0, 42);
975         // }
976         // ```
977         //
978         // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
979         // is problematic as the HIR is being scraped, but ref bindings may be
980         // implicit after #42640. We need to make sure that pat_adjustments
981         // (once introduced) is populated by the time we get here.
982         //
983         // See #44848.
984         let contains_ref_bindings = arms.iter()
985                                         .filter_map(|a| a.contains_explicit_ref_binding())
986                                         .max_by_key(|m| match *m {
987                                             hir::MutMutable => 1,
988                                             hir::MutImmutable => 0,
989                                         });
990
991         if let Some(m) = contains_ref_bindings {
992             self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m))
993         } else {
994             // ...but otherwise we want to use any supertype of the
995             // discriminant. This is sort of a workaround, see note (*) in
996             // `check_pat` for some details.
997             let discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
998             self.check_expr_has_type_or_error(discrim, discrim_ty);
999             discrim_ty
1000         }
1001     }
1002
1003     fn check_pat_struct(
1004         &self,
1005         pat: &'gcx hir::Pat,
1006         qpath: &hir::QPath,
1007         fields: &'gcx [Spanned<hir::FieldPat>],
1008         etc: bool,
1009         expected: Ty<'tcx>,
1010         def_bm: ty::BindingMode,
1011         discrim_span: Option<Span>,
1012     ) -> Ty<'tcx>
1013     {
1014         // Resolve the path and check the definition for errors.
1015         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
1016         {
1017             variant_ty
1018         } else {
1019             for field in fields {
1020                 self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, discrim_span);
1021             }
1022             return self.tcx.types.err;
1023         };
1024
1025         // Type-check the path.
1026         self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
1027
1028         // Type-check subpatterns.
1029         if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
1030         {
1031             pat_ty
1032         } else {
1033             self.tcx.types.err
1034         }
1035     }
1036
1037     fn check_pat_path(
1038         &self,
1039         pat: &hir::Pat,
1040         qpath: &hir::QPath,
1041         expected: Ty<'tcx>,
1042     ) -> Ty<'tcx> {
1043         let tcx = self.tcx;
1044
1045         // Resolve the path and check the definition for errors.
1046         let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1047         match res {
1048             Res::Err => {
1049                 self.set_tainted_by_errors();
1050                 return tcx.types.err;
1051             }
1052             Res::Def(DefKind::Method, _) => {
1053                 report_unexpected_variant_res(tcx, res, pat.span, qpath);
1054                 return tcx.types.err;
1055             }
1056             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
1057             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1058                 report_unexpected_variant_res(tcx, res, pat.span, qpath);
1059                 return tcx.types.err;
1060             }
1061             Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
1062             Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
1063             _ => bug!("unexpected pattern resolution: {:?}", res)
1064         }
1065
1066         // Type-check the path.
1067         let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
1068         self.demand_suptype(pat.span, expected, pat_ty);
1069         pat_ty
1070     }
1071
1072     fn check_pat_tuple_struct(
1073         &self,
1074         pat: &hir::Pat,
1075         qpath: &hir::QPath,
1076         subpats: &'gcx [P<hir::Pat>],
1077         ddpos: Option<usize>,
1078         expected: Ty<'tcx>,
1079         def_bm: ty::BindingMode,
1080         match_arm_pat_span: Option<Span>,
1081     ) -> Ty<'tcx> {
1082         let tcx = self.tcx;
1083         let on_error = || {
1084             for pat in subpats {
1085                 self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
1086             }
1087         };
1088         let report_unexpected_res = |res: Res| {
1089             let msg = format!("expected tuple struct/variant, found {} `{}`",
1090                               res.descr(),
1091                               hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1092             let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
1093             match (res, &pat.node) {
1094                 (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
1095                     err.span_label(pat.span, "`fn` calls are not allowed in patterns");
1096                     err.help("for more information, visit \
1097                               https://doc.rust-lang.org/book/ch18-00-patterns.html");
1098                 }
1099                 _ => {
1100                     err.span_label(pat.span, "not a tuple variant or struct");
1101                 }
1102             }
1103             err.emit();
1104             on_error();
1105         };
1106
1107         // Resolve the path and check the definition for errors.
1108         let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1109         if res == Res::Err {
1110             self.set_tainted_by_errors();
1111             on_error();
1112             return self.tcx.types.err;
1113         }
1114
1115         // Type-check the path.
1116         let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
1117             pat.hir_id);
1118         if !pat_ty.is_fn() {
1119             report_unexpected_res(res);
1120             return self.tcx.types.err;
1121         }
1122
1123         let variant = match res {
1124             Res::Err => {
1125                 self.set_tainted_by_errors();
1126                 on_error();
1127                 return tcx.types.err;
1128             }
1129             Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
1130                 report_unexpected_res(res);
1131                 return tcx.types.err;
1132             }
1133             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1134                 tcx.expect_variant_res(res)
1135             }
1136             _ => bug!("unexpected pattern resolution: {:?}", res)
1137         };
1138
1139         // Replace constructor type with constructed type for tuple struct patterns.
1140         let pat_ty = pat_ty.fn_sig(tcx).output();
1141         let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
1142
1143         self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
1144
1145         // Type-check subpatterns.
1146         if subpats.len() == variant.fields.len() ||
1147                 subpats.len() < variant.fields.len() && ddpos.is_some() {
1148             let substs = match pat_ty.sty {
1149                 ty::Adt(_, substs) => substs,
1150                 _ => bug!("unexpected pattern type {:?}", pat_ty),
1151             };
1152             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
1153                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
1154                 self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
1155
1156                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
1157             }
1158         } else {
1159             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
1160             let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
1161             struct_span_err!(tcx.sess, pat.span, E0023,
1162                              "this pattern has {} field{}, but the corresponding {} has {} field{}",
1163                              subpats.len(), subpats_ending, res.descr(),
1164                              variant.fields.len(),  fields_ending)
1165                 .span_label(pat.span, format!("expected {} field{}, found {}",
1166                                               variant.fields.len(), fields_ending, subpats.len()))
1167                 .emit();
1168             on_error();
1169             return tcx.types.err;
1170         }
1171         pat_ty
1172     }
1173
1174     fn check_struct_pat_fields(
1175         &self,
1176         adt_ty: Ty<'tcx>,
1177         pat_id: hir::HirId,
1178         span: Span,
1179         variant: &'tcx ty::VariantDef,
1180         fields: &'gcx [Spanned<hir::FieldPat>],
1181         etc: bool,
1182         def_bm: ty::BindingMode,
1183     ) -> bool {
1184         let tcx = self.tcx;
1185
1186         let (substs, adt) = match adt_ty.sty {
1187             ty::Adt(adt, substs) => (substs, adt),
1188             _ => span_bug!(span, "struct pattern is not an ADT")
1189         };
1190         let kind_name = adt.variant_descr();
1191
1192         // Index the struct fields' types.
1193         let field_map = variant.fields
1194             .iter()
1195             .enumerate()
1196             .map(|(i, field)| (field.ident.modern(), (i, field)))
1197             .collect::<FxHashMap<_, _>>();
1198
1199         // Keep track of which fields have already appeared in the pattern.
1200         let mut used_fields = FxHashMap::default();
1201         let mut no_field_errors = true;
1202
1203         let mut inexistent_fields = vec![];
1204         // Typecheck each field.
1205         for &Spanned { node: ref field, span } in fields {
1206             let ident = tcx.adjust_ident(field.ident, variant.def_id);
1207             let field_ty = match used_fields.entry(ident) {
1208                 Occupied(occupied) => {
1209                     struct_span_err!(tcx.sess, span, E0025,
1210                                      "field `{}` bound multiple times \
1211                                       in the pattern",
1212                                      field.ident)
1213                         .span_label(span,
1214                                     format!("multiple uses of `{}` in pattern", field.ident))
1215                         .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
1216                         .emit();
1217                     no_field_errors = false;
1218                     tcx.types.err
1219                 }
1220                 Vacant(vacant) => {
1221                     vacant.insert(span);
1222                     field_map.get(&ident)
1223                         .map(|(i, f)| {
1224                             self.write_field_index(field.hir_id, *i);
1225                             self.tcx.check_stability(f.did, Some(pat_id), span);
1226                             self.field_ty(span, f, substs)
1227                         })
1228                         .unwrap_or_else(|| {
1229                             inexistent_fields.push(field.ident);
1230                             no_field_errors = false;
1231                             tcx.types.err
1232                         })
1233                 }
1234             };
1235
1236             self.check_pat_walk(&field.pat, field_ty, def_bm, None);
1237         }
1238         let mut unmentioned_fields = variant.fields
1239                 .iter()
1240                 .map(|field| field.ident.modern())
1241                 .filter(|ident| !used_fields.contains_key(&ident))
1242                 .collect::<Vec<_>>();
1243         if inexistent_fields.len() > 0 && !variant.recovered {
1244             let (field_names, t, plural) = if inexistent_fields.len() == 1 {
1245                 (format!("a field named `{}`", inexistent_fields[0]), "this", "")
1246             } else {
1247                 (format!("fields named {}",
1248                          inexistent_fields.iter()
1249                             .map(|ident| format!("`{}`", ident))
1250                             .collect::<Vec<String>>()
1251                             .join(", ")), "these", "s")
1252             };
1253             let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
1254             let mut err = struct_span_err!(tcx.sess,
1255                                            spans,
1256                                            E0026,
1257                                            "{} `{}` does not have {}",
1258                                            kind_name,
1259                                            tcx.def_path_str(variant.def_id),
1260                                            field_names);
1261             if let Some(ident) = inexistent_fields.last() {
1262                 err.span_label(ident.span,
1263                                format!("{} `{}` does not have {} field{}",
1264                                        kind_name,
1265                                        tcx.def_path_str(variant.def_id),
1266                                        t,
1267                                        plural));
1268                 if plural == "" {
1269                     let input = unmentioned_fields.iter().map(|field| &field.name);
1270                     let suggested_name =
1271                         find_best_match_for_name(input, &ident.as_str(), None);
1272                     if let Some(suggested_name) = suggested_name {
1273                         err.span_suggestion(
1274                             ident.span,
1275                             "a field with a similar name exists",
1276                             suggested_name.to_string(),
1277                             Applicability::MaybeIncorrect,
1278                         );
1279
1280                         // we don't want to throw `E0027` in case we have thrown `E0026` for them
1281                         unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
1282                     }
1283                 }
1284             }
1285             if tcx.sess.teach(&err.get_code().unwrap()) {
1286                 err.note(
1287                     "This error indicates that a struct pattern attempted to \
1288                      extract a non-existent field from a struct. Struct fields \
1289                      are identified by the name used before the colon : so struct \
1290                      patterns should resemble the declaration of the struct type \
1291                      being matched.\n\n\
1292                      If you are using shorthand field patterns but want to refer \
1293                      to the struct field by a different name, you should rename \
1294                      it explicitly."
1295                 );
1296             }
1297             err.emit();
1298         }
1299
1300         // Require `..` if struct has non_exhaustive attribute.
1301         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
1302             span_err!(tcx.sess, span, E0638,
1303                       "`..` required with {} marked as non-exhaustive",
1304                       kind_name);
1305         }
1306
1307         // Report an error if incorrect number of the fields were specified.
1308         if kind_name == "union" {
1309             if fields.len() != 1 {
1310                 tcx.sess.span_err(span, "union patterns should have exactly one field");
1311             }
1312             if etc {
1313                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
1314             }
1315         } else if !etc {
1316             if unmentioned_fields.len() > 0 {
1317                 let field_names = if unmentioned_fields.len() == 1 {
1318                     format!("field `{}`", unmentioned_fields[0])
1319                 } else {
1320                     format!("fields {}",
1321                             unmentioned_fields.iter()
1322                                 .map(|name| format!("`{}`", name))
1323                                 .collect::<Vec<String>>()
1324                                 .join(", "))
1325                 };
1326                 let mut diag = struct_span_err!(tcx.sess, span, E0027,
1327                                                 "pattern does not mention {}",
1328                                                 field_names);
1329                 diag.span_label(span, format!("missing {}", field_names));
1330                 if variant.ctor_kind == CtorKind::Fn {
1331                     diag.note("trying to match a tuple variant with a struct variant pattern");
1332                 }
1333                 if tcx.sess.teach(&diag.get_code().unwrap()) {
1334                     diag.note(
1335                         "This error indicates that a pattern for a struct fails to specify a \
1336                          sub-pattern for every one of the struct's fields. Ensure that each field \
1337                          from the struct's definition is mentioned in the pattern, or use `..` to \
1338                          ignore unwanted fields."
1339                     );
1340                 }
1341                 diag.emit();
1342             }
1343         }
1344         no_field_errors
1345     }
1346 }