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.
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.
11 use rustc::hir::{self, PatKind};
12 use rustc::hir::def::{Def, CtorKind};
13 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
15 use rustc::infer::type_variable::TypeVariableOrigin;
16 use rustc::traits::ObligationCauseCode;
17 use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
18 use check::{FnCtxt, Expectation, Diverges};
19 use check::coercion::CoerceMany;
20 use util::nodemap::FxHashMap;
22 use std::collections::hash_map::Entry::{Occupied, Vacant};
25 use syntax::codemap::Spanned;
29 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30 pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
31 self.check_pat_arg(pat, expected, false);
34 /// The `is_arg` argument indicates whether this pattern is the
35 /// *outermost* pattern in an argument (e.g., in `fn foo(&x:
36 /// &u32)`, it is true for the `&x` pattern but not `x`). This is
37 /// used to tailor error reporting.
38 pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: bool) {
41 debug!("check_pat(pat={:?},expected={:?},is_arg={})", pat, expected, is_arg);
43 let ty = match pat.node {
47 PatKind::Lit(ref lt) => {
48 let ty = self.check_expr(<);
50 // Byte string patterns behave the same way as array patterns
51 // They can denote both statically and dynamically sized byte arrays
53 if let hir::ExprLit(ref lt) = lt.node {
54 if let ast::LitKind::ByteStr(_) = lt.node {
55 let expected_ty = self.structurally_resolved_type(pat.span, expected);
56 if let ty::TyRef(_, mt) = expected_ty.sty {
57 if let ty::TySlice(_) = mt.ty.sty {
58 pat_ty = tcx.mk_imm_ref(tcx.types.re_static,
59 tcx.mk_slice(tcx.types.u8))
65 // somewhat surprising: in this case, the subtyping
66 // relation goes the opposite way as the other
67 // cases. Actually what we really want is not a subtyping
68 // relation at all but rather that there exists a LUB (so
69 // that they can be compared). However, in practice,
70 // constants are always scalars or strings. For scalars
71 // subtyping is irrelevant, and for strings `ty` is
72 // type is `&'static str`, so if we say that
74 // &'static str <: expected
76 // that's equivalent to there existing a LUB.
77 self.demand_suptype(pat.span, expected, pat_ty);
80 PatKind::Range(ref begin, ref end, _) => {
81 let lhs_ty = self.check_expr(begin);
82 let rhs_ty = self.check_expr(end);
84 // Check that both end-points are of numeric or char type.
85 let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char();
86 let lhs_compat = numeric_or_char(lhs_ty);
87 let rhs_compat = numeric_or_char(rhs_ty);
89 if !lhs_compat || !rhs_compat {
90 let span = if !lhs_compat && !rhs_compat {
92 } else if !lhs_compat {
98 struct_span_err!(tcx.sess, span, E0029,
99 "only char and numeric types are allowed in range patterns")
100 .span_label(span, "ranges require char or numeric types")
101 .note(&format!("start type: {}", self.ty_to_string(lhs_ty)))
102 .note(&format!("end type: {}", self.ty_to_string(rhs_ty)))
107 // Now that we know the types can be unified we find the unified type and use
108 // it to type the entire expression.
109 let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
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);
116 PatKind::Binding(ba, def_id, _, ref sub) => {
117 // Note the binding mode in the typeck tables. For now, what we store is always
118 // identical to what could be scraped from the HIR, but this will change with
119 // default binding modes (#42640).
120 let bm = ty::BindingMode::convert(ba);
124 .pat_binding_modes_mut()
125 .insert(pat.hir_id, bm);
126 let typ = self.local_ty(pat.span, pat.id);
128 ty::BindByReference(mutbl) => {
129 // if the binding is like
130 // ref x | ref const x | ref mut x
131 // then `x` is assigned a value of type `&M T` where M is the mutability
132 // and T is the expected type.
133 let region_var = self.next_region_var(infer::PatternRegion(pat.span));
134 let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
135 let region_ty = tcx.mk_ref(region_var, mt);
137 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
138 // required. However, we use equality, which is stronger. See (*) for
140 self.demand_eqtype(pat.span, region_ty, typ);
142 // otherwise the type of x is the expected type T
143 ty::BindByValue(_) => {
144 // As above, `T <: typeof(x)` is required but we
145 // use equality, see (*) below.
146 self.demand_eqtype(pat.span, expected, typ);
150 // if there are multiple arms, make sure they all agree on
151 // what the type of the binding `x` ought to be
152 let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
153 if var_id != pat.id {
154 let vt = self.local_ty(pat.span, var_id);
155 self.demand_eqtype(pat.span, vt, typ);
158 if let Some(ref p) = *sub {
159 self.check_pat(&p, expected);
164 PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
165 self.check_pat_tuple_struct(pat, qpath, &subpats, ddpos, expected)
167 PatKind::Path(ref qpath) => {
168 self.check_pat_path(pat, qpath, expected)
170 PatKind::Struct(ref qpath, ref fields, etc) => {
171 self.check_pat_struct(pat, qpath, fields, etc, expected)
173 PatKind::Tuple(ref elements, ddpos) => {
174 let mut expected_len = elements.len();
176 // Require known type only when `..` is present
177 if let ty::TyTuple(ref tys, _) =
178 self.structurally_resolved_type(pat.span, expected).sty {
179 expected_len = tys.len();
182 let max_len = cmp::max(expected_len, elements.len());
184 let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(
185 // FIXME: MiscVariable for now, obtaining the span and name information
186 // from all tuple elements isn't trivial.
187 TypeVariableOrigin::TypeInference(pat.span)));
188 let element_tys = tcx.mk_type_list(element_tys_iter);
189 let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false));
190 self.demand_eqtype(pat.span, expected, pat_ty);
191 for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
192 self.check_pat(elem, &element_tys[i]);
196 PatKind::Box(ref inner) => {
197 let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));
198 let uniq_ty = tcx.mk_box(inner_ty);
200 if self.check_dereferencable(pat.span, expected, &inner) {
201 // Here, `demand::subtype` is good enough, but I don't
202 // think any errors can be introduced by using
204 self.demand_eqtype(pat.span, expected, uniq_ty);
205 self.check_pat(&inner, inner_ty);
208 self.check_pat(&inner, tcx.types.err);
212 PatKind::Ref(ref inner, mutbl) => {
213 let expected = self.shallow_resolve(expected);
214 if self.check_dereferencable(pat.span, expected, &inner) {
215 // `demand::subtype` would be good enough, but using
216 // `eqtype` turns out to be equally general. See (*)
217 // below for details.
219 // Take region, inner-type from expected type if we
220 // can, to avoid creating needless variables. This
221 // also helps with the bad interactions of the given
222 // hack detailed in (*) below.
223 debug!("check_pat_arg: expected={:?}", expected);
224 let (rptr_ty, inner_ty) = match expected.sty {
225 ty::TyRef(_, mt) if mt.mutbl == mutbl => {
229 let inner_ty = self.next_ty_var(
230 TypeVariableOrigin::TypeInference(inner.span));
231 let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
232 let region = self.next_region_var(infer::PatternRegion(pat.span));
233 let rptr_ty = tcx.mk_ref(region, mt);
234 debug!("check_pat_arg: demanding {:?} = {:?}", expected, rptr_ty);
235 let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
237 // Look for a case like `fn foo(&foo: u32)` and suggest
238 // `fn foo(foo: &u32)`
239 if let Some(mut err) = err {
241 if let PatKind::Binding(..) = inner.node {
242 if let Ok(snippet) = self.sess().codemap()
243 .span_to_snippet(pat.span)
245 err.help(&format!("did you mean `{}: &{}`?",
257 self.check_pat(&inner, inner_ty);
260 self.check_pat(&inner, tcx.types.err);
264 PatKind::Slice(ref before, ref slice, ref after) => {
265 let expected_ty = self.structurally_resolved_type(pat.span, expected);
266 let (inner_ty, slice_ty) = match expected_ty.sty {
267 ty::TyArray(inner_ty, size) => {
268 let min_len = before.len() + after.len();
272 tcx.sess, pat.span, E0527,
273 "pattern requires {} elements but array has {}",
275 .span_label(pat.span, format!("expected {} elements",size))
278 (inner_ty, tcx.types.err)
279 } else if let Some(rest) = size.checked_sub(min_len) {
280 (inner_ty, tcx.mk_array(inner_ty, rest))
282 struct_span_err!(tcx.sess, pat.span, E0528,
283 "pattern requires at least {} elements but array has {}",
285 .span_label(pat.span,
286 format!("pattern cannot match array of {} elements", size))
288 (inner_ty, tcx.types.err)
291 ty::TySlice(inner_ty) => (inner_ty, expected_ty),
293 if !expected_ty.references_error() {
294 let mut err = struct_span_err!(
295 tcx.sess, pat.span, E0529,
296 "expected an array or slice, found `{}`",
298 if let ty::TyRef(_, ty::TypeAndMut { mutbl: _, ty }) = expected_ty.sty {
300 ty::TyArray(..) | ty::TySlice(..) => {
301 err.help("the semantics of slice patterns changed \
302 recently; see issue #23121");
308 err.span_label( pat.span,
309 format!("pattern cannot match with input type `{}`", expected_ty)
312 (tcx.types.err, tcx.types.err)
317 self.check_pat(&elt, inner_ty);
319 if let Some(ref slice) = *slice {
320 self.check_pat(&slice, slice_ty);
323 self.check_pat(&elt, inner_ty);
329 self.write_ty(pat.hir_id, ty);
331 // (*) In most of the cases above (literals and constants being
332 // the exception), we relate types using strict equality, evewn
333 // though subtyping would be sufficient. There are a few reasons
334 // for this, some of which are fairly subtle and which cost me
335 // (nmatsakis) an hour or two debugging to remember, so I thought
336 // I'd write them down this time.
338 // 1. There is no loss of expressiveness here, though it does
339 // cause some inconvenience. What we are saying is that the type
340 // of `x` becomes *exactly* what is expected. This can cause unnecessary
341 // errors in some cases, such as this one:
342 // it will cause errors in a case like this:
345 // fn foo<'x>(x: &'x int) {
352 // The reason we might get an error is that `z` might be
353 // assigned a type like `&'x int`, and then we would have
354 // a problem when we try to assign `&a` to `z`, because
355 // the lifetime of `&a` (i.e., the enclosing block) is
356 // shorter than `'x`.
358 // HOWEVER, this code works fine. The reason is that the
359 // expected type here is whatever type the user wrote, not
360 // the initializer's type. In this case the user wrote
361 // nothing, so we are going to create a type variable `Z`.
362 // Then we will assign the type of the initializer (`&'x
363 // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
364 // will instantiate `Z` as a type `&'0 int` where `'0` is
365 // a fresh region variable, with the constraint that `'x :
366 // '0`. So basically we're all set.
368 // Note that there are two tests to check that this remains true
369 // (`regions-reassign-{match,let}-bound-pointer.rs`).
371 // 2. Things go horribly wrong if we use subtype. The reason for
372 // THIS is a fairly subtle case involving bound regions. See the
373 // `givens` field in `region_inference`, as well as the test
374 // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
375 // for details. Short version is that we must sometimes detect
376 // relationships between specific region variables and regions
377 // bound in a closure signature, and that detection gets thrown
378 // off when we substitute fresh region variables here to enable
382 pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
383 if let PatKind::Binding(..) = inner.node {
384 if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true, ty::NoPreference) {
385 if let ty::TyDynamic(..) = mt.ty.sty {
386 // This is "x = SomeTrait" being reduced from
387 // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
388 let type_str = self.ty_to_string(expected);
389 struct_span_err!(self.tcx.sess, span, E0033,
390 "type `{}` cannot be dereferenced", type_str)
391 .span_label(span, format!("type `{}` cannot be dereferenced", type_str))
400 pub fn check_match(&self,
401 expr: &'gcx hir::Expr,
402 discrim: &'gcx hir::Expr,
403 arms: &'gcx [hir::Arm],
404 expected: Expectation<'tcx>,
405 match_src: hir::MatchSource) -> Ty<'tcx> {
408 // Not entirely obvious: if matches may create ref bindings, we want to
409 // use the *precise* type of the discriminant, *not* some supertype, as
410 // the "discriminant type" (issue #23116).
412 // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
413 // is problematic as the HIR is being scraped, but ref bindings may be
414 // implicit after #42640. We need to make sure that pat_adjustments
415 // (once introduced) is populated by the time we get here.
417 // arielb1 [writes here in this comment thread][c] that there
418 // is certainly *some* potential danger, e.g. for an example
421 // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
424 // let Foo(x) = f()[0];
427 // Then if the pattern matches by reference, we want to match
428 // `f()[0]` as a lexpr, so we can't allow it to be
429 // coerced. But if the pattern matches by value, `f()[0]` is
430 // still syntactically a lexpr, but we *do* want to allow
433 // However, *likely* we are ok with allowing coercions to
434 // happen if there are no explicit ref mut patterns - all
435 // implicit ref mut patterns must occur behind a reference, so
436 // they will have the "correct" variance and lifetime.
438 // This does mean that the following pattern would be legal:
443 // impl Deref for Foo {
444 // type Target = Bar;
445 // fn deref(&self) -> &Bar { &self.0 }
447 // impl DerefMut for Foo {
448 // fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
450 // fn foo(x: &mut Foo) {
452 // let Bar(z): &mut Bar = x;
455 // assert_eq!(foo.0.0, 42);
459 let contains_ref_bindings = arms.iter()
460 .filter_map(|a| a.contains_explicit_ref_binding())
461 .max_by_key(|m| match *m {
462 hir::MutMutable => 1,
463 hir::MutImmutable => 0,
466 if let Some(m) = contains_ref_bindings {
467 discrim_ty = self.check_expr_with_lvalue_pref(discrim, LvaluePreference::from_mutbl(m));
469 // ...but otherwise we want to use any supertype of the
470 // discriminant. This is sort of a workaround, see note (*) in
471 // `check_pat` for some details.
472 discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
473 self.check_expr_has_type_or_error(discrim, discrim_ty);
476 // If the discriminant diverges, the match is pointless (e.g.,
477 // `match (return) { }`).
478 self.warn_if_unreachable(expr.id, expr.span, "expression");
480 // If there are no arms, that is a diverging match; a special case.
482 self.diverges.set(self.diverges.get() | Diverges::Always);
483 return tcx.types.never;
486 // Otherwise, we have to union together the types that the
487 // arms produce and so forth.
489 let discrim_diverges = self.diverges.get();
490 self.diverges.set(Diverges::Maybe);
492 // Typecheck the patterns first, so that we get types for all the
494 let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
495 let mut all_pats_diverge = Diverges::WarnedAlways;
497 self.diverges.set(Diverges::Maybe);
498 self.check_pat(&p, discrim_ty);
499 all_pats_diverge &= self.diverges.get();
502 // As discussed with @eddyb, this is for disabling unreachable_code
503 // warnings on patterns (they're now subsumed by unreachable_patterns
505 match all_pats_diverge {
506 Diverges::Maybe => Diverges::Maybe,
507 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
511 // Now typecheck the blocks.
513 // The result of the match is the common supertype of all the
514 // arms. Start out the value as bottom, since it's the, well,
515 // bottom the type lattice, and we'll be moving up the lattice as
516 // we process each arm. (Note that any match with 0 arms is matching
517 // on any empty type and is therefore unreachable; should the flow
518 // of execution reach it, we will panic, so bottom is an appropriate
519 // type in that case)
520 let mut all_arms_diverge = Diverges::WarnedAlways;
522 let expected = expected.adjust_for_branches(self);
525 let coerce_first = match expected {
526 // We don't coerce to `()` so that if the match expression is a
527 // statement it's branches can have any consistent type. That allows
528 // us to give better error messages (pointing to a usually better
529 // arm for inconsistent arms or to the whole match when a `()` type
531 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_nil() => ety,
532 _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
534 CoerceMany::with_coercion_sites(coerce_first, arms)
537 for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
538 if let Some(ref e) = arm.guard {
539 self.diverges.set(pats_diverge);
540 self.check_expr_has_type_or_error(e, tcx.types.bool);
543 self.diverges.set(pats_diverge);
544 let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
545 all_arms_diverge &= self.diverges.get();
547 // Handle the fallback arm of a desugared if-let like a missing else.
548 let is_if_let_fallback = match match_src {
549 hir::MatchSource::IfLetDesugar { contains_else_clause: false } => {
550 i == arms.len() - 1 && arm_ty.is_nil()
555 if is_if_let_fallback {
556 let cause = self.cause(expr.span, ObligationCauseCode::IfExpressionWithNoElse);
557 assert!(arm_ty.is_nil());
558 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
560 let cause = self.cause(expr.span, ObligationCauseCode::MatchExpressionArm {
561 arm_span: arm.body.span,
564 coercion.coerce(self, &cause, &arm.body, arm_ty, self.diverges.get());
568 // We won't diverge unless the discriminant or all arms diverge.
569 self.diverges.set(discrim_diverges | all_arms_diverge);
571 coercion.complete(self)
574 fn check_pat_struct(&self,
577 fields: &'gcx [Spanned<hir::FieldPat>],
579 expected: Ty<'tcx>) -> Ty<'tcx>
581 // Resolve the path and check the definition for errors.
582 let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.id) {
585 for field in fields {
586 self.check_pat(&field.node.pat, self.tcx.types.err);
588 return self.tcx.types.err;
591 // Type check the path.
592 self.demand_eqtype(pat.span, expected, pat_ty);
594 // Type check subpatterns.
595 self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc);
599 fn check_pat_path(&self,
602 expected: Ty<'tcx>) -> Ty<'tcx>
605 let report_unexpected_def = |def: Def| {
606 span_err!(tcx.sess, pat.span, E0533,
607 "expected unit struct/variant or constant, found {} `{}`",
609 hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
612 // Resolve the path and check the definition for errors.
613 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span);
616 self.set_tainted_by_errors();
617 return tcx.types.err;
620 report_unexpected_def(def);
621 return tcx.types.err;
623 Def::VariantCtor(_, CtorKind::Const) |
624 Def::StructCtor(_, CtorKind::Const) |
625 Def::Const(..) | Def::AssociatedConst(..) => {} // OK
626 _ => bug!("unexpected pattern definition: {:?}", def)
629 // Type check the path.
630 let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
631 self.demand_suptype(pat.span, expected, pat_ty);
635 fn check_pat_tuple_struct(&self,
638 subpats: &'gcx [P<hir::Pat>],
639 ddpos: Option<usize>,
640 expected: Ty<'tcx>) -> Ty<'tcx>
645 self.check_pat(&pat, tcx.types.err);
648 let report_unexpected_def = |def: Def| {
649 let msg = format!("expected tuple struct/variant, found {} `{}`",
651 hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false)));
652 struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
653 .span_label(pat.span, "not a tuple variant or struct").emit();
657 // Resolve the path and check the definition for errors.
658 let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span);
659 let variant = match def {
661 self.set_tainted_by_errors();
663 return tcx.types.err;
665 Def::AssociatedConst(..) | Def::Method(..) => {
666 report_unexpected_def(def);
667 return tcx.types.err;
669 Def::VariantCtor(_, CtorKind::Fn) |
670 Def::StructCtor(_, CtorKind::Fn) => {
671 tcx.expect_variant_def(def)
673 _ => bug!("unexpected pattern definition: {:?}", def)
676 // Type check the path.
677 let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
678 // Replace constructor type with constructed type for tuple struct patterns.
679 let pat_ty = pat_ty.fn_sig(tcx).output();
680 let pat_ty = tcx.no_late_bound_regions(&pat_ty).expect("expected fn type");
681 self.demand_eqtype(pat.span, expected, pat_ty);
683 // Type check subpatterns.
684 if subpats.len() == variant.fields.len() ||
685 subpats.len() < variant.fields.len() && ddpos.is_some() {
686 let substs = match pat_ty.sty {
687 ty::TyAdt(_, substs) => substs,
688 ref ty => bug!("unexpected pattern type {:?}", ty),
690 for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
691 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
692 self.check_pat(&subpat, field_ty);
694 self.tcx.check_stability(variant.fields[i].did, pat.id, subpat.span);
697 let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
698 let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
699 struct_span_err!(tcx.sess, pat.span, E0023,
700 "this pattern has {} field{}, but the corresponding {} has {} field{}",
701 subpats.len(), subpats_ending, def.kind_name(),
702 variant.fields.len(), fields_ending)
703 .span_label(pat.span, format!("expected {} field{}, found {}",
704 variant.fields.len(), fields_ending, subpats.len()))
707 return tcx.types.err;
712 fn check_struct_pat_fields(&self,
716 variant: &'tcx ty::VariantDef,
717 fields: &'gcx [Spanned<hir::FieldPat>],
721 let (substs, kind_name) = match adt_ty.sty {
722 ty::TyAdt(adt, substs) => (substs, adt.variant_descr()),
723 _ => span_bug!(span, "struct pattern is not an ADT")
726 // Index the struct fields' types.
727 let field_map = variant.fields
729 .map(|field| (field.name, field))
730 .collect::<FxHashMap<_, _>>();
732 // Keep track of which fields have already appeared in the pattern.
733 let mut used_fields = FxHashMap();
735 // Typecheck each field.
736 for &Spanned { node: ref field, span } in fields {
737 let field_ty = match used_fields.entry(field.name) {
738 Occupied(occupied) => {
739 struct_span_err!(tcx.sess, span, E0025,
740 "field `{}` bound multiple times \
744 format!("multiple uses of `{}` in pattern", field.name))
745 .span_label(*occupied.get(), format!("first use of `{}`", field.name))
751 field_map.get(&field.name)
753 self.tcx.check_stability(f.did, pat_id, span);
755 self.field_ty(span, f, substs)
758 struct_span_err!(tcx.sess, span, E0026,
759 "{} `{}` does not have a field named `{}`",
761 tcx.item_path_str(variant.did),
764 format!("{} `{}` does not have field `{}`",
766 tcx.item_path_str(variant.did),
775 self.check_pat(&field.pat, field_ty);
778 // Report an error if incorrect number of the fields were specified.
779 if kind_name == "union" {
780 if fields.len() != 1 {
781 tcx.sess.span_err(span, "union patterns should have exactly one field");
784 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
787 for field in variant.fields
789 .filter(|field| !used_fields.contains_key(&field.name)) {
790 struct_span_err!(tcx.sess, span, E0027,
791 "pattern does not mention field `{}`",
793 .span_label(span, format!("missing field `{}`", field.name))