]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/pat.rs
typeck/pat.rs: dedup in `check_pat_box`.
[rust.git] / src / librustc_typeck / check / pat.rs
1 use crate::check::FnCtxt;
2 use crate::util::nodemap::FxHashMap;
3 use errors::{Applicability, DiagnosticBuilder};
4 use rustc::hir::{self, PatKind, Pat, HirId};
5 use rustc::hir::def::{Res, DefKind, CtorKind};
6 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
7 use rustc::hir::ptr::P;
8 use rustc::infer;
9 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
10 use rustc::ty::{self, Ty, BindingMode, TypeFoldable};
11 use rustc::ty::subst::Kind;
12 use syntax::ast;
13 use syntax::util::lev_distance::find_best_match_for_name;
14 use syntax_pos::Span;
15 use syntax_pos::hygiene::DesugaringKind;
16
17 use std::collections::hash_map::Entry::{Occupied, Vacant};
18 use std::cmp;
19
20 use super::report_unexpected_variant_res;
21
22 const CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ: &str = "\
23 This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
24 pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
25 this type has no compile-time size. Therefore, all accesses to trait types must be through \
26 pointers. If you encounter this error you should try to avoid dereferencing the pointer.
27
28 You can read more about trait objects in the Trait Objects section of the Reference: \
29 https://doc.rust-lang.org/reference/types.html#trait-objects";
30
31 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32     pub fn check_pat_top(&self, pat: &'tcx Pat, expected: Ty<'tcx>, discrim_span: Option<Span>) {
33         let def_bm = BindingMode::BindByValue(hir::Mutability::MutImmutable);
34         self.check_pat(pat, expected, def_bm, discrim_span);
35     }
36
37     /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
38     /// expression arm guard, and it points to the match discriminant to add context in type errors.
39     /// In the following example, `discrim_span` corresponds to the `a + b` expression:
40     ///
41     /// ```text
42     /// error[E0308]: mismatched types
43     ///  --> src/main.rs:5:9
44     ///   |
45     /// 4 |    let temp: usize = match a + b {
46     ///   |                            ----- this expression has type `usize`
47     /// 5 |         Ok(num) => num,
48     ///   |         ^^^^^^^ expected usize, found enum `std::result::Result`
49     ///   |
50     ///   = note: expected type `usize`
51     ///              found type `std::result::Result<_, _>`
52     /// ```
53     fn check_pat(
54         &self,
55         pat: &'tcx Pat,
56         expected: Ty<'tcx>,
57         def_bm: BindingMode,
58         discrim_span: Option<Span>,
59     ) {
60         debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
61
62         let path_resolution = match &pat.node {
63             PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
64             _ => None,
65         };
66         let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
67         let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp);
68
69         let ty = match &pat.node {
70             PatKind::Wild => expected,
71             PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span),
72             PatKind::Range(begin, end, _) => {
73                 match self.check_pat_range(pat.span, begin, end, expected, discrim_span) {
74                     None => return,
75                     Some(ty) => ty,
76                 }
77             }
78             PatKind::Binding(ba, var_id, _, sub) => {
79                 let sub = sub.as_deref();
80                 self.check_pat_ident(pat, *ba, *var_id, sub, expected, def_bm, discrim_span)
81             }
82             PatKind::TupleStruct(qpath, subpats, ddpos) => {
83                 self.check_pat_tuple_struct(
84                     pat,
85                     qpath,
86                     subpats,
87                     *ddpos,
88                     expected,
89                     def_bm,
90                     discrim_span,
91                 )
92             }
93             PatKind::Path(qpath) => {
94                 self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
95             }
96             PatKind::Struct(qpath, fields, etc) => {
97                 self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span)
98             }
99             PatKind::Or(pats) => {
100                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
101                 for pat in pats {
102                     self.check_pat(pat, expected, def_bm, discrim_span);
103                 }
104                 expected_ty
105             }
106             PatKind::Tuple(elements, ddpos) => {
107                 self.check_pat_tuple(pat.span, elements, *ddpos, expected, def_bm, discrim_span)
108             }
109             PatKind::Box(inner) => {
110                 self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
111             }
112             PatKind::Ref(inner, mutbl) => {
113                 self.check_pat_ref(pat, inner, *mutbl, expected, def_bm, discrim_span)
114             }
115             PatKind::Slice(before, slice, after) => {
116                 let slice = slice.as_deref();
117                 self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span)
118             }
119         };
120
121         self.write_ty(pat.hir_id, ty);
122
123         // (note_1): In most of the cases where (note_1) is referenced
124         // (literals and constants being the exception), we relate types
125         // using strict equality, even though subtyping would be sufficient.
126         // There are a few reasons for this, some of which are fairly subtle
127         // and which cost me (nmatsakis) an hour or two debugging to remember,
128         // so I thought I'd write them down this time.
129         //
130         // 1. There is no loss of expressiveness here, though it does
131         // cause some inconvenience. What we are saying is that the type
132         // of `x` becomes *exactly* what is expected. This can cause unnecessary
133         // errors in some cases, such as this one:
134         //
135         // ```
136         // fn foo<'x>(x: &'x int) {
137         //    let a = 1;
138         //    let mut z = x;
139         //    z = &a;
140         // }
141         // ```
142         //
143         // The reason we might get an error is that `z` might be
144         // assigned a type like `&'x int`, and then we would have
145         // a problem when we try to assign `&a` to `z`, because
146         // the lifetime of `&a` (i.e., the enclosing block) is
147         // shorter than `'x`.
148         //
149         // HOWEVER, this code works fine. The reason is that the
150         // expected type here is whatever type the user wrote, not
151         // the initializer's type. In this case the user wrote
152         // nothing, so we are going to create a type variable `Z`.
153         // Then we will assign the type of the initializer (`&'x
154         // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
155         // will instantiate `Z` as a type `&'0 int` where `'0` is
156         // a fresh region variable, with the constraint that `'x :
157         // '0`.  So basically we're all set.
158         //
159         // Note that there are two tests to check that this remains true
160         // (`regions-reassign-{match,let}-bound-pointer.rs`).
161         //
162         // 2. Things go horribly wrong if we use subtype. The reason for
163         // THIS is a fairly subtle case involving bound regions. See the
164         // `givens` field in `region_constraints`, as well as the test
165         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
166         // for details. Short version is that we must sometimes detect
167         // relationships between specific region variables and regions
168         // bound in a closure signature, and that detection gets thrown
169         // off when we substitute fresh region variables here to enable
170         // subtyping.
171     }
172
173     /// Compute the new expected type and default binding mode from the old ones
174     /// as well as the pattern form we are currently checking.
175     fn calc_default_binding_mode(
176         &self,
177         pat: &'tcx Pat,
178         expected: Ty<'tcx>,
179         def_bm: BindingMode,
180         is_non_ref_pat: bool,
181     ) -> (Ty<'tcx>, BindingMode) {
182         if is_non_ref_pat {
183             debug!("pattern is non reference pattern");
184             self.peel_off_references(pat, expected, def_bm)
185         } else {
186             // When you encounter a `&pat` pattern, reset to "by
187             // value". This is so that `x` and `y` here are by value,
188             // as they appear to be:
189             //
190             // ```
191             // match &(&22, &44) {
192             //   (&x, &y) => ...
193             // }
194             // ```
195             //
196             // See issue #46688.
197             let def_bm = match pat.node {
198                 PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
199                 _ => def_bm,
200             };
201             (expected, def_bm)
202         }
203     }
204
205     /// Is the pattern a "non reference pattern"?
206     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
207     fn is_non_ref_pat(&self, pat: &'tcx Pat, opt_path_res: Option<Res>) -> bool {
208         match pat.node {
209             PatKind::Struct(..) |
210             PatKind::TupleStruct(..) |
211             PatKind::Or(_) |
212             PatKind::Tuple(..) |
213             PatKind::Box(_) |
214             PatKind::Range(..) |
215             PatKind::Slice(..) => true,
216             PatKind::Lit(ref lt) => {
217                 let ty = self.check_expr(lt);
218                 match ty.sty {
219                     ty::Ref(..) => false,
220                     _ => true,
221                 }
222             }
223             PatKind::Path(_) => {
224                 match opt_path_res.unwrap() {
225                     Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
226                     _ => true,
227                 }
228             }
229             PatKind::Wild |
230             PatKind::Binding(..) |
231             PatKind::Ref(..) => false,
232         }
233     }
234
235     /// Peel off as many immediately nested `& mut?` from the expected type as possible
236     /// and return the new expected type and binding default binding mode.
237     /// The adjustments vector, if non-empty is stored in a table.
238     fn peel_off_references(
239         &self,
240         pat: &'tcx Pat,
241         expected: Ty<'tcx>,
242         mut def_bm: BindingMode,
243     ) -> (Ty<'tcx>, BindingMode) {
244         let mut expected = self.resolve_type_vars_with_obligations(&expected);
245
246         // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
247         // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
248         // the `Some(5)` which is not of type Ref.
249         //
250         // For each ampersand peeled off, update the binding mode and push the original
251         // type into the adjustments vector.
252         //
253         // See the examples in `ui/match-defbm*.rs`.
254         let mut pat_adjustments = vec![];
255         while let ty::Ref(_, inner_ty, inner_mutability) = expected.sty {
256             debug!("inspecting {:?}", expected);
257
258             debug!("current discriminant is Ref, inserting implicit deref");
259             // Preserve the reference type. We'll need it later during HAIR lowering.
260             pat_adjustments.push(expected);
261
262             expected = inner_ty;
263             def_bm = ty::BindByReference(match def_bm {
264                 // If default binding mode is by value, make it `ref` or `ref mut`
265                 // (depending on whether we observe `&` or `&mut`).
266                 ty::BindByValue(_) |
267                 // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
268                 ty::BindByReference(hir::Mutability::MutMutable) => inner_mutability,
269                 // Once a `ref`, always a `ref`.
270                 // This is because a `& &mut` cannot mutate the underlying value.
271                 ty::BindByReference(m @ hir::Mutability::MutImmutable) => m,
272             });
273         }
274
275         if pat_adjustments.len() > 0 {
276             debug!("default binding mode is now {:?}", def_bm);
277             self.inh.tables.borrow_mut()
278                 .pat_adjustments_mut()
279                 .insert(pat.hir_id, pat_adjustments);
280         }
281
282         (expected, def_bm)
283     }
284
285     fn check_pat_lit(
286         &self,
287         span: Span,
288         lt: &hir::Expr,
289         expected: Ty<'tcx>,
290         discrim_span: Option<Span>,
291     ) -> Ty<'tcx> {
292         // We've already computed the type above (when checking for a non-ref pat),
293         // so avoid computing it again.
294         let ty = self.node_ty(lt.hir_id);
295
296         // Byte string patterns behave the same way as array patterns
297         // They can denote both statically and dynamically-sized byte arrays.
298         let mut pat_ty = ty;
299         if let hir::ExprKind::Lit(ref lt) = lt.node {
300             if let ast::LitKind::ByteStr(_) = lt.node {
301                 let expected_ty = self.structurally_resolved_type(span, expected);
302                 if let ty::Ref(_, r_ty, _) = expected_ty.sty {
303                     if let ty::Slice(_) = r_ty.sty {
304                         let tcx = self.tcx;
305                         pat_ty = tcx.mk_imm_ref(
306                             tcx.lifetimes.re_static,
307                             tcx.mk_slice(tcx.types.u8),
308                         );
309                     }
310                 }
311             }
312         }
313
314         // Somewhat surprising: in this case, the subtyping relation goes the
315         // opposite way as the other cases. Actually what we really want is not
316         // a subtyping relation at all but rather that there exists a LUB
317         // (so that they can be compared). However, in practice, constants are
318         // always scalars or strings. For scalars subtyping is irrelevant,
319         // and for strings `ty` is type is `&'static str`, so if we say that
320         //
321         //     &'static str <: expected
322         //
323         // then that's equivalent to there existing a LUB.
324         if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
325             err.emit_unless(discrim_span
326                 .filter(|&s| {
327                     // In the case of `if`- and `while`-expressions we've already checked
328                     // that `scrutinee: bool`. We know that the pattern is `true`,
329                     // so an error here would be a duplicate and from the wrong POV.
330                     s.is_desugaring(DesugaringKind::CondTemporary)
331                 })
332                 .is_some());
333         }
334
335         pat_ty
336     }
337
338     fn check_pat_range(
339         &self,
340         span: Span,
341         begin: &'tcx hir::Expr,
342         end: &'tcx hir::Expr,
343         expected: Ty<'tcx>,
344         discrim_span: Option<Span>,
345     ) -> Option<Ty<'tcx>> {
346         let lhs_ty = self.check_expr(begin);
347         let rhs_ty = self.check_expr(end);
348
349         // Check that both end-points are of numeric or char type.
350         let numeric_or_char = |ty: Ty<'_>| {
351             ty.is_numeric()
352             || ty.is_char()
353             || ty.references_error()
354         };
355         let lhs_compat = numeric_or_char(lhs_ty);
356         let rhs_compat = numeric_or_char(rhs_ty);
357
358         if !lhs_compat || !rhs_compat {
359             let span = if !lhs_compat && !rhs_compat {
360                 span
361             } else if !lhs_compat {
362                 begin.span
363             } else {
364                 end.span
365             };
366
367             let mut err = struct_span_err!(
368                 self.tcx.sess,
369                 span,
370                 E0029,
371                 "only char and numeric types are allowed in range patterns"
372             );
373             err.span_label(span, "ranges require char or numeric types");
374             err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
375             err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
376             if self.tcx.sess.teach(&err.get_code().unwrap()) {
377                 err.note(
378                     "In a match expression, only numbers and characters can be matched \
379                         against a range. This is because the compiler checks that the range \
380                         is non-empty at compile-time, and is unable to evaluate arbitrary \
381                         comparison functions. If you want to capture values of an orderable \
382                         type between two end-points, you can use a guard."
383                     );
384             }
385             err.emit();
386             return None;
387         }
388
389         // Now that we know the types can be unified we find the unified type and use
390         // it to type the entire expression.
391         let common_type = self.resolve_vars_if_possible(&lhs_ty);
392
393         // Subtyping doesn't matter here, as the value is some kind of scalar.
394         self.demand_eqtype_pat(span, expected, lhs_ty, discrim_span);
395         self.demand_eqtype_pat(span, expected, rhs_ty, discrim_span);
396         Some(common_type)
397     }
398
399     fn check_pat_ident(
400         &self,
401         pat: &Pat,
402         ba: hir::BindingAnnotation,
403         var_id: HirId,
404         sub: Option<&'tcx Pat>,
405         expected: Ty<'tcx>,
406         def_bm: BindingMode,
407         discrim_span: Option<Span>,
408     ) -> Ty<'tcx> {
409         // Determine the binding mode...
410         let bm = match ba {
411             hir::BindingAnnotation::Unannotated => def_bm,
412             _ => BindingMode::convert(ba),
413         };
414         // ...and store it in a side table:
415         self.inh
416             .tables
417             .borrow_mut()
418             .pat_binding_modes_mut()
419             .insert(pat.hir_id, bm);
420
421         debug!("check_pat_ident: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
422
423         let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
424         let eq_ty = match bm {
425             ty::BindByReference(mutbl) => {
426                 // If the binding is like `ref x | ref const x | ref mut x`
427                 // then `x` is assigned a value of type `&M T` where M is the
428                 // mutability and T is the expected type.
429                 let region_ty = self.new_ref_ty(pat.span, mutbl, expected);
430
431                 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
432                 // is required. However, we use equality, which is stronger.
433                 // See (note_1) for an explanation.
434                 region_ty
435             }
436             // Otherwise, the type of x is the expected type `T`.
437             ty::BindByValue(_) => {
438                 // As above, `T <: typeof(x)` is required, but we use equality, see (note_1).
439                 expected
440             }
441         };
442         self.demand_eqtype_pat(pat.span, eq_ty, local_ty, discrim_span);
443
444         // If there are multiple arms, make sure they all agree on
445         // what the type of the binding `x` ought to be.
446         if var_id != pat.hir_id {
447             let vt = self.local_ty(pat.span, var_id).decl_ty;
448             self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
449         }
450
451         if let Some(p) = sub {
452             self.check_pat(&p, expected, def_bm, discrim_span);
453         }
454
455         local_ty
456     }
457
458     fn borrow_pat_suggestion(
459         &self,
460         err: &mut DiagnosticBuilder<'_>,
461         pat: &Pat,
462         inner: &Pat,
463         expected: Ty<'tcx>,
464     ) {
465         let tcx = self.tcx;
466         if let PatKind::Binding(..) = inner.node {
467             let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
468             let binding_parent = tcx.hir().get(binding_parent_id);
469             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
470             match binding_parent {
471                 hir::Node::Arg(hir::Arg { span, .. }) => {
472                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
473                         err.span_suggestion(
474                             *span,
475                             &format!("did you mean `{}`", snippet),
476                             format!(" &{}", expected),
477                             Applicability::MachineApplicable,
478                         );
479                     }
480                 }
481                 hir::Node::Arm(_) |
482                 hir::Node::Pat(_) => {
483                     // rely on match ergonomics or it might be nested `&&pat`
484                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
485                         err.span_suggestion(
486                             pat.span,
487                             "you can probably remove the explicit borrow",
488                             snippet,
489                             Applicability::MaybeIncorrect,
490                         );
491                     }
492                 }
493                 _ => {} // don't provide suggestions in other cases #55175
494             }
495         }
496     }
497
498     pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat) -> bool {
499         if let PatKind::Binding(..) = inner.node {
500             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
501                 if let ty::Dynamic(..) = mt.ty.sty {
502                     // This is "x = SomeTrait" being reduced from
503                     // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
504                     let type_str = self.ty_to_string(expected);
505                     let mut err = struct_span_err!(
506                         self.tcx.sess,
507                         span,
508                         E0033,
509                         "type `{}` cannot be dereferenced",
510                         type_str
511                     );
512                     err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
513                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
514                         err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
515                     }
516                     err.emit();
517                     return false
518                 }
519             }
520         }
521         true
522     }
523
524     fn check_pat_struct(
525         &self,
526         pat: &'tcx Pat,
527         qpath: &hir::QPath,
528         fields: &'tcx [hir::FieldPat],
529         etc: bool,
530         expected: Ty<'tcx>,
531         def_bm: BindingMode,
532         discrim_span: Option<Span>,
533     ) -> Ty<'tcx> {
534         // Resolve the path and check the definition for errors.
535         let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
536         {
537             variant_ty
538         } else {
539             for field in fields {
540                 self.check_pat(&field.pat, self.tcx.types.err, def_bm, discrim_span);
541             }
542             return self.tcx.types.err;
543         };
544
545         // Type-check the path.
546         self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
547
548         // Type-check subpatterns.
549         if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
550         {
551             pat_ty
552         } else {
553             self.tcx.types.err
554         }
555     }
556
557     fn check_pat_path(
558         &self,
559         pat: &Pat,
560         path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment]),
561         qpath: &hir::QPath,
562         expected: Ty<'tcx>,
563     ) -> Ty<'tcx> {
564         let tcx = self.tcx;
565
566         // We have already resolved the path.
567         let (res, opt_ty, segments) = path_resolution;
568         match res {
569             Res::Err => {
570                 self.set_tainted_by_errors();
571                 return tcx.types.err;
572             }
573             Res::Def(DefKind::Method, _) |
574             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
575             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
576                 report_unexpected_variant_res(tcx, res, pat.span, qpath);
577                 return tcx.types.err;
578             }
579             Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
580             Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
581             _ => bug!("unexpected pattern resolution: {:?}", res)
582         }
583
584         // Type-check the path.
585         let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
586         self.demand_suptype(pat.span, expected, pat_ty);
587         pat_ty
588     }
589
590     fn check_pat_tuple_struct(
591         &self,
592         pat: &Pat,
593         qpath: &hir::QPath,
594         subpats: &'tcx [P<Pat>],
595         ddpos: Option<usize>,
596         expected: Ty<'tcx>,
597         def_bm: BindingMode,
598         match_arm_pat_span: Option<Span>,
599     ) -> Ty<'tcx> {
600         let tcx = self.tcx;
601         let on_error = || {
602             for pat in subpats {
603                 self.check_pat(&pat, tcx.types.err, def_bm, match_arm_pat_span);
604             }
605         };
606         let report_unexpected_res = |res: Res| {
607             let msg = format!("expected tuple struct/variant, found {} `{}`",
608                               res.descr(),
609                               hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
610             let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
611             match (res, &pat.node) {
612                 (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
613                     err.span_label(pat.span, "`fn` calls are not allowed in patterns");
614                     err.help("for more information, visit \
615                               https://doc.rust-lang.org/book/ch18-00-patterns.html");
616                 }
617                 _ => {
618                     err.span_label(pat.span, "not a tuple variant or struct");
619                 }
620             }
621             err.emit();
622             on_error();
623         };
624
625         // Resolve the path and check the definition for errors.
626         let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
627         if res == Res::Err {
628             self.set_tainted_by_errors();
629             on_error();
630             return self.tcx.types.err;
631         }
632
633         // Type-check the path.
634         let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
635             pat.hir_id);
636         if !pat_ty.is_fn() {
637             report_unexpected_res(res);
638             return tcx.types.err;
639         }
640
641         let variant = match res {
642             Res::Err => {
643                 self.set_tainted_by_errors();
644                 on_error();
645                 return tcx.types.err;
646             }
647             Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
648                 report_unexpected_res(res);
649                 return tcx.types.err;
650             }
651             Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
652                 tcx.expect_variant_res(res)
653             }
654             _ => bug!("unexpected pattern resolution: {:?}", res)
655         };
656
657         // Replace constructor type with constructed type for tuple struct patterns.
658         let pat_ty = pat_ty.fn_sig(tcx).output();
659         let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
660
661         self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
662
663         // Type-check subpatterns.
664         if subpats.len() == variant.fields.len()
665             || subpats.len() < variant.fields.len() && ddpos.is_some()
666         {
667             let substs = match pat_ty.sty {
668                 ty::Adt(_, substs) => substs,
669                 _ => bug!("unexpected pattern type {:?}", pat_ty),
670             };
671             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
672                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
673                 self.check_pat(&subpat, field_ty, def_bm, match_arm_pat_span);
674
675                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
676             }
677         } else {
678             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
679             let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
680             struct_span_err!(tcx.sess, pat.span, E0023,
681                              "this pattern has {} field{}, but the corresponding {} has {} field{}",
682                              subpats.len(), subpats_ending, res.descr(),
683                              variant.fields.len(),  fields_ending)
684                 .span_label(pat.span, format!("expected {} field{}, found {}",
685                                               variant.fields.len(), fields_ending, subpats.len()))
686                 .emit();
687             on_error();
688             return tcx.types.err;
689         }
690         pat_ty
691     }
692
693     fn check_pat_tuple(
694         &self,
695         span: Span,
696         elements: &'tcx [P<Pat>],
697         ddpos: Option<usize>,
698         expected: Ty<'tcx>,
699         def_bm: BindingMode,
700         discrim_span: Option<Span>,
701     ) -> Ty<'tcx> {
702         let tcx = self.tcx;
703         let mut expected_len = elements.len();
704         if ddpos.is_some() {
705             // Require known type only when `..` is present.
706             if let ty::Tuple(ref tys) = self.structurally_resolved_type(span, expected).sty {
707                 expected_len = tys.len();
708             }
709         }
710         let max_len = cmp::max(expected_len, elements.len());
711
712         let element_tys_iter = (0..max_len).map(|_| {
713             Kind::from(self.next_ty_var(
714                 // FIXME: `MiscVariable` for now -- obtaining the span and name information
715                 // from all tuple elements isn't trivial.
716                 TypeVariableOrigin {
717                     kind: TypeVariableOriginKind::TypeInference,
718                     span,
719                 },
720             ))
721         });
722         let element_tys = tcx.mk_substs(element_tys_iter);
723         let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
724         if let Some(mut err) = self.demand_eqtype_diag(span, expected, pat_ty) {
725             err.emit();
726             // Walk subpatterns with an expected type of `err` in this case to silence
727             // further errors being emitted when using the bindings. #50333
728             let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
729             for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
730                 self.check_pat(elem, &tcx.types.err, def_bm, discrim_span);
731             }
732             tcx.mk_tup(element_tys_iter)
733         } else {
734             for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
735                 self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, discrim_span);
736             }
737             pat_ty
738         }
739     }
740
741     fn check_struct_pat_fields(
742         &self,
743         adt_ty: Ty<'tcx>,
744         pat_id: HirId,
745         span: Span,
746         variant: &'tcx ty::VariantDef,
747         fields: &'tcx [hir::FieldPat],
748         etc: bool,
749         def_bm: BindingMode,
750     ) -> bool {
751         let tcx = self.tcx;
752
753         let (substs, adt) = match adt_ty.sty {
754             ty::Adt(adt, substs) => (substs, adt),
755             _ => span_bug!(span, "struct pattern is not an ADT")
756         };
757         let kind_name = adt.variant_descr();
758
759         // Index the struct fields' types.
760         let field_map = variant.fields
761             .iter()
762             .enumerate()
763             .map(|(i, field)| (field.ident.modern(), (i, field)))
764             .collect::<FxHashMap<_, _>>();
765
766         // Keep track of which fields have already appeared in the pattern.
767         let mut used_fields = FxHashMap::default();
768         let mut no_field_errors = true;
769
770         let mut inexistent_fields = vec![];
771         // Typecheck each field.
772         for field in fields {
773             let span = field.span;
774             let ident = tcx.adjust_ident(field.ident, variant.def_id);
775             let field_ty = match used_fields.entry(ident) {
776                 Occupied(occupied) => {
777                     self.error_field_already_bound(span, field.ident, *occupied.get());
778                     no_field_errors = false;
779                     tcx.types.err
780                 }
781                 Vacant(vacant) => {
782                     vacant.insert(span);
783                     field_map.get(&ident)
784                         .map(|(i, f)| {
785                             self.write_field_index(field.hir_id, *i);
786                             self.tcx.check_stability(f.did, Some(pat_id), span);
787                             self.field_ty(span, f, substs)
788                         })
789                         .unwrap_or_else(|| {
790                             inexistent_fields.push(field.ident);
791                             no_field_errors = false;
792                             tcx.types.err
793                         })
794                 }
795             };
796
797             self.check_pat(&field.pat, field_ty, def_bm, None);
798         }
799
800         let mut unmentioned_fields = variant.fields
801                 .iter()
802                 .map(|field| field.ident.modern())
803                 .filter(|ident| !used_fields.contains_key(&ident))
804                 .collect::<Vec<_>>();
805
806         if inexistent_fields.len() > 0 && !variant.recovered {
807             self.error_inexistent_fields(
808                 kind_name,
809                 &inexistent_fields,
810                 &mut unmentioned_fields,
811                 variant
812             );
813         }
814
815         // Require `..` if struct has non_exhaustive attribute.
816         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
817             span_err!(tcx.sess, span, E0638,
818                       "`..` required with {} marked as non-exhaustive",
819                       kind_name);
820         }
821
822         // Report an error if incorrect number of the fields were specified.
823         if kind_name == "union" {
824             if fields.len() != 1 {
825                 tcx.sess.span_err(span, "union patterns should have exactly one field");
826             }
827             if etc {
828                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
829             }
830         } else if !etc && unmentioned_fields.len() > 0 {
831             self.error_unmentioned_fields(span, &unmentioned_fields, variant);
832         }
833         no_field_errors
834     }
835
836     fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
837         struct_span_err!(
838             self.tcx.sess, span, E0025,
839             "field `{}` bound multiple times in the pattern",
840             ident
841         )
842         .span_label(span, format!("multiple uses of `{}` in pattern", ident))
843         .span_label(other_field, format!("first use of `{}`", ident))
844         .emit();
845     }
846
847     fn error_inexistent_fields(
848         &self,
849         kind_name: &str,
850         inexistent_fields: &[ast::Ident],
851         unmentioned_fields: &mut Vec<ast::Ident>,
852         variant: &ty::VariantDef,
853     ) {
854         let tcx = self.tcx;
855         let (field_names, t, plural) = if inexistent_fields.len() == 1 {
856             (format!("a field named `{}`", inexistent_fields[0]), "this", "")
857         } else {
858             (format!("fields named {}",
859                         inexistent_fields.iter()
860                         .map(|ident| format!("`{}`", ident))
861                         .collect::<Vec<String>>()
862                         .join(", ")), "these", "s")
863         };
864         let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
865         let mut err = struct_span_err!(tcx.sess,
866                                         spans,
867                                         E0026,
868                                         "{} `{}` does not have {}",
869                                         kind_name,
870                                         tcx.def_path_str(variant.def_id),
871                                         field_names);
872         if let Some(ident) = inexistent_fields.last() {
873             err.span_label(ident.span,
874                             format!("{} `{}` does not have {} field{}",
875                                     kind_name,
876                                     tcx.def_path_str(variant.def_id),
877                                     t,
878                                     plural));
879             if plural == "" {
880                 let input = unmentioned_fields.iter().map(|field| &field.name);
881                 let suggested_name =
882                     find_best_match_for_name(input, &ident.as_str(), None);
883                 if let Some(suggested_name) = suggested_name {
884                     err.span_suggestion(
885                         ident.span,
886                         "a field with a similar name exists",
887                         suggested_name.to_string(),
888                         Applicability::MaybeIncorrect,
889                     );
890
891                     // we don't want to throw `E0027` in case we have thrown `E0026` for them
892                     unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
893                 }
894             }
895         }
896         if tcx.sess.teach(&err.get_code().unwrap()) {
897             err.note(
898                 "This error indicates that a struct pattern attempted to \
899                     extract a non-existent field from a struct. Struct fields \
900                     are identified by the name used before the colon : so struct \
901                     patterns should resemble the declaration of the struct type \
902                     being matched.\n\n\
903                     If you are using shorthand field patterns but want to refer \
904                     to the struct field by a different name, you should rename \
905                     it explicitly."
906             );
907         }
908         err.emit();
909     }
910
911     fn error_unmentioned_fields(
912         &self,
913         span: Span,
914         unmentioned_fields: &[ast::Ident],
915         variant: &ty::VariantDef,
916     ) {
917         let field_names = if unmentioned_fields.len() == 1 {
918             format!("field `{}`", unmentioned_fields[0])
919         } else {
920             let fields = unmentioned_fields.iter()
921                 .map(|name| format!("`{}`", name))
922                 .collect::<Vec<String>>()
923                 .join(", ");
924             format!("fields {}", fields)
925         };
926         let mut diag = struct_span_err!(
927             self.tcx.sess, span, E0027,
928             "pattern does not mention {}",
929             field_names
930         );
931         diag.span_label(span, format!("missing {}", field_names));
932         if variant.ctor_kind == CtorKind::Fn {
933             diag.note("trying to match a tuple variant with a struct variant pattern");
934         }
935         if self.tcx.sess.teach(&diag.get_code().unwrap()) {
936             diag.note(
937                 "This error indicates that a pattern for a struct fails to specify a \
938                     sub-pattern for every one of the struct's fields. Ensure that each field \
939                     from the struct's definition is mentioned in the pattern, or use `..` to \
940                     ignore unwanted fields."
941             );
942         }
943         diag.emit();
944     }
945
946     fn check_pat_box(
947         &self,
948         span: Span,
949         inner: &'tcx Pat,
950         expected: Ty<'tcx>,
951         def_bm: BindingMode,
952         discrim_span: Option<Span>,
953     ) -> Ty<'tcx> {
954         let tcx = self.tcx;
955         let (box_ty, inner_ty) = if self.check_dereferencable(span, expected, &inner) {
956             // Here, `demand::subtype` is good enough, but I don't
957             // think any errors can be introduced by using `demand::eqtype`.
958             let inner_ty = self.next_ty_var(TypeVariableOrigin {
959                 kind: TypeVariableOriginKind::TypeInference,
960                 span: inner.span,
961             });
962             let box_ty = tcx.mk_box(inner_ty);
963             self.demand_eqtype_pat(span, expected, box_ty, discrim_span);
964             (box_ty, inner_ty)
965         } else {
966             (tcx.types.err, tcx.types.err)
967         };
968         self.check_pat(&inner, inner_ty, def_bm, discrim_span);
969         box_ty
970     }
971
972     fn check_pat_ref(
973         &self,
974         pat: &Pat,
975         inner: &'tcx Pat,
976         mutbl: hir::Mutability,
977         expected: Ty<'tcx>,
978         def_bm: BindingMode,
979         discrim_span: Option<Span>,
980     ) -> Ty<'tcx> {
981         let tcx = self.tcx;
982         let expected = self.shallow_resolve(expected);
983         let (rptr_ty, inner_ty) = if self.check_dereferencable(pat.span, expected, &inner) {
984             // `demand::subtype` would be good enough, but using `eqtype` turns
985             // out to be equally general. See (note_1) for details.
986
987             // Take region, inner-type from expected type if we can,
988             // to avoid creating needless variables. This also helps with
989             // the bad  interactions of the given hack detailed in (note_1).
990             debug!("check_pat_ref: expected={:?}", expected);
991             match expected.sty {
992                 ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
993                 _ => {
994                     let inner_ty = self.next_ty_var(
995                         TypeVariableOrigin {
996                             kind: TypeVariableOriginKind::TypeInference,
997                             span: inner.span,
998                         }
999                     );
1000                     let rptr_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
1001                     debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
1002                     let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
1003
1004                     // Look for a case like `fn foo(&foo: u32)` and suggest
1005                     // `fn foo(foo: &u32)`
1006                     if let Some(mut err) = err {
1007                         self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
1008                         err.emit();
1009                     }
1010                     (rptr_ty, inner_ty)
1011                 }
1012             }
1013         } else {
1014             (tcx.types.err, tcx.types.err)
1015         };
1016         self.check_pat(&inner, inner_ty, def_bm, discrim_span);
1017         rptr_ty
1018     }
1019
1020     /// Create a reference type with a fresh region variable.
1021     fn new_ref_ty(&self, span: Span, mutbl: hir::Mutability, ty: Ty<'tcx>) -> Ty<'tcx> {
1022         let region = self.next_region_var(infer::PatternRegion(span));
1023         let mt = ty::TypeAndMut { ty, mutbl };
1024         self.tcx.mk_ref(region, mt)
1025     }
1026
1027     fn check_pat_slice(
1028         &self,
1029         span: Span,
1030         before: &'tcx [P<Pat>],
1031         slice: Option<&'tcx Pat>,
1032         after: &'tcx [P<Pat>],
1033         expected: Ty<'tcx>,
1034         def_bm: BindingMode,
1035         discrim_span: Option<Span>,
1036     ) -> Ty<'tcx> {
1037         let tcx = self.tcx;
1038         let expected_ty = self.structurally_resolved_type(span, expected);
1039         let (inner_ty, slice_ty) = match expected_ty.sty {
1040             ty::Array(inner_ty, size) => {
1041                 let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
1042                     let min_len = before.len() as u64 + after.len() as u64;
1043                     if slice.is_none() {
1044                         if min_len != size {
1045                             self.error_scrutinee_inconsistent_length(span, min_len, size)
1046                         }
1047                         tcx.types.err
1048                     } else if let Some(rest) = size.checked_sub(min_len) {
1049                         tcx.mk_array(inner_ty, rest)
1050                     } else {
1051                         self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size);
1052                         tcx.types.err
1053                     }
1054                 } else {
1055                     self.error_scrutinee_unfixed_length(span);
1056                     tcx.types.err
1057                 };
1058                 (inner_ty, slice_ty)
1059             }
1060             ty::Slice(inner_ty) => (inner_ty, expected_ty),
1061             _ => {
1062                 if !expected_ty.references_error() {
1063                     self.error_expected_array_or_slice(span, expected_ty);
1064                 }
1065                 (tcx.types.err, tcx.types.err)
1066             }
1067         };
1068
1069         for elt in before {
1070             self.check_pat(&elt, inner_ty, def_bm, discrim_span);
1071         }
1072         if let Some(slice) = slice {
1073             self.check_pat(&slice, slice_ty, def_bm, discrim_span);
1074         }
1075         for elt in after {
1076             self.check_pat(&elt, inner_ty, def_bm, discrim_span);
1077         }
1078         expected_ty
1079     }
1080
1081     fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
1082         struct_span_err!(
1083             self.tcx.sess, span, E0527,
1084             "pattern requires {} elements but array has {}",
1085             min_len, size
1086         )
1087         .span_label(span, format!("expected {} elements", size))
1088         .emit();
1089     }
1090
1091     fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
1092         struct_span_err!(
1093             self.tcx.sess, span, E0528,
1094             "pattern requires at least {} elements but array has {}",
1095             min_len, size
1096         )
1097         .span_label(span, format!("pattern cannot match array of {} elements", size))
1098         .emit();
1099     }
1100
1101     fn error_scrutinee_unfixed_length(&self, span: Span) {
1102         struct_span_err!(
1103             self.tcx.sess, span, E0730,
1104             "cannot pattern-match on an array without a fixed length",
1105         )
1106         .emit();
1107     }
1108
1109     fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>) {
1110         let mut err = struct_span_err!(
1111             self.tcx.sess, span, E0529,
1112             "expected an array or slice, found `{}`",
1113             expected_ty
1114         );
1115         if let ty::Ref(_, ty, _) = expected_ty.sty {
1116             if let ty::Array(..) | ty::Slice(..) = ty.sty {
1117                 err.help("the semantics of slice patterns changed recently; see issue #62254");
1118             }
1119         }
1120         err.span_label(span, format!("pattern cannot match with input type `{}`", expected_ty));
1121         err.emit();
1122     }
1123 }