]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/_match.rs
Update E0253.rs
[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 hir::def::Def;
12 use rustc::infer::{self, InferOk, TypeOrigin};
13 use hir::pat_util::EnumerateAndAdjustIterator;
14 use rustc::ty::subst::Substs;
15 use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference, VariantKind};
16 use check::{FnCtxt, Expectation};
17 use lint;
18 use util::nodemap::FnvHashMap;
19
20 use std::collections::hash_map::Entry::{Occupied, Vacant};
21 use std::cmp;
22 use syntax::ast;
23 use syntax::codemap::Spanned;
24 use syntax::ptr::P;
25 use syntax_pos::Span;
26
27 use rustc::hir::{self, PatKind};
28 use rustc::hir::print as pprust;
29
30 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
31     pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
32         let tcx = self.tcx;
33
34         debug!("check_pat(pat={:?},expected={:?})", pat, expected);
35
36         match pat.node {
37             PatKind::Wild => {
38                 self.write_ty(pat.id, expected);
39             }
40             PatKind::Lit(ref lt) => {
41                 self.check_expr(&lt);
42                 let expr_ty = self.expr_ty(&lt);
43
44                 // Byte string patterns behave the same way as array patterns
45                 // They can denote both statically and dynamically sized byte arrays
46                 let mut pat_ty = expr_ty;
47                 if let hir::ExprLit(ref lt) = lt.node {
48                     if let ast::LitKind::ByteStr(_) = lt.node {
49                         let expected_ty = self.structurally_resolved_type(pat.span, expected);
50                         if let ty::TyRef(_, mt) = expected_ty.sty {
51                             if let ty::TySlice(_) = mt.ty.sty {
52                                 pat_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic),
53                                                          tcx.mk_slice(tcx.types.u8))
54                             }
55                         }
56                     }
57                 }
58
59                 self.write_ty(pat.id, pat_ty);
60
61                 // somewhat surprising: in this case, the subtyping
62                 // relation goes the opposite way as the other
63                 // cases. Actually what we really want is not a subtyping
64                 // relation at all but rather that there exists a LUB (so
65                 // that they can be compared). However, in practice,
66                 // constants are always scalars or strings.  For scalars
67                 // subtyping is irrelevant, and for strings `expr_ty` is
68                 // type is `&'static str`, so if we say that
69                 //
70                 //     &'static str <: expected
71                 //
72                 // that's equivalent to there existing a LUB.
73                 self.demand_suptype(pat.span, expected, pat_ty);
74             }
75             PatKind::Range(ref begin, ref end) => {
76                 self.check_expr(begin);
77                 self.check_expr(end);
78
79                 let lhs_ty = self.expr_ty(begin);
80                 let rhs_ty = self.expr_ty(end);
81
82                 // Check that both end-points are of numeric or char type.
83                 let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char();
84                 let lhs_compat = numeric_or_char(lhs_ty);
85                 let rhs_compat = numeric_or_char(rhs_ty);
86
87                 if !lhs_compat || !rhs_compat {
88                     let span = if !lhs_compat && !rhs_compat {
89                         pat.span
90                     } else if !lhs_compat {
91                         begin.span
92                     } else {
93                         end.span
94                     };
95
96                     struct_span_err!(tcx.sess, span, E0029,
97                         "only char and numeric types are allowed in range patterns")
98                         .span_label(span, &format!("ranges require char or numeric types"))
99                         .note(&format!("start type: {}", self.ty_to_string(lhs_ty)))
100                         .note(&format!("end type: {}", self.ty_to_string(rhs_ty)))
101                         .emit();
102                     return;
103                 }
104
105                 // Now that we know the types can be unified we find the unified type and use
106                 // it to type the entire expression.
107                 let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
108
109                 self.write_ty(pat.id, common_type);
110
111                 // subtyping doesn't matter here, as the value is some kind of scalar
112                 self.demand_eqtype(pat.span, expected, lhs_ty);
113                 self.demand_eqtype(pat.span, expected, rhs_ty);
114             }
115             PatKind::Binding(bm, _, ref sub) => {
116                 let typ = self.local_ty(pat.span, pat.id);
117                 match bm {
118                     hir::BindByRef(mutbl) => {
119                         // if the binding is like
120                         //    ref x | ref const x | ref mut x
121                         // then `x` is assigned a value of type `&M T` where M is the mutability
122                         // and T is the expected type.
123                         let region_var = self.next_region_var(infer::PatternRegion(pat.span));
124                         let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
125                         let region_ty = tcx.mk_ref(tcx.mk_region(region_var), mt);
126
127                         // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
128                         // required. However, we use equality, which is stronger. See (*) for
129                         // an explanation.
130                         self.demand_eqtype(pat.span, region_ty, typ);
131                     }
132                     // otherwise the type of x is the expected type T
133                     hir::BindByValue(_) => {
134                         // As above, `T <: typeof(x)` is required but we
135                         // use equality, see (*) below.
136                         self.demand_eqtype(pat.span, expected, typ);
137                     }
138                 }
139
140                 self.write_ty(pat.id, typ);
141
142                 // if there are multiple arms, make sure they all agree on
143                 // what the type of the binding `x` ought to be
144                 match tcx.expect_def(pat.id) {
145                     Def::Err => {}
146                     Def::Local(_, var_id) => {
147                         if var_id != pat.id {
148                             let vt = self.local_ty(pat.span, var_id);
149                             self.demand_eqtype(pat.span, vt, typ);
150                         }
151                     }
152                     d => bug!("bad def for pattern binding `{:?}`", d)
153                 }
154
155                 if let Some(ref p) = *sub {
156                     self.check_pat(&p, expected);
157                 }
158             }
159             PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
160                 self.check_pat_tuple_struct(pat, path, &subpats, ddpos, expected);
161             }
162             PatKind::Path(ref opt_qself, ref path) => {
163                 let opt_qself_ty = opt_qself.as_ref().map(|qself| self.to_ty(&qself.ty));
164                 self.check_pat_path(pat, opt_qself_ty, path, expected);
165             }
166             PatKind::Struct(ref path, ref fields, etc) => {
167                 self.check_pat_struct(pat, path, fields, etc, expected);
168             }
169             PatKind::Tuple(ref elements, ddpos) => {
170                 let mut expected_len = elements.len();
171                 if ddpos.is_some() {
172                     // Require known type only when `..` is present
173                     if let ty::TyTuple(ref tys) =
174                             self.structurally_resolved_type(pat.span, expected).sty {
175                         expected_len = tys.len();
176                     }
177                 }
178                 let max_len = cmp::max(expected_len, elements.len());
179
180                 let element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect();
181                 let pat_ty = tcx.mk_tup(element_tys.clone());
182                 self.write_ty(pat.id, pat_ty);
183                 self.demand_eqtype(pat.span, expected, pat_ty);
184                 for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
185                     self.check_pat(elem, &element_tys[i]);
186                 }
187             }
188             PatKind::Box(ref inner) => {
189                 let inner_ty = self.next_ty_var();
190                 let uniq_ty = tcx.mk_box(inner_ty);
191
192                 if self.check_dereferencable(pat.span, expected, &inner) {
193                     // Here, `demand::subtype` is good enough, but I don't
194                     // think any errors can be introduced by using
195                     // `demand::eqtype`.
196                     self.demand_eqtype(pat.span, expected, uniq_ty);
197                     self.write_ty(pat.id, uniq_ty);
198                     self.check_pat(&inner, inner_ty);
199                 } else {
200                     self.write_error(pat.id);
201                     self.check_pat(&inner, tcx.types.err);
202                 }
203             }
204             PatKind::Ref(ref inner, mutbl) => {
205                 let expected = self.shallow_resolve(expected);
206                 if self.check_dereferencable(pat.span, expected, &inner) {
207                     // `demand::subtype` would be good enough, but using
208                     // `eqtype` turns out to be equally general. See (*)
209                     // below for details.
210
211                     // Take region, inner-type from expected type if we
212                     // can, to avoid creating needless variables.  This
213                     // also helps with the bad interactions of the given
214                     // hack detailed in (*) below.
215                     let (rptr_ty, inner_ty) = match expected.sty {
216                         ty::TyRef(_, mt) if mt.mutbl == mutbl => {
217                             (expected, mt.ty)
218                         }
219                         _ => {
220                             let inner_ty = self.next_ty_var();
221                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
222                             let region = self.next_region_var(infer::PatternRegion(pat.span));
223                             let rptr_ty = tcx.mk_ref(tcx.mk_region(region), mt);
224                             self.demand_eqtype(pat.span, expected, rptr_ty);
225                             (rptr_ty, inner_ty)
226                         }
227                     };
228
229                     self.write_ty(pat.id, rptr_ty);
230                     self.check_pat(&inner, inner_ty);
231                 } else {
232                     self.write_error(pat.id);
233                     self.check_pat(&inner, tcx.types.err);
234                 }
235             }
236             PatKind::Vec(ref before, ref slice, ref after) => {
237                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
238                 let (inner_ty, slice_ty) = match expected_ty.sty {
239                     ty::TyArray(inner_ty, size) => {
240                         let min_len = before.len() + after.len();
241                         if slice.is_none() {
242                             if min_len != size {
243                                 span_err!(tcx.sess, pat.span, E0527,
244                                           "pattern requires {} elements but array has {}",
245                                           min_len, size);
246                             }
247                             (inner_ty, tcx.types.err)
248                         } else if let Some(rest) = size.checked_sub(min_len) {
249                             (inner_ty, tcx.mk_array(inner_ty, rest))
250                         } else {
251                             span_err!(tcx.sess, pat.span, E0528,
252                                       "pattern requires at least {} elements but array has {}",
253                                       min_len, size);
254                             (inner_ty, tcx.types.err)
255                         }
256                     }
257                     ty::TySlice(inner_ty) => (inner_ty, expected_ty),
258                     _ => {
259                         if !expected_ty.references_error() {
260                             let mut err = struct_span_err!(
261                                 tcx.sess, pat.span, E0529,
262                                 "expected an array or slice, found `{}`",
263                                 expected_ty);
264                             if let ty::TyRef(_, ty::TypeAndMut { mutbl: _, ty }) = expected_ty.sty {
265                                 match ty.sty {
266                                     ty::TyArray(..) | ty::TySlice(..) => {
267                                         err.help("the semantics of slice patterns changed \
268                                                   recently; see issue #23121");
269                                     }
270                                     _ => {}
271                                 }
272                             }
273                             err.emit();
274                         }
275                         (tcx.types.err, tcx.types.err)
276                     }
277                 };
278
279                 self.write_ty(pat.id, expected_ty);
280
281                 for elt in before {
282                     self.check_pat(&elt, inner_ty);
283                 }
284                 if let Some(ref slice) = *slice {
285                     self.check_pat(&slice, slice_ty);
286                 }
287                 for elt in after {
288                     self.check_pat(&elt, inner_ty);
289                 }
290             }
291         }
292
293         // (*) In most of the cases above (literals and constants being
294         // the exception), we relate types using strict equality, evewn
295         // though subtyping would be sufficient. There are a few reasons
296         // for this, some of which are fairly subtle and which cost me
297         // (nmatsakis) an hour or two debugging to remember, so I thought
298         // I'd write them down this time.
299         //
300         // 1. There is no loss of expressiveness here, though it does
301         // cause some inconvenience. What we are saying is that the type
302         // of `x` becomes *exactly* what is expected. This can cause unnecessary
303         // errors in some cases, such as this one:
304         // it will cause errors in a case like this:
305         //
306         // ```
307         // fn foo<'x>(x: &'x int) {
308         //    let a = 1;
309         //    let mut z = x;
310         //    z = &a;
311         // }
312         // ```
313         //
314         // The reason we might get an error is that `z` might be
315         // assigned a type like `&'x int`, and then we would have
316         // a problem when we try to assign `&a` to `z`, because
317         // the lifetime of `&a` (i.e., the enclosing block) is
318         // shorter than `'x`.
319         //
320         // HOWEVER, this code works fine. The reason is that the
321         // expected type here is whatever type the user wrote, not
322         // the initializer's type. In this case the user wrote
323         // nothing, so we are going to create a type variable `Z`.
324         // Then we will assign the type of the initializer (`&'x
325         // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
326         // will instantiate `Z` as a type `&'0 int` where `'0` is
327         // a fresh region variable, with the constraint that `'x :
328         // '0`.  So basically we're all set.
329         //
330         // Note that there are two tests to check that this remains true
331         // (`regions-reassign-{match,let}-bound-pointer.rs`).
332         //
333         // 2. Things go horribly wrong if we use subtype. The reason for
334         // THIS is a fairly subtle case involving bound regions. See the
335         // `givens` field in `region_inference`, as well as the test
336         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
337         // for details. Short version is that we must sometimes detect
338         // relationships between specific region variables and regions
339         // bound in a closure signature, and that detection gets thrown
340         // off when we substitute fresh region variables here to enable
341         // subtyping.
342     }
343
344     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
345         if let PatKind::Binding(..) = inner.node {
346             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true, ty::NoPreference) {
347                 if let ty::TyTrait(..) = mt.ty.sty {
348                     // This is "x = SomeTrait" being reduced from
349                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
350                     span_err!(self.tcx.sess, span, E0033,
351                               "type `{}` cannot be dereferenced",
352                               self.ty_to_string(expected));
353                     return false
354                 }
355             }
356         }
357         true
358     }
359 }
360
361 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
362     pub fn check_match(&self,
363                        expr: &'gcx hir::Expr,
364                        discrim: &'gcx hir::Expr,
365                        arms: &'gcx [hir::Arm],
366                        expected: Expectation<'tcx>,
367                        match_src: hir::MatchSource) {
368         let tcx = self.tcx;
369
370         // Not entirely obvious: if matches may create ref bindings, we
371         // want to use the *precise* type of the discriminant, *not* some
372         // supertype, as the "discriminant type" (issue #23116).
373         let contains_ref_bindings = arms.iter()
374                                         .filter_map(|a| tcx.arm_contains_ref_binding(a))
375                                         .max_by_key(|m| match *m {
376                                             hir::MutMutable => 1,
377                                             hir::MutImmutable => 0,
378                                         });
379         let discrim_ty;
380         if let Some(m) = contains_ref_bindings {
381             self.check_expr_with_lvalue_pref(discrim, LvaluePreference::from_mutbl(m));
382             discrim_ty = self.expr_ty(discrim);
383         } else {
384             // ...but otherwise we want to use any supertype of the
385             // discriminant. This is sort of a workaround, see note (*) in
386             // `check_pat` for some details.
387             discrim_ty = self.next_ty_var();
388             self.check_expr_has_type(discrim, discrim_ty);
389         };
390
391         // Typecheck the patterns first, so that we get types for all the
392         // bindings.
393         for arm in arms {
394             for p in &arm.pats {
395                 self.check_pat(&p, discrim_ty);
396             }
397         }
398
399         // Now typecheck the blocks.
400         //
401         // The result of the match is the common supertype of all the
402         // arms. Start out the value as bottom, since it's the, well,
403         // bottom the type lattice, and we'll be moving up the lattice as
404         // we process each arm. (Note that any match with 0 arms is matching
405         // on any empty type and is therefore unreachable; should the flow
406         // of execution reach it, we will panic, so bottom is an appropriate
407         // type in that case)
408         let expected = expected.adjust_for_branches(self);
409         let mut result_ty = self.next_diverging_ty_var();
410         let coerce_first = match expected {
411             // We don't coerce to `()` so that if the match expression is a
412             // statement it's branches can have any consistent type. That allows
413             // us to give better error messages (pointing to a usually better
414             // arm for inconsistent arms or to the whole match when a `()` type
415             // is required).
416             Expectation::ExpectHasType(ety) if ety != self.tcx.mk_nil() => {
417                 ety
418             }
419             _ => result_ty
420         };
421         for (i, arm) in arms.iter().enumerate() {
422             if let Some(ref e) = arm.guard {
423                 self.check_expr_has_type(e, tcx.types.bool);
424             }
425             self.check_expr_with_expectation(&arm.body, expected);
426             let arm_ty = self.expr_ty(&arm.body);
427
428             if result_ty.references_error() || arm_ty.references_error() {
429                 result_ty = tcx.types.err;
430                 continue;
431             }
432
433             // Handle the fallback arm of a desugared if-let like a missing else.
434             let is_if_let_fallback = match match_src {
435                 hir::MatchSource::IfLetDesugar { contains_else_clause: false } => {
436                     i == arms.len() - 1 && arm_ty.is_nil()
437                 }
438                 _ => false
439             };
440
441             let origin = if is_if_let_fallback {
442                 TypeOrigin::IfExpressionWithNoElse(expr.span)
443             } else {
444                 TypeOrigin::MatchExpressionArm(expr.span, arm.body.span, match_src)
445             };
446
447             let result = if is_if_let_fallback {
448                 self.eq_types(true, origin, arm_ty, result_ty)
449                     .map(|InferOk { obligations, .. }| {
450                         // FIXME(#32730) propagate obligations
451                         assert!(obligations.is_empty());
452                         arm_ty
453                     })
454             } else if i == 0 {
455                 // Special-case the first arm, as it has no "previous expressions".
456                 self.try_coerce(&arm.body, coerce_first)
457             } else {
458                 let prev_arms = || arms[..i].iter().map(|arm| &*arm.body);
459                 self.try_find_coercion_lub(origin, prev_arms, result_ty, &arm.body)
460             };
461
462             result_ty = match result {
463                 Ok(ty) => ty,
464                 Err(e) => {
465                     let (expected, found) = if is_if_let_fallback {
466                         (arm_ty, result_ty)
467                     } else {
468                         (result_ty, arm_ty)
469                     };
470                     self.report_mismatched_types(origin, expected, found, e);
471                     self.tcx.types.err
472                 }
473             };
474         }
475
476         self.write_ty(expr.id, result_ty);
477     }
478 }
479
480 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
481     fn check_pat_struct(&self,
482                         pat: &'gcx hir::Pat,
483                         path: &hir::Path,
484                         fields: &'gcx [Spanned<hir::FieldPat>],
485                         etc: bool,
486                         expected: Ty<'tcx>)
487     {
488         // Resolve the path and check the definition for errors.
489         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id,
490                                                                                  pat.span) {
491             variant_ty
492         } else {
493             self.write_error(pat.id);
494             for field in fields {
495                 self.check_pat(&field.node.pat, self.tcx.types.err);
496             }
497             return;
498         };
499
500         // Type check the path.
501         self.demand_eqtype(pat.span, expected, pat_ty);
502
503         // Type check subpatterns.
504         let substs = match pat_ty.sty {
505             ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
506             _ => span_bug!(pat.span, "struct variant is not an ADT")
507         };
508         self.check_struct_pat_fields(pat.span, fields, variant, substs, etc);
509     }
510
511     fn check_pat_path(&self,
512                       pat: &hir::Pat,
513                       opt_self_ty: Option<Ty<'tcx>>,
514                       path: &hir::Path,
515                       expected: Ty<'tcx>)
516     {
517         let tcx = self.tcx;
518         let report_unexpected_def = || {
519             span_err!(tcx.sess, pat.span, E0533,
520                       "`{}` does not name a unit variant, unit struct or a constant",
521                       pprust::path_to_string(path));
522             self.write_error(pat.id);
523         };
524
525         // Resolve the path and check the definition for errors.
526         let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path,
527                                                                    pat.id, pat.span);
528         match def {
529             Def::Err => {
530                 self.set_tainted_by_errors();
531                 self.write_error(pat.id);
532                 return;
533             }
534             Def::Method(..) => {
535                 report_unexpected_def();
536                 return;
537             }
538             Def::Variant(..) | Def::Struct(..) => {
539                 let variant = tcx.expect_variant_def(def);
540                 if variant.kind != VariantKind::Unit {
541                     report_unexpected_def();
542                     return;
543                 }
544             }
545             Def::Const(..) | Def::AssociatedConst(..) => {} // OK
546             _ => bug!("unexpected pattern definition {:?}", def)
547         }
548
549         // Type check the path.
550         let scheme = tcx.lookup_item_type(def.def_id());
551         let predicates = tcx.lookup_predicates(def.def_id());
552         let pat_ty = self.instantiate_value_path(segments, scheme, &predicates,
553                                                  opt_ty, def, pat.span, pat.id);
554         self.demand_suptype(pat.span, expected, pat_ty);
555     }
556
557     fn check_pat_tuple_struct(&self,
558                               pat: &hir::Pat,
559                               path: &hir::Path,
560                               subpats: &'gcx [P<hir::Pat>],
561                               ddpos: Option<usize>,
562                               expected: Ty<'tcx>)
563     {
564         let tcx = self.tcx;
565         let on_error = || {
566             self.write_error(pat.id);
567             for pat in subpats {
568                 self.check_pat(&pat, tcx.types.err);
569             }
570         };
571         let report_unexpected_def = |is_lint| {
572             let msg = format!("`{}` does not name a tuple variant or a tuple struct",
573                               pprust::path_to_string(path));
574             if is_lint {
575                 tcx.sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
576                                   pat.id, pat.span, msg);
577             } else {
578                 span_err!(tcx.sess, pat.span, E0164, "{}", msg);
579                 on_error();
580             }
581         };
582
583         // Resolve the path and check the definition for errors.
584         let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(None, path, pat.id, pat.span);
585         let variant = match def {
586             Def::Err => {
587                 self.set_tainted_by_errors();
588                 on_error();
589                 return;
590             }
591             Def::Const(..) | Def::AssociatedConst(..) | Def::Method(..) => {
592                 report_unexpected_def(false);
593                 return;
594             }
595             Def::Variant(..) | Def::Struct(..) => {
596                 tcx.expect_variant_def(def)
597             }
598             _ => bug!("unexpected pattern definition {:?}", def)
599         };
600         if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() {
601             // Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
602             // is allowed for backward compatibility.
603             report_unexpected_def(true);
604         } else if variant.kind != VariantKind::Tuple {
605             report_unexpected_def(false);
606             return;
607         }
608
609         // Type check the path.
610         let scheme = tcx.lookup_item_type(def.def_id());
611         let scheme = if scheme.ty.is_fn() {
612             // Replace constructor type with constructed type for tuple struct patterns.
613             let fn_ret = tcx.no_late_bound_regions(&scheme.ty.fn_ret()).unwrap().unwrap();
614             ty::TypeScheme { ty: fn_ret, generics: scheme.generics }
615         } else {
616             // Leave the type as is for unit structs (backward compatibility).
617             scheme
618         };
619         let predicates = tcx.lookup_predicates(def.def_id());
620         let pat_ty = self.instantiate_value_path(segments, scheme, &predicates,
621                                                  opt_ty, def, pat.span, pat.id);
622         self.demand_eqtype(pat.span, expected, pat_ty);
623
624         // Type check subpatterns.
625         if subpats.len() == variant.fields.len() ||
626                 subpats.len() < variant.fields.len() && ddpos.is_some() {
627             let substs = match pat_ty.sty {
628                 ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs,
629                 ref ty => bug!("unexpected pattern type {:?}", ty),
630             };
631             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
632                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
633                 self.check_pat(&subpat, field_ty);
634             }
635         } else {
636             span_err!(tcx.sess, pat.span, E0023,
637                       "this pattern has {} field{s}, but the corresponding {} has {} field{s}",
638                       subpats.len(), def.kind_name(), variant.fields.len(),
639                       s = if variant.fields.len() == 1 {""} else {"s"});
640             on_error();
641         }
642     }
643
644     /// `path` is the AST path item naming the type of this struct.
645     /// `fields` is the field patterns of the struct pattern.
646     /// `struct_fields` describes the type of each field of the struct.
647     /// `struct_id` is the ID of the struct.
648     /// `etc` is true if the pattern said '...' and false otherwise.
649     pub fn check_struct_pat_fields(&self,
650                                    span: Span,
651                                    fields: &'gcx [Spanned<hir::FieldPat>],
652                                    variant: ty::VariantDef<'tcx>,
653                                    substs: &Substs<'tcx>,
654                                    etc: bool) {
655         let tcx = self.tcx;
656
657         // Index the struct fields' types.
658         let field_map = variant.fields
659             .iter()
660             .map(|field| (field.name, field))
661             .collect::<FnvHashMap<_, _>>();
662
663         // Keep track of which fields have already appeared in the pattern.
664         let mut used_fields = FnvHashMap();
665
666         // Typecheck each field.
667         for &Spanned { node: ref field, span } in fields {
668             let field_ty = match used_fields.entry(field.name) {
669                 Occupied(occupied) => {
670                     let mut err = struct_span_err!(tcx.sess, span, E0025,
671                                                    "field `{}` bound multiple times \
672                                                     in the pattern",
673                                                    field.name);
674                     span_note!(&mut err, *occupied.get(),
675                                "field `{}` previously bound here",
676                                field.name);
677                     err.emit();
678                     tcx.types.err
679                 }
680                 Vacant(vacant) => {
681                     vacant.insert(span);
682                     field_map.get(&field.name)
683                         .map(|f| self.field_ty(span, f, substs))
684                         .unwrap_or_else(|| {
685                             span_err!(tcx.sess, span, E0026,
686                                 "struct `{}` does not have a field named `{}`",
687                                 tcx.item_path_str(variant.did),
688                                 field.name);
689                             tcx.types.err
690                         })
691                 }
692             };
693
694             self.check_pat(&field.pat, field_ty);
695         }
696
697         // Report an error if not all the fields were specified.
698         if !etc {
699             for field in variant.fields
700                 .iter()
701                 .filter(|field| !used_fields.contains_key(&field.name)) {
702                 struct_span_err!(tcx.sess, span, E0027,
703                                 "pattern does not mention field `{}`",
704                                 field.name)
705                                 .span_label(span, &format!("missing field `{}`", field.name))
706                                 .emit();
707             }
708         }
709     }
710 }