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