]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/_match.rs
2a8ee4bd8df0eeeb9feb5e19bbecb337641271c0
[rust.git] / src / librustc_typeck / check / _match.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use rustc::hir::{self, PatKind};
12 use rustc::hir::def::{Def, CtorKind};
13 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
14 use rustc::infer;
15 use rustc::infer::type_variable::TypeVariableOrigin;
16 use rustc::traits::ObligationCauseCode;
17 use rustc::ty::{self, Ty, TypeFoldable};
18 use check::{FnCtxt, Expectation, Diverges, Needs};
19 use check::coercion::CoerceMany;
20 use util::nodemap::FxHashMap;
21
22 use std::collections::hash_map::Entry::{Occupied, Vacant};
23 use std::cmp;
24 use syntax::ast;
25 use syntax::source_map::Spanned;
26 use syntax::ptr::P;
27 use syntax_pos::Span;
28
29 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30     /// The `is_arg` argument indicates whether this pattern is the
31     /// *outermost* pattern in an argument (e.g., in `fn foo(&x:
32     /// &u32)`, it is true for the `&x` pattern but not `x`). This is
33     /// used to tailor error reporting.
34     pub fn check_pat_walk(
35         &self,
36         pat: &'gcx hir::Pat,
37         mut expected: Ty<'tcx>,
38         mut def_bm: ty::BindingMode,
39         is_arg: bool)
40     {
41         let tcx = self.tcx;
42
43         debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?},is_arg={})",
44             pat, expected, def_bm, is_arg);
45
46         let is_non_ref_pat = match pat.node {
47             PatKind::Struct(..) |
48             PatKind::TupleStruct(..) |
49             PatKind::Tuple(..) |
50             PatKind::Box(_) |
51             PatKind::Range(..) |
52             PatKind::Slice(..) => true,
53             PatKind::Lit(ref lt) => {
54                 let ty = self.check_expr(lt);
55                 match ty.sty {
56                     ty::Ref(..) => false,
57                     _ => true,
58                 }
59             }
60             PatKind::Path(ref qpath) => {
61                 let (def, _, _) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span);
62                 match def {
63                     Def::Const(..) | Def::AssociatedConst(..) => false,
64                     _ => true,
65                 }
66             }
67             PatKind::Wild |
68             PatKind::Binding(..) |
69             PatKind::Ref(..) => false,
70         };
71         if is_non_ref_pat {
72             debug!("pattern is non reference pattern");
73             let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
74
75             // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
76             // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
77             // the `Some(5)` which is not of type Ref.
78             //
79             // For each ampersand peeled off, update the binding mode and push the original
80             // type into the adjustments vector.
81             //
82             // See the examples in `run-pass/match-defbm*.rs`.
83             let mut pat_adjustments = vec![];
84             expected = loop {
85                 debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty);
86                 match exp_ty.sty {
87                     ty::Ref(_, inner_ty, inner_mutability) => {
88                         debug!("current discriminant is Ref, inserting implicit deref");
89                         // Preserve the reference type. We'll need it later during HAIR lowering.
90                         pat_adjustments.push(exp_ty);
91
92                         exp_ty = inner_ty;
93                         def_bm = match def_bm {
94                             // If default binding mode is by value, make it `ref` or `ref mut`
95                             // (depending on whether we observe `&` or `&mut`).
96                             ty::BindByValue(_) =>
97                                 ty::BindByReference(inner_mutability),
98
99                             // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
100                             // the underlying value.
101                             ty::BindByReference(hir::Mutability::MutImmutable) =>
102                                 ty::BindByReference(hir::Mutability::MutImmutable),
103
104                             // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
105                             // (on `&`).
106                             ty::BindByReference(hir::Mutability::MutMutable) =>
107                                 ty::BindByReference(inner_mutability),
108                         };
109                     },
110                     _ => break exp_ty,
111                 }
112             };
113             if pat_adjustments.len() > 0 {
114                 debug!("default binding mode is now {:?}", def_bm);
115                 self.inh.tables.borrow_mut()
116                     .pat_adjustments_mut()
117                     .insert(pat.hir_id, pat_adjustments);
118             }
119         } else if let PatKind::Ref(..) = pat.node {
120             // When you encounter a `&pat` pattern, reset to "by
121             // value". This is so that `x` and `y` here are by value,
122             // as they appear to be:
123             //
124             // ```
125             // match &(&22, &44) {
126             //   (&x, &y) => ...
127             // }
128             // ```
129             //
130             // cc #46688
131             def_bm = ty::BindByValue(hir::MutImmutable);
132         }
133
134         // Lose mutability now that we know binding mode and discriminant type.
135         let def_bm = def_bm;
136         let expected = expected;
137
138         let ty = match pat.node {
139             PatKind::Wild => {
140                 expected
141             }
142             PatKind::Lit(ref lt) => {
143                 // We've already computed the type above (when checking for a non-ref pat), so
144                 // avoid computing it again.
145                 let ty = self.node_ty(lt.hir_id);
146
147                 // Byte string patterns behave the same way as array patterns
148                 // They can denote both statically and dynamically sized byte arrays
149                 let mut pat_ty = ty;
150                 if let hir::ExprKind::Lit(ref lt) = lt.node {
151                     if let ast::LitKind::ByteStr(_) = lt.node {
152                         let expected_ty = self.structurally_resolved_type(pat.span, expected);
153                         if let ty::Ref(_, r_ty, _) = expected_ty.sty {
154                             if let ty::Slice(_) = r_ty.sty {
155                                 pat_ty = tcx.mk_imm_ref(tcx.types.re_static,
156                                                          tcx.mk_slice(tcx.types.u8))
157                             }
158                         }
159                     }
160                 }
161
162                 // somewhat surprising: in this case, the subtyping
163                 // relation goes the opposite way as the other
164                 // cases. Actually what we really want is not a subtyping
165                 // relation at all but rather that there exists a LUB (so
166                 // that they can be compared). However, in practice,
167                 // constants are always scalars or strings.  For scalars
168                 // subtyping is irrelevant, and for strings `ty` is
169                 // type is `&'static str`, so if we say that
170                 //
171                 //     &'static str <: expected
172                 //
173                 // that's equivalent to there existing a LUB.
174                 self.demand_suptype(pat.span, expected, pat_ty);
175                 pat_ty
176             }
177             PatKind::Range(ref begin, ref end, _) => {
178                 let lhs_ty = self.check_expr(begin);
179                 let rhs_ty = self.check_expr(end);
180
181                 // Check that both end-points are of numeric or char type.
182                 let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char();
183                 let lhs_compat = numeric_or_char(lhs_ty);
184                 let rhs_compat = numeric_or_char(rhs_ty);
185
186                 if !lhs_compat || !rhs_compat {
187                     let span = if !lhs_compat && !rhs_compat {
188                         pat.span
189                     } else if !lhs_compat {
190                         begin.span
191                     } else {
192                         end.span
193                     };
194
195                     let mut err = struct_span_err!(
196                         tcx.sess,
197                         span,
198                         E0029,
199                         "only char and numeric types are allowed in range patterns"
200                     );
201                     err.span_label(span, "ranges require char or numeric types");
202                     err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
203                     err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
204                     if tcx.sess.teach(&err.get_code().unwrap()) {
205                         err.note(
206                             "In a match expression, only numbers and characters can be matched \
207                              against a range. This is because the compiler checks that the range \
208                              is non-empty at compile-time, and is unable to evaluate arbitrary \
209                              comparison functions. If you want to capture values of an orderable \
210                              type between two end-points, you can use a guard."
211                          );
212                     }
213                     err.emit();
214                     return;
215                 }
216
217                 // Now that we know the types can be unified we find the unified type and use
218                 // it to type the entire expression.
219                 let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
220
221                 // subtyping doesn't matter here, as the value is some kind of scalar
222                 self.demand_eqtype(pat.span, expected, lhs_ty);
223                 self.demand_eqtype(pat.span, expected, rhs_ty);
224                 common_type
225             }
226             PatKind::Binding(ba, var_id, _, ref sub) => {
227                 let bm = if ba == hir::BindingAnnotation::Unannotated {
228                     def_bm
229                 } else {
230                     ty::BindingMode::convert(ba)
231                 };
232                 self.inh
233                     .tables
234                     .borrow_mut()
235                     .pat_binding_modes_mut()
236                     .insert(pat.hir_id, bm);
237                 debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
238                 let typ = self.local_ty(pat.span, pat.id);
239                 match bm {
240                     ty::BindByReference(mutbl) => {
241                         // if the binding is like
242                         //    ref x | ref const x | ref mut x
243                         // then `x` is assigned a value of type `&M T` where M is the mutability
244                         // and T is the expected type.
245                         let region_var = self.next_region_var(infer::PatternRegion(pat.span));
246                         let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
247                         let region_ty = tcx.mk_ref(region_var, mt);
248
249                         // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
250                         // required. However, we use equality, which is stronger. See (*) for
251                         // an explanation.
252                         self.demand_eqtype(pat.span, region_ty, typ);
253                     }
254                     // otherwise the type of x is the expected type T
255                     ty::BindByValue(_) => {
256                         // As above, `T <: typeof(x)` is required but we
257                         // use equality, see (*) below.
258                         self.demand_eqtype(pat.span, expected, typ);
259                     }
260                 }
261
262                 // if there are multiple arms, make sure they all agree on
263                 // what the type of the binding `x` ought to be
264                 if var_id != pat.id {
265                     let vt = self.local_ty(pat.span, var_id);
266                     self.demand_eqtype(pat.span, vt, typ);
267                 }
268
269                 if let Some(ref p) = *sub {
270                     self.check_pat_walk(&p, expected, def_bm, true);
271                 }
272
273                 typ
274             }
275             PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
276                 self.check_pat_tuple_struct(pat, qpath, &subpats, ddpos, expected, def_bm)
277             }
278             PatKind::Path(ref qpath) => {
279                 self.check_pat_path(pat, qpath, expected)
280             }
281             PatKind::Struct(ref qpath, ref fields, etc) => {
282                 self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm)
283             }
284             PatKind::Tuple(ref elements, ddpos) => {
285                 let mut expected_len = elements.len();
286                 if ddpos.is_some() {
287                     // Require known type only when `..` is present
288                     if let ty::Tuple(ref tys) =
289                             self.structurally_resolved_type(pat.span, expected).sty {
290                         expected_len = tys.len();
291                     }
292                 }
293                 let max_len = cmp::max(expected_len, elements.len());
294
295                 let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(
296                     // FIXME: MiscVariable for now, obtaining the span and name information
297                     //       from all tuple elements isn't trivial.
298                     TypeVariableOrigin::TypeInference(pat.span)));
299                 let element_tys = tcx.mk_type_list(element_tys_iter);
300                 let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
301                 self.demand_eqtype(pat.span, expected, pat_ty);
302                 for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
303                     self.check_pat_walk(elem, &element_tys[i], def_bm, true);
304                 }
305                 pat_ty
306             }
307             PatKind::Box(ref inner) => {
308                 let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));
309                 let uniq_ty = tcx.mk_box(inner_ty);
310
311                 if self.check_dereferencable(pat.span, expected, &inner) {
312                     // Here, `demand::subtype` is good enough, but I don't
313                     // think any errors can be introduced by using
314                     // `demand::eqtype`.
315                     self.demand_eqtype(pat.span, expected, uniq_ty);
316                     self.check_pat_walk(&inner, inner_ty, def_bm, true);
317                     uniq_ty
318                 } else {
319                     self.check_pat_walk(&inner, tcx.types.err, def_bm, true);
320                     tcx.types.err
321                 }
322             }
323             PatKind::Ref(ref inner, mutbl) => {
324                 let expected = self.shallow_resolve(expected);
325                 if self.check_dereferencable(pat.span, expected, &inner) {
326                     // `demand::subtype` would be good enough, but using
327                     // `eqtype` turns out to be equally general. See (*)
328                     // below for details.
329
330                     // Take region, inner-type from expected type if we
331                     // can, to avoid creating needless variables.  This
332                     // also helps with the bad interactions of the given
333                     // hack detailed in (*) below.
334                     debug!("check_pat_walk: expected={:?}", expected);
335                     let (rptr_ty, inner_ty) = match expected.sty {
336                         ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
337                             (expected, r_ty)
338                         }
339                         _ => {
340                             let inner_ty = self.next_ty_var(
341                                 TypeVariableOrigin::TypeInference(inner.span));
342                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
343                             let region = self.next_region_var(infer::PatternRegion(pat.span));
344                             let rptr_ty = tcx.mk_ref(region, mt);
345                             debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
346                             let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
347
348                             // Look for a case like `fn foo(&foo: u32)` and suggest
349                             // `fn foo(foo: &u32)`
350                             if let Some(mut err) = err {
351                                 if is_arg {
352                                     if let PatKind::Binding(..) = inner.node {
353                                         if let Ok(snippet) = tcx.sess.source_map()
354                                                                      .span_to_snippet(pat.span)
355                                         {
356                                             err.help(&format!("did you mean `{}: &{}`?",
357                                                               &snippet[1..],
358                                                               expected));
359                                         }
360                                     }
361                                 }
362                                 err.emit();
363                             }
364                             (rptr_ty, inner_ty)
365                         }
366                     };
367
368                     self.check_pat_walk(&inner, inner_ty, def_bm, true);
369                     rptr_ty
370                 } else {
371                     self.check_pat_walk(&inner, tcx.types.err, def_bm, true);
372                     tcx.types.err
373                 }
374             }
375             PatKind::Slice(ref before, ref slice, ref after) => {
376                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
377                 let (inner_ty, slice_ty) = match expected_ty.sty {
378                     ty::Array(inner_ty, size) => {
379                         let size = size.unwrap_usize(tcx);
380                         let min_len = before.len() as u64 + after.len() as u64;
381                         if slice.is_none() {
382                             if min_len != size {
383                                 struct_span_err!(
384                                     tcx.sess, pat.span, E0527,
385                                     "pattern requires {} elements but array has {}",
386                                     min_len, size)
387                                     .span_label(pat.span, format!("expected {} elements",size))
388                                     .emit();
389                             }
390                             (inner_ty, tcx.types.err)
391                         } else if let Some(rest) = size.checked_sub(min_len) {
392                             (inner_ty, tcx.mk_array(inner_ty, rest))
393                         } else {
394                             struct_span_err!(tcx.sess, pat.span, E0528,
395                                     "pattern requires at least {} elements but array has {}",
396                                     min_len, size)
397                                 .span_label(pat.span,
398                                     format!("pattern cannot match array of {} elements", size))
399                                 .emit();
400                             (inner_ty, tcx.types.err)
401                         }
402                     }
403                     ty::Slice(inner_ty) => (inner_ty, expected_ty),
404                     _ => {
405                         if !expected_ty.references_error() {
406                             let mut err = struct_span_err!(
407                                 tcx.sess, pat.span, E0529,
408                                 "expected an array or slice, found `{}`",
409                                 expected_ty);
410                             if let ty::Ref(_, ty, _) = expected_ty.sty {
411                                 match ty.sty {
412                                     ty::Array(..) | ty::Slice(..) => {
413                                         err.help("the semantics of slice patterns changed \
414                                                   recently; see issue #23121");
415                                     }
416                                     _ => {}
417                                 }
418                             }
419
420                             err.span_label( pat.span,
421                                 format!("pattern cannot match with input type `{}`", expected_ty)
422                             ).emit();
423                         }
424                         (tcx.types.err, tcx.types.err)
425                     }
426                 };
427
428                 for elt in before {
429                     self.check_pat_walk(&elt, inner_ty, def_bm, true);
430                 }
431                 if let Some(ref slice) = *slice {
432                     self.check_pat_walk(&slice, slice_ty, def_bm, true);
433                 }
434                 for elt in after {
435                     self.check_pat_walk(&elt, inner_ty, def_bm, true);
436                 }
437                 expected_ty
438             }
439         };
440
441         self.write_ty(pat.hir_id, ty);
442
443         // (*) In most of the cases above (literals and constants being
444         // the exception), we relate types using strict equality, even
445         // though subtyping would be sufficient. There are a few reasons
446         // for this, some of which are fairly subtle and which cost me
447         // (nmatsakis) an hour or two debugging to remember, so I thought
448         // I'd write them down this time.
449         //
450         // 1. There is no loss of expressiveness here, though it does
451         // cause some inconvenience. What we are saying is that the type
452         // of `x` becomes *exactly* what is expected. This can cause unnecessary
453         // errors in some cases, such as this one:
454         //
455         // ```
456         // fn foo<'x>(x: &'x int) {
457         //    let a = 1;
458         //    let mut z = x;
459         //    z = &a;
460         // }
461         // ```
462         //
463         // The reason we might get an error is that `z` might be
464         // assigned a type like `&'x int`, and then we would have
465         // a problem when we try to assign `&a` to `z`, because
466         // the lifetime of `&a` (i.e., the enclosing block) is
467         // shorter than `'x`.
468         //
469         // HOWEVER, this code works fine. The reason is that the
470         // expected type here is whatever type the user wrote, not
471         // the initializer's type. In this case the user wrote
472         // nothing, so we are going to create a type variable `Z`.
473         // Then we will assign the type of the initializer (`&'x
474         // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
475         // will instantiate `Z` as a type `&'0 int` where `'0` is
476         // a fresh region variable, with the constraint that `'x :
477         // '0`.  So basically we're all set.
478         //
479         // Note that there are two tests to check that this remains true
480         // (`regions-reassign-{match,let}-bound-pointer.rs`).
481         //
482         // 2. Things go horribly wrong if we use subtype. The reason for
483         // THIS is a fairly subtle case involving bound regions. See the
484         // `givens` field in `region_constraints`, as well as the test
485         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
486         // for details. Short version is that we must sometimes detect
487         // relationships between specific region variables and regions
488         // bound in a closure signature, and that detection gets thrown
489         // off when we substitute fresh region variables here to enable
490         // subtyping.
491     }
492
493     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
494         if let PatKind::Binding(..) = inner.node {
495             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
496                 if let ty::Dynamic(..) = mt.ty.sty {
497                     // This is "x = SomeTrait" being reduced from
498                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
499                     let type_str = self.ty_to_string(expected);
500                     let mut err = struct_span_err!(
501                         self.tcx.sess,
502                         span,
503                         E0033,
504                         "type `{}` cannot be dereferenced",
505                         type_str
506                     );
507                     err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
508                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
509                         err.note("\
510 This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
511 pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
512 this type has no compile-time size. Therefore, all accesses to trait types must be through \
513 pointers. If you encounter this error you should try to avoid dereferencing the pointer.
514
515 You can read more about trait objects in the Trait Objects section of the Reference: \
516 https://doc.rust-lang.org/reference/types.html#trait-objects");
517                     }
518                     err.emit();
519                     return false
520                 }
521             }
522         }
523         true
524     }
525
526     pub fn check_match(&self,
527                        expr: &'gcx hir::Expr,
528                        discrim: &'gcx hir::Expr,
529                        arms: &'gcx [hir::Arm],
530                        expected: Expectation<'tcx>,
531                        match_src: hir::MatchSource) -> Ty<'tcx> {
532         let tcx = self.tcx;
533
534         // Not entirely obvious: if matches may create ref bindings, we want to
535         // use the *precise* type of the discriminant, *not* some supertype, as
536         // the "discriminant type" (issue #23116).
537         //
538         // arielb1 [writes here in this comment thread][c] that there
539         // is certainly *some* potential danger, e.g. for an example
540         // like:
541         //
542         // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
543         //
544         // ```
545         // let Foo(x) = f()[0];
546         // ```
547         //
548         // Then if the pattern matches by reference, we want to match
549         // `f()[0]` as a lexpr, so we can't allow it to be
550         // coerced. But if the pattern matches by value, `f()[0]` is
551         // still syntactically a lexpr, but we *do* want to allow
552         // coercions.
553         //
554         // However, *likely* we are ok with allowing coercions to
555         // happen if there are no explicit ref mut patterns - all
556         // implicit ref mut patterns must occur behind a reference, so
557         // they will have the "correct" variance and lifetime.
558         //
559         // This does mean that the following pattern would be legal:
560         //
561         // ```
562         // struct Foo(Bar);
563         // struct Bar(u32);
564         // impl Deref for Foo {
565         //     type Target = Bar;
566         //     fn deref(&self) -> &Bar { &self.0 }
567         // }
568         // impl DerefMut for Foo {
569         //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
570         // }
571         // fn foo(x: &mut Foo) {
572         //     {
573         //         let Bar(z): &mut Bar = x;
574         //         *z = 42;
575         //     }
576         //     assert_eq!(foo.0.0, 42);
577         // }
578         // ```
579         //
580         // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
581         // is problematic as the HIR is being scraped, but ref bindings may be
582         // implicit after #42640. We need to make sure that pat_adjustments
583         // (once introduced) is populated by the time we get here.
584         //
585         // See #44848.
586         let contains_ref_bindings = arms.iter()
587                                         .filter_map(|a| a.contains_explicit_ref_binding())
588                                         .max_by_key(|m| match *m {
589                                             hir::MutMutable => 1,
590                                             hir::MutImmutable => 0,
591                                         });
592         let discrim_ty;
593         if let Some(m) = contains_ref_bindings {
594             discrim_ty = self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m));
595         } else {
596             // ...but otherwise we want to use any supertype of the
597             // discriminant. This is sort of a workaround, see note (*) in
598             // `check_pat` for some details.
599             discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
600             self.check_expr_has_type_or_error(discrim, discrim_ty);
601         };
602
603         // If the discriminant diverges, the match is pointless (e.g.,
604         // `match (return) { }`).
605         self.warn_if_unreachable(expr.id, expr.span, "expression");
606
607         // If there are no arms, that is a diverging match; a special case.
608         if arms.is_empty() {
609             self.diverges.set(self.diverges.get() | Diverges::Always);
610             return tcx.types.never;
611         }
612
613         // Otherwise, we have to union together the types that the
614         // arms produce and so forth.
615
616         let discrim_diverges = self.diverges.get();
617         self.diverges.set(Diverges::Maybe);
618
619         // Typecheck the patterns first, so that we get types for all the
620         // bindings.
621         let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
622             let mut all_pats_diverge = Diverges::WarnedAlways;
623             for p in &arm.pats {
624                 self.diverges.set(Diverges::Maybe);
625                 self.check_pat_walk(&p, discrim_ty,
626                     ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true);
627                 all_pats_diverge &= self.diverges.get();
628             }
629
630             // As discussed with @eddyb, this is for disabling unreachable_code
631             // warnings on patterns (they're now subsumed by unreachable_patterns
632             // warnings).
633             match all_pats_diverge {
634                 Diverges::Maybe => Diverges::Maybe,
635                 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
636             }
637         }).collect();
638
639         // Now typecheck the blocks.
640         //
641         // The result of the match is the common supertype of all the
642         // arms. Start out the value as bottom, since it's the, well,
643         // bottom the type lattice, and we'll be moving up the lattice as
644         // we process each arm. (Note that any match with 0 arms is matching
645         // on any empty type and is therefore unreachable; should the flow
646         // of execution reach it, we will panic, so bottom is an appropriate
647         // type in that case)
648         let mut all_arms_diverge = Diverges::WarnedAlways;
649
650         let expected = expected.adjust_for_branches(self);
651
652         let mut coercion = {
653             let coerce_first = match expected {
654                 // We don't coerce to `()` so that if the match expression is a
655                 // statement it's branches can have any consistent type. That allows
656                 // us to give better error messages (pointing to a usually better
657                 // arm for inconsistent arms or to the whole match when a `()` type
658                 // is required).
659                 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_nil() => ety,
660                 _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
661             };
662             CoerceMany::with_coercion_sites(coerce_first, arms)
663         };
664
665         for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
666             if let Some(ref g) = arm.guard {
667                 self.diverges.set(pats_diverge);
668                 match g {
669                     hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
670                 };
671             }
672
673             self.diverges.set(pats_diverge);
674             let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
675             all_arms_diverge &= self.diverges.get();
676
677             // Handle the fallback arm of a desugared if-let like a missing else.
678             let is_if_let_fallback = match match_src {
679                 hir::MatchSource::IfLetDesugar { contains_else_clause: false } => {
680                     i == arms.len() - 1 && arm_ty.is_nil()
681                 }
682                 _ => false
683             };
684
685             if is_if_let_fallback {
686                 let cause = self.cause(expr.span, ObligationCauseCode::IfExpressionWithNoElse);
687                 assert!(arm_ty.is_nil());
688                 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
689             } else {
690                 let cause = self.cause(expr.span, ObligationCauseCode::MatchExpressionArm {
691                     arm_span: arm.body.span,
692                     source: match_src
693                 });
694                 coercion.coerce(self, &cause, &arm.body, arm_ty);
695             }
696         }
697
698         // We won't diverge unless the discriminant or all arms diverge.
699         self.diverges.set(discrim_diverges | all_arms_diverge);
700
701         coercion.complete(self)
702     }
703
704     fn check_pat_struct(&self,
705                         pat: &'gcx hir::Pat,
706                         qpath: &hir::QPath,
707                         fields: &'gcx [Spanned<hir::FieldPat>],
708                         etc: bool,
709                         expected: Ty<'tcx>,
710                         def_bm: ty::BindingMode) -> Ty<'tcx>
711     {
712         // Resolve the path and check the definition for errors.
713         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.id) {
714             variant_ty
715         } else {
716             for field in fields {
717                 self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, true);
718             }
719             return self.tcx.types.err;
720         };
721
722         // Type check the path.
723         self.demand_eqtype(pat.span, expected, pat_ty);
724
725         // Type check subpatterns.
726         if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) {
727             pat_ty
728         } else {
729             self.tcx.types.err
730         }
731     }
732
733     fn check_pat_path(&self,
734                       pat: &hir::Pat,
735                       qpath: &hir::QPath,
736                       expected: Ty<'tcx>) -> Ty<'tcx>
737     {
738         let tcx = self.tcx;
739         let report_unexpected_def = |def: Def| {
740             span_err!(tcx.sess, pat.span, E0533,
741                       "expected unit struct/variant or constant, found {} `{}`",
742                       def.kind_name(),
743                       hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
744         };
745
746         // Resolve the path and check the definition for errors.
747         let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span);
748         match def {
749             Def::Err => {
750                 self.set_tainted_by_errors();
751                 return tcx.types.err;
752             }
753             Def::Method(..) => {
754                 report_unexpected_def(def);
755                 return tcx.types.err;
756             }
757             Def::VariantCtor(_, CtorKind::Const) |
758             Def::StructCtor(_, CtorKind::Const) |
759             Def::Const(..) | Def::AssociatedConst(..) => {} // OK
760             _ => bug!("unexpected pattern definition: {:?}", def)
761         }
762
763         // Type check the path.
764         let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
765         self.demand_suptype(pat.span, expected, pat_ty);
766         pat_ty
767     }
768
769     fn check_pat_tuple_struct(&self,
770                               pat: &hir::Pat,
771                               qpath: &hir::QPath,
772                               subpats: &'gcx [P<hir::Pat>],
773                               ddpos: Option<usize>,
774                               expected: Ty<'tcx>,
775                               def_bm: ty::BindingMode) -> Ty<'tcx>
776     {
777         let tcx = self.tcx;
778         let on_error = || {
779             for pat in subpats {
780                 self.check_pat_walk(&pat, tcx.types.err, def_bm, true);
781             }
782         };
783         let report_unexpected_def = |def: Def| {
784             let msg = format!("expected tuple struct/variant, found {} `{}`",
785                               def.kind_name(),
786                               hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
787             struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
788                 .span_label(pat.span, "not a tuple variant or struct").emit();
789             on_error();
790         };
791
792         // Resolve the path and check the definition for errors.
793         let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span);
794         let variant = match def {
795             Def::Err => {
796                 self.set_tainted_by_errors();
797                 on_error();
798                 return tcx.types.err;
799             }
800             Def::AssociatedConst(..) | Def::Method(..) => {
801                 report_unexpected_def(def);
802                 return tcx.types.err;
803             }
804             Def::VariantCtor(_, CtorKind::Fn) |
805             Def::StructCtor(_, CtorKind::Fn) => {
806                 tcx.expect_variant_def(def)
807             }
808             _ => bug!("unexpected pattern definition: {:?}", def)
809         };
810
811         // Type check the path.
812         let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
813         // Replace constructor type with constructed type for tuple struct patterns.
814         let pat_ty = pat_ty.fn_sig(tcx).output();
815         let pat_ty = pat_ty.no_late_bound_regions().expect("expected fn type");
816
817         self.demand_eqtype(pat.span, expected, pat_ty);
818
819         // Type check subpatterns.
820         if subpats.len() == variant.fields.len() ||
821                 subpats.len() < variant.fields.len() && ddpos.is_some() {
822             let substs = match pat_ty.sty {
823                 ty::Adt(_, substs) => substs,
824                 ref ty => bug!("unexpected pattern type {:?}", ty),
825             };
826             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
827                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
828                 self.check_pat_walk(&subpat, field_ty, def_bm, true);
829
830                 self.tcx.check_stability(variant.fields[i].did, Some(pat.id), subpat.span);
831             }
832         } else {
833             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
834             let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
835             struct_span_err!(tcx.sess, pat.span, E0023,
836                              "this pattern has {} field{}, but the corresponding {} has {} field{}",
837                              subpats.len(), subpats_ending, def.kind_name(),
838                              variant.fields.len(),  fields_ending)
839                 .span_label(pat.span, format!("expected {} field{}, found {}",
840                                                variant.fields.len(), fields_ending, subpats.len()))
841                 .emit();
842             on_error();
843             return tcx.types.err;
844         }
845         pat_ty
846     }
847
848     fn check_struct_pat_fields(&self,
849                                adt_ty: Ty<'tcx>,
850                                pat_id: ast::NodeId,
851                                span: Span,
852                                variant: &'tcx ty::VariantDef,
853                                fields: &'gcx [Spanned<hir::FieldPat>],
854                                etc: bool,
855                                def_bm: ty::BindingMode) -> bool {
856         let tcx = self.tcx;
857
858         let (substs, adt) = match adt_ty.sty {
859             ty::Adt(adt, substs) => (substs, adt),
860             _ => span_bug!(span, "struct pattern is not an ADT")
861         };
862         let kind_name = adt.variant_descr();
863
864         // Index the struct fields' types.
865         let field_map = variant.fields
866             .iter()
867             .enumerate()
868             .map(|(i, field)| (field.ident.modern(), (i, field)))
869             .collect::<FxHashMap<_, _>>();
870
871         // Keep track of which fields have already appeared in the pattern.
872         let mut used_fields = FxHashMap();
873         let mut no_field_errors = true;
874
875         let mut inexistent_fields = vec![];
876         // Typecheck each field.
877         for &Spanned { node: ref field, span } in fields {
878             let ident = tcx.adjust_ident(field.ident, variant.did, self.body_id).0;
879             let field_ty = match used_fields.entry(ident) {
880                 Occupied(occupied) => {
881                     struct_span_err!(tcx.sess, span, E0025,
882                                      "field `{}` bound multiple times \
883                                       in the pattern",
884                                      field.ident)
885                         .span_label(span,
886                                     format!("multiple uses of `{}` in pattern", field.ident))
887                         .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
888                         .emit();
889                     no_field_errors = false;
890                     tcx.types.err
891                 }
892                 Vacant(vacant) => {
893                     vacant.insert(span);
894                     field_map.get(&ident)
895                         .map(|(i, f)| {
896                             self.write_field_index(field.id, *i);
897                             self.tcx.check_stability(f.did, Some(pat_id), span);
898                             self.field_ty(span, f, substs)
899                         })
900                         .unwrap_or_else(|| {
901                             inexistent_fields.push((span, field.ident));
902                             no_field_errors = false;
903                             tcx.types.err
904                         })
905                 }
906             };
907
908             self.check_pat_walk(&field.pat, field_ty, def_bm, true);
909         }
910
911         if inexistent_fields.len() > 0 {
912             let (field_names, t, plural) = if inexistent_fields.len() == 1 {
913                 (format!("a field named `{}`", inexistent_fields[0].1), "this", "")
914             } else {
915                 (format!("fields named {}",
916                          inexistent_fields.iter()
917                             .map(|(_, name)| format!("`{}`", name))
918                             .collect::<Vec<String>>()
919                             .join(", ")), "these", "s")
920             };
921             let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::<Vec<_>>();
922             let mut err = struct_span_err!(tcx.sess,
923                                            spans,
924                                            E0026,
925                                            "{} `{}` does not have {}",
926                                            kind_name,
927                                            tcx.item_path_str(variant.did),
928                                            field_names);
929             if let Some((span, _)) = inexistent_fields.last() {
930                 err.span_label(*span,
931                                format!("{} `{}` does not have {} field{}",
932                                        kind_name,
933                                        tcx.item_path_str(variant.did),
934                                        t,
935                                        plural));
936             }
937             if tcx.sess.teach(&err.get_code().unwrap()) {
938                 err.note(
939                     "This error indicates that a struct pattern attempted to \
940                      extract a non-existent field from a struct. Struct fields \
941                      are identified by the name used before the colon : so struct \
942                      patterns should resemble the declaration of the struct type \
943                      being matched.\n\n\
944                      If you are using shorthand field patterns but want to refer \
945                      to the struct field by a different name, you should rename \
946                      it explicitly."
947                 );
948             }
949             err.emit();
950         }
951
952         // Require `..` if struct has non_exhaustive attribute.
953         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
954             span_err!(tcx.sess, span, E0638,
955                       "`..` required with {} marked as non-exhaustive",
956                       kind_name);
957         }
958
959         // Report an error if incorrect number of the fields were specified.
960         if kind_name == "union" {
961             if fields.len() != 1 {
962                 tcx.sess.span_err(span, "union patterns should have exactly one field");
963             }
964             if etc {
965                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
966             }
967         } else if !etc {
968             let unmentioned_fields = variant.fields
969                 .iter()
970                 .map(|field| field.ident.modern())
971                 .filter(|ident| !used_fields.contains_key(&ident))
972                 .collect::<Vec<_>>();
973             if unmentioned_fields.len() > 0 {
974                 let field_names = if unmentioned_fields.len() == 1 {
975                     format!("field `{}`", unmentioned_fields[0])
976                 } else {
977                     format!("fields {}",
978                             unmentioned_fields.iter()
979                                 .map(|name| format!("`{}`", name))
980                                 .collect::<Vec<String>>()
981                                 .join(", "))
982                 };
983                 let mut diag = struct_span_err!(tcx.sess, span, E0027,
984                                                 "pattern does not mention {}",
985                                                 field_names);
986                 diag.span_label(span, format!("missing {}", field_names));
987                 if variant.ctor_kind == CtorKind::Fn {
988                     diag.note("trying to match a tuple variant with a struct variant pattern");
989                 }
990                 if tcx.sess.teach(&diag.get_code().unwrap()) {
991                     diag.note(
992                         "This error indicates that a pattern for a struct fails to specify a \
993                          sub-pattern for every one of the struct's fields. Ensure that each field \
994                          from the struct's definition is mentioned in the pattern, or use `..` to \
995                          ignore unwanted fields."
996                     );
997                 }
998                 diag.emit();
999             }
1000         }
1001         no_field_errors
1002     }
1003 }