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