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