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