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