]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/_match.rs
Rollup merge of #61599 - laumann:pin-docs-minor-edits, r=Centril
[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, TypeVariableOriginKind};
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                     Kind::from(self.next_ty_var(
315                         // FIXME: `MiscVariable` for now -- obtaining the span and name information
316                         // from all tuple elements isn't trivial.
317                         TypeVariableOrigin {
318                             kind: TypeVariableOriginKind::TypeInference,
319                             span: pat.span,
320                         },
321                     ))
322                 });
323                 let element_tys = tcx.mk_substs(element_tys_iter);
324                 let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
325                 if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
326                     err.emit();
327                     // Walk subpatterns with an expected type of `err` in this case to silence
328                     // further errors being emitted when using the bindings. #50333
329                     let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
330                     for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
331                         self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
332                     }
333                     tcx.mk_tup(element_tys_iter)
334                 } else {
335                     for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
336                         self.check_pat_walk(
337                             elem,
338                             &element_tys[i].expect_ty(),
339                             def_bm,
340                             discrim_span,
341                         );
342                     }
343                     pat_ty
344                 }
345             }
346             PatKind::Box(ref inner) => {
347                 let inner_ty = self.next_ty_var(TypeVariableOrigin {
348                     kind: TypeVariableOriginKind::TypeInference,
349                     span: inner.span,
350                 });
351                 let uniq_ty = tcx.mk_box(inner_ty);
352
353                 if self.check_dereferencable(pat.span, expected, &inner) {
354                     // Here, `demand::subtype` is good enough, but I don't
355                     // think any errors can be introduced by using
356                     // `demand::eqtype`.
357                     self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
358                     self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
359                     uniq_ty
360                 } else {
361                     self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
362                     tcx.types.err
363                 }
364             }
365             PatKind::Ref(ref inner, mutbl) => {
366                 let expected = self.shallow_resolve(expected);
367                 if self.check_dereferencable(pat.span, expected, &inner) {
368                     // `demand::subtype` would be good enough, but using
369                     // `eqtype` turns out to be equally general. See (*)
370                     // below for details.
371
372                     // Take region, inner-type from expected type if we
373                     // can, to avoid creating needless variables.  This
374                     // also helps with the bad interactions of the given
375                     // hack detailed in (*) below.
376                     debug!("check_pat_walk: expected={:?}", expected);
377                     let (rptr_ty, inner_ty) = match expected.sty {
378                         ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
379                             (expected, r_ty)
380                         }
381                         _ => {
382                             let inner_ty = self.next_ty_var(
383                                 TypeVariableOrigin {
384                                     kind: TypeVariableOriginKind::TypeInference,
385                                     span: inner.span,
386                                 }
387                             );
388                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
389                             let region = self.next_region_var(infer::PatternRegion(pat.span));
390                             let rptr_ty = tcx.mk_ref(region, mt);
391                             debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
392                             let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
393
394                             // Look for a case like `fn foo(&foo: u32)` and suggest
395                             // `fn foo(foo: &u32)`
396                             if let Some(mut err) = err {
397                                 self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
398                                 err.emit();
399                             }
400                             (rptr_ty, inner_ty)
401                         }
402                     };
403
404                     self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
405                     rptr_ty
406                 } else {
407                     self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
408                     tcx.types.err
409                 }
410             }
411             PatKind::Slice(ref before, ref slice, ref after) => {
412                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
413                 let (inner_ty, slice_ty) = match expected_ty.sty {
414                     ty::Array(inner_ty, size) => {
415                         if let Some(size) = size.assert_usize(tcx) {
416                             let min_len = before.len() as u64 + after.len() as u64;
417                             if slice.is_none() {
418                                 if min_len != size {
419                                     struct_span_err!(
420                                         tcx.sess, pat.span, E0527,
421                                         "pattern requires {} elements but array has {}",
422                                         min_len, size)
423                                         .span_label(pat.span, format!("expected {} elements", size))
424                                         .emit();
425                                 }
426                                 (inner_ty, tcx.types.err)
427                             } else if let Some(rest) = size.checked_sub(min_len) {
428                                 (inner_ty, tcx.mk_array(inner_ty, rest))
429                             } else {
430                                 struct_span_err!(tcx.sess, pat.span, E0528,
431                                         "pattern requires at least {} elements but array has {}",
432                                         min_len, size)
433                                     .span_label(pat.span,
434                                         format!("pattern cannot match array of {} elements", size))
435                                     .emit();
436                                 (inner_ty, tcx.types.err)
437                             }
438                         } else {
439                             struct_span_err!(
440                                 tcx.sess,
441                                 pat.span,
442                                 E0730,
443                                 "cannot pattern-match on an array without a fixed length",
444                             ).emit();
445                             (inner_ty, tcx.types.err)
446                         }
447                     }
448                     ty::Slice(inner_ty) => (inner_ty, expected_ty),
449                     _ => {
450                         if !expected_ty.references_error() {
451                             let mut err = struct_span_err!(
452                                 tcx.sess, pat.span, E0529,
453                                 "expected an array or slice, found `{}`",
454                                 expected_ty);
455                             if let ty::Ref(_, ty, _) = expected_ty.sty {
456                                 match ty.sty {
457                                     ty::Array(..) | ty::Slice(..) => {
458                                         err.help("the semantics of slice patterns changed \
459                                                   recently; see issue #23121");
460                                     }
461                                     _ => {}
462                                 }
463                             }
464
465                             err.span_label( pat.span,
466                                 format!("pattern cannot match with input type `{}`", expected_ty)
467                             ).emit();
468                         }
469                         (tcx.types.err, tcx.types.err)
470                     }
471                 };
472
473                 for elt in before {
474                     self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
475                 }
476                 if let Some(ref slice) = *slice {
477                     self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
478                 }
479                 for elt in after {
480                     self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
481                 }
482                 expected_ty
483             }
484         };
485
486         self.write_ty(pat.hir_id, ty);
487
488         // (*) In most of the cases above (literals and constants being
489         // the exception), we relate types using strict equality, even
490         // though subtyping would be sufficient. There are a few reasons
491         // for this, some of which are fairly subtle and which cost me
492         // (nmatsakis) an hour or two debugging to remember, so I thought
493         // I'd write them down this time.
494         //
495         // 1. There is no loss of expressiveness here, though it does
496         // cause some inconvenience. What we are saying is that the type
497         // of `x` becomes *exactly* what is expected. This can cause unnecessary
498         // errors in some cases, such as this one:
499         //
500         // ```
501         // fn foo<'x>(x: &'x int) {
502         //    let a = 1;
503         //    let mut z = x;
504         //    z = &a;
505         // }
506         // ```
507         //
508         // The reason we might get an error is that `z` might be
509         // assigned a type like `&'x int`, and then we would have
510         // a problem when we try to assign `&a` to `z`, because
511         // the lifetime of `&a` (i.e., the enclosing block) is
512         // shorter than `'x`.
513         //
514         // HOWEVER, this code works fine. The reason is that the
515         // expected type here is whatever type the user wrote, not
516         // the initializer's type. In this case the user wrote
517         // nothing, so we are going to create a type variable `Z`.
518         // Then we will assign the type of the initializer (`&'x
519         // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
520         // will instantiate `Z` as a type `&'0 int` where `'0` is
521         // a fresh region variable, with the constraint that `'x :
522         // '0`.  So basically we're all set.
523         //
524         // Note that there are two tests to check that this remains true
525         // (`regions-reassign-{match,let}-bound-pointer.rs`).
526         //
527         // 2. Things go horribly wrong if we use subtype. The reason for
528         // THIS is a fairly subtle case involving bound regions. See the
529         // `givens` field in `region_constraints`, as well as the test
530         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
531         // for details. Short version is that we must sometimes detect
532         // relationships between specific region variables and regions
533         // bound in a closure signature, and that detection gets thrown
534         // off when we substitute fresh region variables here to enable
535         // subtyping.
536     }
537
538     fn borrow_pat_suggestion(
539         &self,
540         err: &mut DiagnosticBuilder<'_>,
541         pat: &Pat,
542         inner: &Pat,
543         expected: Ty<'tcx>,
544     ) {
545         let tcx = self.tcx;
546         if let PatKind::Binding(..) = inner.node {
547             let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
548             let parent = tcx.hir().get_by_hir_id(parent_id);
549             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
550             match parent {
551                 hir::Node::Item(hir::Item { node: hir::ItemKind::Fn(..), .. }) |
552                 hir::Node::ForeignItem(hir::ForeignItem {
553                     node: hir::ForeignItemKind::Fn(..), ..
554                 }) |
555                 hir::Node::TraitItem(hir::TraitItem { node: hir::TraitItemKind::Method(..), .. }) |
556                 hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => {
557                     // this pat is likely an argument
558                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
559                         // FIXME: turn into structured suggestion, will need a span that also
560                         // includes the the arg's type.
561                         err.help(&format!("did you mean `{}: &{}`?", snippet, expected));
562                     }
563                 }
564                 hir::Node::Arm(_) |
565                 hir::Node::Pat(_) => {
566                     // rely on match ergonomics or it might be nested `&&pat`
567                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
568                         err.span_suggestion(
569                             pat.span,
570                             "you can probably remove the explicit borrow",
571                             snippet,
572                             Applicability::MaybeIncorrect,
573                         );
574                     }
575                 }
576                 _ => {} // don't provide suggestions in other cases #55175
577             }
578         }
579     }
580
581     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
582         if let PatKind::Binding(..) = inner.node {
583             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
584                 if let ty::Dynamic(..) = mt.ty.sty {
585                     // This is "x = SomeTrait" being reduced from
586                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
587                     let type_str = self.ty_to_string(expected);
588                     let mut err = struct_span_err!(
589                         self.tcx.sess,
590                         span,
591                         E0033,
592                         "type `{}` cannot be dereferenced",
593                         type_str
594                     );
595                     err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
596                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
597                         err.note("\
598 This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
599 pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
600 this type has no compile-time size. Therefore, all accesses to trait types must be through \
601 pointers. If you encounter this error you should try to avoid dereferencing the pointer.
602
603 You can read more about trait objects in the Trait Objects section of the Reference: \
604 https://doc.rust-lang.org/reference/types.html#trait-objects");
605                     }
606                     err.emit();
607                     return false
608                 }
609             }
610         }
611         true
612     }
613
614     pub fn check_match(
615         &self,
616         expr: &'gcx hir::Expr,
617         discrim: &'gcx hir::Expr,
618         arms: &'gcx [hir::Arm],
619         expected: Expectation<'tcx>,
620         match_src: hir::MatchSource,
621     ) -> Ty<'tcx> {
622         let tcx = self.tcx;
623
624         use hir::MatchSource::*;
625         let (source_if, if_no_else, if_desugar) = match match_src {
626             IfDesugar { contains_else_clause } => (true, !contains_else_clause, true),
627             IfLetDesugar { contains_else_clause } => (true, !contains_else_clause, false),
628             _ => (false, false, false),
629         };
630
631         // Type check the descriminant and get its type.
632         let discrim_ty = if if_desugar {
633             // Here we want to ensure:
634             //
635             // 1. That default match bindings are *not* accepted in the condition of an
636             //    `if` expression. E.g. given `fn foo() -> &bool;` we reject `if foo() { .. }`.
637             //
638             // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
639             //
640             // FIXME(60707): Consider removing hack with principled solution.
641             self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
642         } else {
643             self.demand_discriminant_type(arms, discrim)
644         };
645
646         // If there are no arms, that is a diverging match; a special case.
647         if arms.is_empty() {
648             self.diverges.set(self.diverges.get() | Diverges::Always);
649             return tcx.types.never;
650         }
651
652         self.warn_arms_when_scrutinee_diverges(arms, source_if);
653
654         // Otherwise, we have to union together the types that the
655         // arms produce and so forth.
656         let discrim_diverges = self.diverges.get();
657         self.diverges.set(Diverges::Maybe);
658
659         // rust-lang/rust#55810: Typecheck patterns first (via eager
660         // collection into `Vec`), so we get types for all bindings.
661         let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
662             let mut all_pats_diverge = Diverges::WarnedAlways;
663             for p in &arm.pats {
664                 self.diverges.set(Diverges::Maybe);
665                 let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
666                 self.check_pat_walk(&p, discrim_ty, binding_mode, Some(discrim.span));
667                 all_pats_diverge &= self.diverges.get();
668             }
669
670             // As discussed with @eddyb, this is for disabling unreachable_code
671             // warnings on patterns (they're now subsumed by unreachable_patterns
672             // warnings).
673             match all_pats_diverge {
674                 Diverges::Maybe => Diverges::Maybe,
675                 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
676             }
677         }).collect();
678
679         // Now typecheck the blocks.
680         //
681         // The result of the match is the common supertype of all the
682         // arms. Start out the value as bottom, since it's the, well,
683         // bottom the type lattice, and we'll be moving up the lattice as
684         // we process each arm. (Note that any match with 0 arms is matching
685         // on any empty type and is therefore unreachable; should the flow
686         // of execution reach it, we will panic, so bottom is an appropriate
687         // type in that case)
688         let mut all_arms_diverge = Diverges::WarnedAlways;
689
690         let expected = expected.adjust_for_branches(self);
691
692         let mut coercion = {
693             let coerce_first = match expected {
694                 // We don't coerce to `()` so that if the match expression is a
695                 // statement it's branches can have any consistent type. That allows
696                 // us to give better error messages (pointing to a usually better
697                 // arm for inconsistent arms or to the whole match when a `()` type
698                 // is required).
699                 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety,
700                 _ => self.next_ty_var(TypeVariableOrigin {
701                     kind: TypeVariableOriginKind::MiscVariable,
702                     span: expr.span,
703                 }),
704             };
705             CoerceMany::with_coercion_sites(coerce_first, arms)
706         };
707
708         let mut other_arms = vec![];  // used only for diagnostics
709         let mut prior_arm_ty = None;
710         for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
711             if let Some(g) = &arm.guard {
712                 self.diverges.set(pats_diverge);
713                 match g {
714                     hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
715                 };
716             }
717
718             self.diverges.set(pats_diverge);
719             let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
720             all_arms_diverge &= self.diverges.get();
721
722             let span = expr.span;
723
724             if source_if {
725                 let then_expr = &arms[0].body;
726                 match (i, if_no_else) {
727                     (0, _) => coercion.coerce(self, &self.misc(span), then_expr, arm_ty),
728                     (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
729                     (_, _) => {
730                         let then_ty = prior_arm_ty.unwrap();
731                         let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
732                         coercion.coerce(self, &cause, &arm.body, arm_ty);
733                     }
734                 }
735             } else {
736                 let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node {
737                     // Point at the block expr instead of the entire block
738                     blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span)
739                 } else {
740                     arm.body.span
741                 };
742                 let (span, code) = match i {
743                     // The reason for the first arm to fail is not that the match arms diverge,
744                     // but rather that there's a prior obligation that doesn't hold.
745                     0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
746                     _ => (span, ObligationCauseCode::MatchExpressionArm {
747                         arm_span,
748                         source: match_src,
749                         prior_arms: other_arms.clone(),
750                         last_ty: prior_arm_ty.unwrap(),
751                         discrim_hir_id: discrim.hir_id,
752                     }),
753                 };
754                 let cause = self.cause(span, code);
755                 coercion.coerce(self, &cause, &arm.body, arm_ty);
756                 other_arms.push(arm_span);
757                 if other_arms.len() > 5 {
758                     other_arms.remove(0);
759                 }
760             }
761             prior_arm_ty = Some(arm_ty);
762         }
763
764         // We won't diverge unless the discriminant or all arms diverge.
765         self.diverges.set(discrim_diverges | all_arms_diverge);
766
767         coercion.complete(self)
768     }
769
770     /// When the previously checked expression (the scrutinee) diverges,
771     /// warn the user about the match arms being unreachable.
772     fn warn_arms_when_scrutinee_diverges(&self, arms: &'gcx [hir::Arm], source_if: bool) {
773         if self.diverges.get().always() {
774             let msg = if source_if { "block in `if` expression" } else { "arm" };
775             for arm in arms {
776                 self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg);
777             }
778         }
779     }
780
781     /// Handle the fallback arm of a desugared if(-let) like a missing else.
782     fn if_fallback_coercion(
783         &self,
784         span: Span,
785         then_expr: &'gcx hir::Expr,
786         coercion: &mut CoerceMany<'gcx, 'tcx, '_, rustc::hir::Arm>,
787     ) {
788         // If this `if` expr is the parent's function return expr,
789         // the cause of the type coercion is the return type, point at it. (#25228)
790         let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
791         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
792         coercion.coerce_forced_unit(self, &cause, &mut |err| {
793             if let Some((span, msg)) = &ret_reason {
794                 err.span_label(*span, msg.as_str());
795             } else if let ExprKind::Block(block, _) = &then_expr.node {
796                 if let Some(expr) = &block.expr {
797                     err.span_label(expr.span, "found here".to_string());
798                 }
799             }
800             err.note("`if` expressions without `else` evaluate to `()`");
801             err.help("consider adding an `else` block that evaluates to the expected type");
802         }, ret_reason.is_none());
803     }
804
805     fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
806         use hir::Node::{Block, Item, Local};
807
808         let hir = self.tcx.hir();
809         let arm_id = hir.get_parent_node_by_hir_id(hir_id);
810         let match_id = hir.get_parent_node_by_hir_id(arm_id);
811         let containing_id = hir.get_parent_node_by_hir_id(match_id);
812
813         let node = hir.get_by_hir_id(containing_id);
814         if let Block(block) = node {
815             // check that the body's parent is an fn
816             let parent = hir.get_by_hir_id(
817                 hir.get_parent_node_by_hir_id(
818                     hir.get_parent_node_by_hir_id(block.hir_id),
819                 ),
820             );
821             if let (Some(expr), Item(hir::Item {
822                 node: hir::ItemKind::Fn(..), ..
823             })) = (&block.expr, parent) {
824                 // check that the `if` expr without `else` is the fn body's expr
825                 if expr.span == span {
826                     return self.get_fn_decl(hir_id).map(|(fn_decl, _)| (
827                         fn_decl.output.span(),
828                         format!("expected `{}` because of this return type", fn_decl.output),
829                     ));
830                 }
831             }
832         }
833         if let Local(hir::Local { ty: Some(_), pat, .. }) = node {
834             return Some((pat.span, "expected because of this assignment".to_string()));
835         }
836         None
837     }
838
839     fn if_cause(
840         &self,
841         span: Span,
842         then_expr: &'gcx hir::Expr,
843         else_expr: &'gcx hir::Expr,
844         then_ty: Ty<'tcx>,
845         else_ty: Ty<'tcx>,
846     ) -> ObligationCause<'tcx> {
847         let mut outer_sp = if self.tcx.sess.source_map().is_multiline(span) {
848             // The `if`/`else` isn't in one line in the output, include some context to make it
849             // clear it is an if/else expression:
850             // ```
851             // LL |      let x = if true {
852             //    | _____________-
853             // LL ||         10i32
854             //    ||         ----- expected because of this
855             // LL ||     } else {
856             // LL ||         10u32
857             //    ||         ^^^^^ expected i32, found u32
858             // LL ||     };
859             //    ||_____- if and else have incompatible types
860             // ```
861             Some(span)
862         } else {
863             // The entire expression is in one line, only point at the arms
864             // ```
865             // LL |     let x = if true { 10i32 } else { 10u32 };
866             //    |                       -----          ^^^^^ expected i32, found u32
867             //    |                       |
868             //    |                       expected because of this
869             // ```
870             None
871         };
872
873         let mut remove_semicolon = None;
874         let error_sp = if let ExprKind::Block(block, _) = &else_expr.node {
875             if let Some(expr) = &block.expr {
876                 expr.span
877             } else if let Some(stmt) = block.stmts.last() {
878                 // possibly incorrect trailing `;` in the else arm
879                 remove_semicolon = self.could_remove_semicolon(block, then_ty);
880                 stmt.span
881             } else {  // empty block, point at its entirety
882                 // Avoid overlapping spans that aren't as readable:
883                 // ```
884                 // 2 |        let x = if true {
885                 //   |   _____________-
886                 // 3 |  |         3
887                 //   |  |         - expected because of this
888                 // 4 |  |     } else {
889                 //   |  |____________^
890                 // 5 | ||
891                 // 6 | ||     };
892                 //   | ||     ^
893                 //   | ||_____|
894                 //   | |______if and else have incompatible types
895                 //   |        expected integer, found ()
896                 // ```
897                 // by not pointing at the entire expression:
898                 // ```
899                 // 2 |       let x = if true {
900                 //   |               ------- if and else have incompatible types
901                 // 3 |           3
902                 //   |           - expected because of this
903                 // 4 |       } else {
904                 //   |  ____________^
905                 // 5 | |
906                 // 6 | |     };
907                 //   | |_____^ expected integer, found ()
908                 // ```
909                 if outer_sp.is_some() {
910                     outer_sp = Some(self.tcx.sess.source_map().def_span(span));
911                 }
912                 else_expr.span
913             }
914         } else { // shouldn't happen unless the parser has done something weird
915             else_expr.span
916         };
917
918         // Compute `Span` of `then` part of `if`-expression:
919         let then_sp = if let ExprKind::Block(block, _) = &then_expr.node {
920             if let Some(expr) = &block.expr {
921                 expr.span
922             } else if let Some(stmt) = block.stmts.last() {
923                 // possibly incorrect trailing `;` in the else arm
924                 remove_semicolon = remove_semicolon.or(self.could_remove_semicolon(block, else_ty));
925                 stmt.span
926             } else {  // empty block, point at its entirety
927                 outer_sp = None;  // same as in `error_sp`, cleanup output
928                 then_expr.span
929             }
930         } else {  // shouldn't happen unless the parser has done something weird
931             then_expr.span
932         };
933
934         // Finally construct the cause:
935         self.cause(error_sp, ObligationCauseCode::IfExpression {
936             then: then_sp,
937             outer: outer_sp,
938             semicolon: remove_semicolon,
939         })
940     }
941
942     fn demand_discriminant_type(
943         &self,
944         arms: &'gcx [hir::Arm],
945         discrim: &'gcx hir::Expr,
946     ) -> Ty<'tcx> {
947         // Not entirely obvious: if matches may create ref bindings, we want to
948         // use the *precise* type of the discriminant, *not* some supertype, as
949         // the "discriminant type" (issue #23116).
950         //
951         // arielb1 [writes here in this comment thread][c] that there
952         // is certainly *some* potential danger, e.g., for an example
953         // like:
954         //
955         // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
956         //
957         // ```
958         // let Foo(x) = f()[0];
959         // ```
960         //
961         // Then if the pattern matches by reference, we want to match
962         // `f()[0]` as a lexpr, so we can't allow it to be
963         // coerced. But if the pattern matches by value, `f()[0]` is
964         // still syntactically a lexpr, but we *do* want to allow
965         // coercions.
966         //
967         // However, *likely* we are ok with allowing coercions to
968         // happen if there are no explicit ref mut patterns - all
969         // implicit ref mut patterns must occur behind a reference, so
970         // they will have the "correct" variance and lifetime.
971         //
972         // This does mean that the following pattern would be legal:
973         //
974         // ```
975         // struct Foo(Bar);
976         // struct Bar(u32);
977         // impl Deref for Foo {
978         //     type Target = Bar;
979         //     fn deref(&self) -> &Bar { &self.0 }
980         // }
981         // impl DerefMut for Foo {
982         //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
983         // }
984         // fn foo(x: &mut Foo) {
985         //     {
986         //         let Bar(z): &mut Bar = x;
987         //         *z = 42;
988         //     }
989         //     assert_eq!(foo.0.0, 42);
990         // }
991         // ```
992         //
993         // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
994         // is problematic as the HIR is being scraped, but ref bindings may be
995         // implicit after #42640. We need to make sure that pat_adjustments
996         // (once introduced) is populated by the time we get here.
997         //
998         // See #44848.
999         let contains_ref_bindings = arms.iter()
1000                                         .filter_map(|a| a.contains_explicit_ref_binding())
1001                                         .max_by_key(|m| match *m {
1002                                             hir::MutMutable => 1,
1003                                             hir::MutImmutable => 0,
1004                                         });
1005
1006         if let Some(m) = contains_ref_bindings {
1007             self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m))
1008         } else {
1009             // ...but otherwise we want to use any supertype of the
1010             // discriminant. This is sort of a workaround, see note (*) in
1011             // `check_pat` for some details.
1012             let discrim_ty = self.next_ty_var(TypeVariableOrigin {
1013                 kind: TypeVariableOriginKind::TypeInference,
1014                 span: discrim.span,
1015             });
1016             self.check_expr_has_type_or_error(discrim, discrim_ty);
1017             discrim_ty
1018         }
1019     }
1020
1021     fn check_pat_struct(
1022         &self,
1023         pat: &'gcx hir::Pat,
1024         qpath: &hir::QPath,
1025         fields: &'gcx [Spanned<hir::FieldPat>],
1026         etc: bool,
1027         expected: Ty<'tcx>,
1028         def_bm: ty::BindingMode,
1029         discrim_span: Option<Span>,
1030     ) -> Ty<'tcx>
1031     {
1032         // Resolve the path and check the definition for errors.
1033         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
1034         {
1035             variant_ty
1036         } else {
1037             for field in fields {
1038                 self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, discrim_span);
1039             }
1040             return self.tcx.types.err;
1041         };
1042
1043         // Type-check the path.
1044         self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
1045
1046         // Type-check subpatterns.
1047         if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
1048         {
1049             pat_ty
1050         } else {
1051             self.tcx.types.err
1052         }
1053     }
1054
1055     fn check_pat_path(
1056         &self,
1057         pat: &hir::Pat,
1058         qpath: &hir::QPath,
1059         expected: Ty<'tcx>,
1060     ) -> Ty<'tcx> {
1061         let tcx = self.tcx;
1062
1063         // Resolve the path and check the definition for errors.
1064         let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1065         match res {
1066             Res::Err => {
1067                 self.set_tainted_by_errors();
1068                 return tcx.types.err;
1069             }
1070             Res::Def(DefKind::Method, _) => {
1071                 report_unexpected_variant_res(tcx, res, pat.span, qpath);
1072                 return tcx.types.err;
1073             }
1074             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
1075             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1076                 report_unexpected_variant_res(tcx, res, pat.span, qpath);
1077                 return tcx.types.err;
1078             }
1079             Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
1080             Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
1081             _ => bug!("unexpected pattern resolution: {:?}", res)
1082         }
1083
1084         // Type-check the path.
1085         let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
1086         self.demand_suptype(pat.span, expected, pat_ty);
1087         pat_ty
1088     }
1089
1090     fn check_pat_tuple_struct(
1091         &self,
1092         pat: &hir::Pat,
1093         qpath: &hir::QPath,
1094         subpats: &'gcx [P<hir::Pat>],
1095         ddpos: Option<usize>,
1096         expected: Ty<'tcx>,
1097         def_bm: ty::BindingMode,
1098         match_arm_pat_span: Option<Span>,
1099     ) -> Ty<'tcx> {
1100         let tcx = self.tcx;
1101         let on_error = || {
1102             for pat in subpats {
1103                 self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
1104             }
1105         };
1106         let report_unexpected_res = |res: Res| {
1107             let msg = format!("expected tuple struct/variant, found {} `{}`",
1108                               res.descr(),
1109                               hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
1110             let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
1111             match (res, &pat.node) {
1112                 (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
1113                     err.span_label(pat.span, "`fn` calls are not allowed in patterns");
1114                     err.help("for more information, visit \
1115                               https://doc.rust-lang.org/book/ch18-00-patterns.html");
1116                 }
1117                 _ => {
1118                     err.span_label(pat.span, "not a tuple variant or struct");
1119                 }
1120             }
1121             err.emit();
1122             on_error();
1123         };
1124
1125         // Resolve the path and check the definition for errors.
1126         let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1127         if res == Res::Err {
1128             self.set_tainted_by_errors();
1129             on_error();
1130             return self.tcx.types.err;
1131         }
1132
1133         // Type-check the path.
1134         let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
1135             pat.hir_id);
1136         if !pat_ty.is_fn() {
1137             report_unexpected_res(res);
1138             return self.tcx.types.err;
1139         }
1140
1141         let variant = match res {
1142             Res::Err => {
1143                 self.set_tainted_by_errors();
1144                 on_error();
1145                 return tcx.types.err;
1146             }
1147             Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
1148                 report_unexpected_res(res);
1149                 return tcx.types.err;
1150             }
1151             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1152                 tcx.expect_variant_res(res)
1153             }
1154             _ => bug!("unexpected pattern resolution: {:?}", res)
1155         };
1156
1157         // Replace constructor type with constructed type for tuple struct patterns.
1158         let pat_ty = pat_ty.fn_sig(tcx).output();
1159         let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
1160
1161         self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
1162
1163         // Type-check subpatterns.
1164         if subpats.len() == variant.fields.len() ||
1165                 subpats.len() < variant.fields.len() && ddpos.is_some() {
1166             let substs = match pat_ty.sty {
1167                 ty::Adt(_, substs) => substs,
1168                 _ => bug!("unexpected pattern type {:?}", pat_ty),
1169             };
1170             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
1171                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
1172                 self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
1173
1174                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
1175             }
1176         } else {
1177             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
1178             let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
1179             struct_span_err!(tcx.sess, pat.span, E0023,
1180                              "this pattern has {} field{}, but the corresponding {} has {} field{}",
1181                              subpats.len(), subpats_ending, res.descr(),
1182                              variant.fields.len(),  fields_ending)
1183                 .span_label(pat.span, format!("expected {} field{}, found {}",
1184                                               variant.fields.len(), fields_ending, subpats.len()))
1185                 .emit();
1186             on_error();
1187             return tcx.types.err;
1188         }
1189         pat_ty
1190     }
1191
1192     fn check_struct_pat_fields(
1193         &self,
1194         adt_ty: Ty<'tcx>,
1195         pat_id: hir::HirId,
1196         span: Span,
1197         variant: &'tcx ty::VariantDef,
1198         fields: &'gcx [Spanned<hir::FieldPat>],
1199         etc: bool,
1200         def_bm: ty::BindingMode,
1201     ) -> bool {
1202         let tcx = self.tcx;
1203
1204         let (substs, adt) = match adt_ty.sty {
1205             ty::Adt(adt, substs) => (substs, adt),
1206             _ => span_bug!(span, "struct pattern is not an ADT")
1207         };
1208         let kind_name = adt.variant_descr();
1209
1210         // Index the struct fields' types.
1211         let field_map = variant.fields
1212             .iter()
1213             .enumerate()
1214             .map(|(i, field)| (field.ident.modern(), (i, field)))
1215             .collect::<FxHashMap<_, _>>();
1216
1217         // Keep track of which fields have already appeared in the pattern.
1218         let mut used_fields = FxHashMap::default();
1219         let mut no_field_errors = true;
1220
1221         let mut inexistent_fields = vec![];
1222         // Typecheck each field.
1223         for &Spanned { node: ref field, span } in fields {
1224             let ident = tcx.adjust_ident(field.ident, variant.def_id);
1225             let field_ty = match used_fields.entry(ident) {
1226                 Occupied(occupied) => {
1227                     struct_span_err!(tcx.sess, span, E0025,
1228                                      "field `{}` bound multiple times \
1229                                       in the pattern",
1230                                      field.ident)
1231                         .span_label(span,
1232                                     format!("multiple uses of `{}` in pattern", field.ident))
1233                         .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
1234                         .emit();
1235                     no_field_errors = false;
1236                     tcx.types.err
1237                 }
1238                 Vacant(vacant) => {
1239                     vacant.insert(span);
1240                     field_map.get(&ident)
1241                         .map(|(i, f)| {
1242                             self.write_field_index(field.hir_id, *i);
1243                             self.tcx.check_stability(f.did, Some(pat_id), span);
1244                             self.field_ty(span, f, substs)
1245                         })
1246                         .unwrap_or_else(|| {
1247                             inexistent_fields.push(field.ident);
1248                             no_field_errors = false;
1249                             tcx.types.err
1250                         })
1251                 }
1252             };
1253
1254             self.check_pat_walk(&field.pat, field_ty, def_bm, None);
1255         }
1256         let mut unmentioned_fields = variant.fields
1257                 .iter()
1258                 .map(|field| field.ident.modern())
1259                 .filter(|ident| !used_fields.contains_key(&ident))
1260                 .collect::<Vec<_>>();
1261         if inexistent_fields.len() > 0 && !variant.recovered {
1262             let (field_names, t, plural) = if inexistent_fields.len() == 1 {
1263                 (format!("a field named `{}`", inexistent_fields[0]), "this", "")
1264             } else {
1265                 (format!("fields named {}",
1266                          inexistent_fields.iter()
1267                             .map(|ident| format!("`{}`", ident))
1268                             .collect::<Vec<String>>()
1269                             .join(", ")), "these", "s")
1270             };
1271             let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
1272             let mut err = struct_span_err!(tcx.sess,
1273                                            spans,
1274                                            E0026,
1275                                            "{} `{}` does not have {}",
1276                                            kind_name,
1277                                            tcx.def_path_str(variant.def_id),
1278                                            field_names);
1279             if let Some(ident) = inexistent_fields.last() {
1280                 err.span_label(ident.span,
1281                                format!("{} `{}` does not have {} field{}",
1282                                        kind_name,
1283                                        tcx.def_path_str(variant.def_id),
1284                                        t,
1285                                        plural));
1286                 if plural == "" {
1287                     let input = unmentioned_fields.iter().map(|field| &field.name);
1288                     let suggested_name =
1289                         find_best_match_for_name(input, &ident.as_str(), None);
1290                     if let Some(suggested_name) = suggested_name {
1291                         err.span_suggestion(
1292                             ident.span,
1293                             "a field with a similar name exists",
1294                             suggested_name.to_string(),
1295                             Applicability::MaybeIncorrect,
1296                         );
1297
1298                         // we don't want to throw `E0027` in case we have thrown `E0026` for them
1299                         unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
1300                     }
1301                 }
1302             }
1303             if tcx.sess.teach(&err.get_code().unwrap()) {
1304                 err.note(
1305                     "This error indicates that a struct pattern attempted to \
1306                      extract a non-existent field from a struct. Struct fields \
1307                      are identified by the name used before the colon : so struct \
1308                      patterns should resemble the declaration of the struct type \
1309                      being matched.\n\n\
1310                      If you are using shorthand field patterns but want to refer \
1311                      to the struct field by a different name, you should rename \
1312                      it explicitly."
1313                 );
1314             }
1315             err.emit();
1316         }
1317
1318         // Require `..` if struct has non_exhaustive attribute.
1319         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
1320             span_err!(tcx.sess, span, E0638,
1321                       "`..` required with {} marked as non-exhaustive",
1322                       kind_name);
1323         }
1324
1325         // Report an error if incorrect number of the fields were specified.
1326         if kind_name == "union" {
1327             if fields.len() != 1 {
1328                 tcx.sess.span_err(span, "union patterns should have exactly one field");
1329             }
1330             if etc {
1331                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
1332             }
1333         } else if !etc {
1334             if unmentioned_fields.len() > 0 {
1335                 let field_names = if unmentioned_fields.len() == 1 {
1336                     format!("field `{}`", unmentioned_fields[0])
1337                 } else {
1338                     format!("fields {}",
1339                             unmentioned_fields.iter()
1340                                 .map(|name| format!("`{}`", name))
1341                                 .collect::<Vec<String>>()
1342                                 .join(", "))
1343                 };
1344                 let mut diag = struct_span_err!(tcx.sess, span, E0027,
1345                                                 "pattern does not mention {}",
1346                                                 field_names);
1347                 diag.span_label(span, format!("missing {}", field_names));
1348                 if variant.ctor_kind == CtorKind::Fn {
1349                     diag.note("trying to match a tuple variant with a struct variant pattern");
1350                 }
1351                 if tcx.sess.teach(&diag.get_code().unwrap()) {
1352                     diag.note(
1353                         "This error indicates that a pattern for a struct fails to specify a \
1354                          sub-pattern for every one of the struct's fields. Ensure that each field \
1355                          from the struct's definition is mentioned in the pattern, or use `..` to \
1356                          ignore unwanted fields."
1357                     );
1358                 }
1359                 diag.emit();
1360             }
1361         }
1362         no_field_errors
1363     }
1364 }