]> git.proxmox.com Git - rustc.git/blame - src/librustc_typeck/check/_match.rs
New upstream version 1.36.0+dfsg1
[rustc.git] / src / librustc_typeck / check / _match.rs
CommitLineData
9fa01778
XL
1use crate::check::{FnCtxt, Expectation, Diverges, Needs};
2use crate::check::coercion::CoerceMany;
3use crate::util::nodemap::FxHashMap;
48663c56
XL
4use errors::{Applicability, DiagnosticBuilder};
5use rustc::hir::{self, PatKind, Pat, ExprKind};
6use rustc::hir::def::{Res, DefKind, CtorKind};
c30ab7b3 7use rustc::hir::pat_util::EnumerateAndAdjustIterator;
476ff2be
SL
8use rustc::infer;
9use rustc::infer::type_variable::TypeVariableOrigin;
48663c56 10use rustc::traits::{ObligationCause, ObligationCauseCode};
2c00a5a8 11use rustc::ty::{self, Ty, TypeFoldable};
48663c56 12use rustc::ty::subst::Kind;
1a4d82fc 13use syntax::ast;
b7449926 14use syntax::source_map::Spanned;
1a4d82fc 15use syntax::ptr::P;
0bf4aa26 16use syntax::util::lev_distance::find_best_match_for_name;
3157f602 17use syntax_pos::Span;
48663c56 18use syntax_pos::hygiene::CompilerDesugaringKind;
0731742a
XL
19
20use std::collections::hash_map::Entry::{Occupied, Vacant};
21use std::cmp;
22
48663c56 23use super::report_unexpected_variant_res;
1a4d82fc 24
3157f602 25impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48663c56
XL
26 /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
27 /// expression arm guard, and it points to the match discriminant to add context in type errors.
28 /// In the following example, `discrim_span` corresponds to the `a + b` expression:
0731742a
XL
29 ///
30 /// ```text
31 /// error[E0308]: mismatched types
32 /// --> src/main.rs:5:9
33 /// |
34 /// 4 | let temp: usize = match a + b {
35 /// | ----- this expression has type `usize`
36 /// 5 | Ok(num) => num,
37 /// | ^^^^^^^ expected usize, found enum `std::result::Result`
38 /// |
39 /// = note: expected type `usize`
40 /// found type `std::result::Result<_, _>`
41 /// ```
ea8adc8c
XL
42 pub fn check_pat_walk(
43 &self,
44 pat: &'gcx hir::Pat,
45 mut expected: Ty<'tcx>,
46 mut def_bm: ty::BindingMode,
48663c56 47 discrim_span: Option<Span>,
0731742a 48 ) {
a7813a04
XL
49 let tcx = self.tcx;
50
0731742a 51 debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
ea8adc8c
XL
52
53 let is_non_ref_pat = match pat.node {
54 PatKind::Struct(..) |
55 PatKind::TupleStruct(..) |
56 PatKind::Tuple(..) |
57 PatKind::Box(_) |
58 PatKind::Range(..) |
59 PatKind::Slice(..) => true,
60 PatKind::Lit(ref lt) => {
61 let ty = self.check_expr(lt);
62 match ty.sty {
b7449926 63 ty::Ref(..) => false,
ea8adc8c
XL
64 _ => true,
65 }
66 }
67 PatKind::Path(ref qpath) => {
48663c56 68 let (def, _, _) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
ea8adc8c 69 match def {
48663c56 70 Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => false,
ea8adc8c
XL
71 _ => true,
72 }
73 }
74 PatKind::Wild |
75 PatKind::Binding(..) |
76 PatKind::Ref(..) => false,
77 };
abe05a73 78 if is_non_ref_pat {
ea8adc8c
XL
79 debug!("pattern is non reference pattern");
80 let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
81
82 // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
83 // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
b7449926 84 // the `Some(5)` which is not of type Ref.
ea8adc8c
XL
85 //
86 // For each ampersand peeled off, update the binding mode and push the original
87 // type into the adjustments vector.
88 //
89 // See the examples in `run-pass/match-defbm*.rs`.
90 let mut pat_adjustments = vec![];
0bf4aa26 91 while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
532ac7d7 92 debug!("inspecting {:?}", exp_ty);
0bf4aa26
XL
93
94 debug!("current discriminant is Ref, inserting implicit deref");
95 // Preserve the reference type. We'll need it later during HAIR lowering.
96 pat_adjustments.push(exp_ty);
97
98 exp_ty = inner_ty;
99 def_bm = match def_bm {
100 // If default binding mode is by value, make it `ref` or `ref mut`
101 // (depending on whether we observe `&` or `&mut`).
102 ty::BindByValue(_) =>
103 ty::BindByReference(inner_mutability),
104
105 // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
106 // the underlying value.
107 ty::BindByReference(hir::Mutability::MutImmutable) =>
108 ty::BindByReference(hir::Mutability::MutImmutable),
109
110 // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
111 // (on `&`).
112 ty::BindByReference(hir::Mutability::MutMutable) =>
113 ty::BindByReference(inner_mutability),
114 };
115 }
116 expected = exp_ty;
117
ea8adc8c 118 if pat_adjustments.len() > 0 {
0531ce1d
XL
119 debug!("default binding mode is now {:?}", def_bm);
120 self.inh.tables.borrow_mut()
121 .pat_adjustments_mut()
122 .insert(pat.hir_id, pat_adjustments);
ea8adc8c 123 }
0531ce1d
XL
124 } else if let PatKind::Ref(..) = pat.node {
125 // When you encounter a `&pat` pattern, reset to "by
126 // value". This is so that `x` and `y` here are by value,
127 // as they appear to be:
128 //
129 // ```
130 // match &(&22, &44) {
131 // (&x, &y) => ...
132 // }
133 // ```
134 //
135 // cc #46688
136 def_bm = ty::BindByValue(hir::MutImmutable);
ea8adc8c
XL
137 }
138
139 // Lose mutability now that we know binding mode and discriminant type.
140 let def_bm = def_bm;
141 let expected = expected;
a7813a04 142
9e0c209e 143 let ty = match pat.node {
a7813a04 144 PatKind::Wild => {
9e0c209e 145 expected
a7813a04
XL
146 }
147 PatKind::Lit(ref lt) => {
ea8adc8c
XL
148 // We've already computed the type above (when checking for a non-ref pat), so
149 // avoid computing it again.
150 let ty = self.node_ty(lt.hir_id);
a7813a04
XL
151
152 // Byte string patterns behave the same way as array patterns
153 // They can denote both statically and dynamically sized byte arrays
9e0c209e 154 let mut pat_ty = ty;
8faf50e0 155 if let hir::ExprKind::Lit(ref lt) = lt.node {
a7813a04
XL
156 if let ast::LitKind::ByteStr(_) = lt.node {
157 let expected_ty = self.structurally_resolved_type(pat.span, expected);
b7449926
XL
158 if let ty::Ref(_, r_ty, _) = expected_ty.sty {
159 if let ty::Slice(_) = r_ty.sty {
48663c56 160 pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
0bf4aa26 161 tcx.mk_slice(tcx.types.u8))
a7813a04 162 }
c34b1796
AL
163 }
164 }
165 }
c34b1796 166
a7813a04
XL
167 // somewhat surprising: in this case, the subtyping
168 // relation goes the opposite way as the other
169 // cases. Actually what we really want is not a subtyping
170 // relation at all but rather that there exists a LUB (so
171 // that they can be compared). However, in practice,
172 // constants are always scalars or strings. For scalars
9e0c209e 173 // subtyping is irrelevant, and for strings `ty` is
a7813a04
XL
174 // type is `&'static str`, so if we say that
175 //
176 // &'static str <: expected
177 //
178 // that's equivalent to there existing a LUB.
48663c56
XL
179 if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
180 err.emit_unless(discrim_span
181 .filter(|&s| s.is_compiler_desugaring(CompilerDesugaringKind::IfTemporary))
182 .is_some());
183 }
184
9e0c209e 185 pat_ty
62682a34 186 }
32a655c1 187 PatKind::Range(ref begin, ref end, _) => {
9e0c209e
SL
188 let lhs_ty = self.check_expr(begin);
189 let rhs_ty = self.check_expr(end);
a7813a04
XL
190
191 // Check that both end-points are of numeric or char type.
9fa01778 192 let numeric_or_char = |ty: Ty<'_>| ty.is_numeric() || ty.is_char();
a7813a04
XL
193 let lhs_compat = numeric_or_char(lhs_ty);
194 let rhs_compat = numeric_or_char(rhs_ty);
195
196 if !lhs_compat || !rhs_compat {
197 let span = if !lhs_compat && !rhs_compat {
198 pat.span
199 } else if !lhs_compat {
200 begin.span
201 } else {
202 end.span
203 };
204
2c00a5a8
XL
205 let mut err = struct_span_err!(
206 tcx.sess,
207 span,
208 E0029,
209 "only char and numeric types are allowed in range patterns"
210 );
211 err.span_label(span, "ranges require char or numeric types");
212 err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
213 err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
214 if tcx.sess.teach(&err.get_code().unwrap()) {
215 err.note(
216 "In a match expression, only numbers and characters can be matched \
217 against a range. This is because the compiler checks that the range \
218 is non-empty at compile-time, and is unable to evaluate arbitrary \
219 comparison functions. If you want to capture values of an orderable \
220 type between two end-points, you can use a guard."
221 );
222 }
223 err.emit();
a7813a04
XL
224 return;
225 }
1a4d82fc 226
a7813a04
XL
227 // Now that we know the types can be unified we find the unified type and use
228 // it to type the entire expression.
229 let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
62682a34 230
a7813a04 231 // subtyping doesn't matter here, as the value is some kind of scalar
48663c56
XL
232 self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
233 self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span);
9e0c209e 234 common_type
1a4d82fc 235 }
532ac7d7 236 PatKind::Binding(ba, var_id, _, ref sub) => {
ea8adc8c
XL
237 let bm = if ba == hir::BindingAnnotation::Unannotated {
238 def_bm
239 } else {
240 ty::BindingMode::convert(ba)
241 };
3b2f2976
XL
242 self.inh
243 .tables
244 .borrow_mut()
245 .pat_binding_modes_mut()
246 .insert(pat.hir_id, bm);
2c912e08 247 debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
532ac7d7 248 let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
a7813a04 249 match bm {
3b2f2976 250 ty::BindByReference(mutbl) => {
a7813a04
XL
251 // if the binding is like
252 // ref x | ref const x | ref mut x
253 // then `x` is assigned a value of type `&M T` where M is the mutability
254 // and T is the expected type.
255 let region_var = self.next_region_var(infer::PatternRegion(pat.span));
256 let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
9e0c209e 257 let region_ty = tcx.mk_ref(region_var, mt);
a7813a04
XL
258
259 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
260 // required. However, we use equality, which is stronger. See (*) for
261 // an explanation.
48663c56 262 self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span);
a7813a04
XL
263 }
264 // otherwise the type of x is the expected type T
3b2f2976 265 ty::BindByValue(_) => {
a7813a04
XL
266 // As above, `T <: typeof(x)` is required but we
267 // use equality, see (*) below.
48663c56 268 self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span);
a7813a04
XL
269 }
270 }
1a4d82fc 271
a7813a04
XL
272 // if there are multiple arms, make sure they all agree on
273 // what the type of the binding `x` ought to be
532ac7d7 274 if var_id != pat.hir_id {
0bf4aa26 275 let vt = self.local_ty(pat.span, var_id).decl_ty;
48663c56 276 self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
3157f602 277 }
1a4d82fc 278
3157f602 279 if let Some(ref p) = *sub {
48663c56 280 self.check_pat_walk(&p, expected, def_bm, discrim_span);
9cc50fc6 281 }
9e0c209e 282
0bf4aa26 283 local_ty
1a4d82fc 284 }
476ff2be 285 PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
0731742a
XL
286 self.check_pat_tuple_struct(
287 pat,
288 qpath,
289 &subpats,
290 ddpos,
291 expected,
292 def_bm,
48663c56 293 discrim_span,
0731742a 294 )
a7813a04 295 }
476ff2be
SL
296 PatKind::Path(ref qpath) => {
297 self.check_pat_path(pat, qpath, expected)
a7813a04 298 }
476ff2be 299 PatKind::Struct(ref qpath, ref fields, etc) => {
48663c56 300 self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
a7813a04 301 }
3157f602
XL
302 PatKind::Tuple(ref elements, ddpos) => {
303 let mut expected_len = elements.len();
304 if ddpos.is_some() {
0731742a 305 // Require known type only when `..` is present.
b7449926 306 if let ty::Tuple(ref tys) =
3157f602
XL
307 self.structurally_resolved_type(pat.span, expected).sty {
308 expected_len = tys.len();
309 }
310 }
311 let max_len = cmp::max(expected_len, elements.len());
312
48663c56 313 let element_tys_iter = (0..max_len).map(|_| {
0731742a
XL
314 // FIXME: `MiscVariable` for now -- obtaining the span and name information
315 // from all tuple elements isn't trivial.
48663c56
XL
316 Kind::from(self.next_ty_var(TypeVariableOrigin::TypeInference(pat.span)))
317 });
318 let element_tys = tcx.mk_substs(element_tys_iter);
b7449926
XL
319 let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
320 if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
321 err.emit();
322 // Walk subpatterns with an expected type of `err` in this case to silence
323 // further errors being emitted when using the bindings. #50333
324 let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
325 for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
48663c56 326 self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
b7449926
XL
327 }
328 tcx.mk_tup(element_tys_iter)
329 } else {
330 for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
48663c56
XL
331 self.check_pat_walk(
332 elem,
333 &element_tys[i].expect_ty(),
334 def_bm,
335 discrim_span,
336 );
b7449926
XL
337 }
338 pat_ty
d9579d0f 339 }
a7813a04
XL
340 }
341 PatKind::Box(ref inner) => {
476ff2be 342 let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));
a7813a04
XL
343 let uniq_ty = tcx.mk_box(inner_ty);
344
345 if self.check_dereferencable(pat.span, expected, &inner) {
346 // Here, `demand::subtype` is good enough, but I don't
347 // think any errors can be introduced by using
348 // `demand::eqtype`.
48663c56
XL
349 self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
350 self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
9e0c209e 351 uniq_ty
d9579d0f 352 } else {
48663c56 353 self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
9e0c209e 354 tcx.types.err
d9579d0f
AL
355 }
356 }
a7813a04
XL
357 PatKind::Ref(ref inner, mutbl) => {
358 let expected = self.shallow_resolve(expected);
359 if self.check_dereferencable(pat.span, expected, &inner) {
360 // `demand::subtype` would be good enough, but using
361 // `eqtype` turns out to be equally general. See (*)
362 // below for details.
363
364 // Take region, inner-type from expected type if we
365 // can, to avoid creating needless variables. This
366 // also helps with the bad interactions of the given
367 // hack detailed in (*) below.
ea8adc8c 368 debug!("check_pat_walk: expected={:?}", expected);
a7813a04 369 let (rptr_ty, inner_ty) = match expected.sty {
b7449926 370 ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
94b46f34 371 (expected, r_ty)
a7813a04
XL
372 }
373 _ => {
476ff2be
SL
374 let inner_ty = self.next_ty_var(
375 TypeVariableOrigin::TypeInference(inner.span));
a7813a04
XL
376 let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
377 let region = self.next_region_var(infer::PatternRegion(pat.span));
9e0c209e 378 let rptr_ty = tcx.mk_ref(region, mt);
ea8adc8c 379 debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
32a655c1
SL
380 let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
381
382 // Look for a case like `fn foo(&foo: u32)` and suggest
383 // `fn foo(foo: &u32)`
384 if let Some(mut err) = err {
48663c56 385 self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
32a655c1
SL
386 err.emit();
387 }
a7813a04
XL
388 (rptr_ty, inner_ty)
389 }
390 };
b039eaaf 391
48663c56 392 self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
9e0c209e 393 rptr_ty
a7813a04 394 } else {
48663c56 395 self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
9e0c209e 396 tcx.types.err
a7813a04
XL
397 }
398 }
c30ab7b3 399 PatKind::Slice(ref before, ref slice, ref after) => {
a7813a04 400 let expected_ty = self.structurally_resolved_type(pat.span, expected);
3157f602 401 let (inner_ty, slice_ty) = match expected_ty.sty {
b7449926 402 ty::Array(inner_ty, size) => {
94b46f34 403 let size = size.unwrap_usize(tcx);
ea8adc8c 404 let min_len = before.len() as u64 + after.len() as u64;
3157f602
XL
405 if slice.is_none() {
406 if min_len != size {
9e0c209e
SL
407 struct_span_err!(
408 tcx.sess, pat.span, E0527,
409 "pattern requires {} elements but array has {}",
410 min_len, size)
0bf4aa26 411 .span_label(pat.span, format!("expected {} elements", size))
9e0c209e 412 .emit();
3157f602
XL
413 }
414 (inner_ty, tcx.types.err)
415 } else if let Some(rest) = size.checked_sub(min_len) {
416 (inner_ty, tcx.mk_array(inner_ty, rest))
417 } else {
9e0c209e
SL
418 struct_span_err!(tcx.sess, pat.span, E0528,
419 "pattern requires at least {} elements but array has {}",
420 min_len, size)
421 .span_label(pat.span,
7cac9316 422 format!("pattern cannot match array of {} elements", size))
9e0c209e 423 .emit();
3157f602 424 (inner_ty, tcx.types.err)
a7813a04 425 }
3157f602 426 }
b7449926 427 ty::Slice(inner_ty) => (inner_ty, expected_ty),
b039eaaf 428 _ => {
3157f602
XL
429 if !expected_ty.references_error() {
430 let mut err = struct_span_err!(
431 tcx.sess, pat.span, E0529,
432 "expected an array or slice, found `{}`",
433 expected_ty);
b7449926 434 if let ty::Ref(_, ty, _) = expected_ty.sty {
3157f602 435 match ty.sty {
b7449926 436 ty::Array(..) | ty::Slice(..) => {
3157f602
XL
437 err.help("the semantics of slice patterns changed \
438 recently; see issue #23121");
439 }
440 _ => {}
441 }
442 }
9e0c209e
SL
443
444 err.span_label( pat.span,
7cac9316 445 format!("pattern cannot match with input type `{}`", expected_ty)
9e0c209e 446 ).emit();
3157f602
XL
447 }
448 (tcx.types.err, tcx.types.err)
b039eaaf
SL
449 }
450 };
451
a7813a04 452 for elt in before {
48663c56 453 self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
a7813a04
XL
454 }
455 if let Some(ref slice) = *slice {
48663c56 456 self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
a7813a04
XL
457 }
458 for elt in after {
48663c56 459 self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
a7813a04 460 }
9e0c209e 461 expected_ty
1a4d82fc 462 }
9e0c209e
SL
463 };
464
3b2f2976 465 self.write_ty(pat.hir_id, ty);
1a4d82fc 466
a7813a04 467 // (*) In most of the cases above (literals and constants being
ea8adc8c 468 // the exception), we relate types using strict equality, even
a7813a04
XL
469 // though subtyping would be sufficient. There are a few reasons
470 // for this, some of which are fairly subtle and which cost me
471 // (nmatsakis) an hour or two debugging to remember, so I thought
472 // I'd write them down this time.
473 //
474 // 1. There is no loss of expressiveness here, though it does
475 // cause some inconvenience. What we are saying is that the type
476 // of `x` becomes *exactly* what is expected. This can cause unnecessary
477 // errors in some cases, such as this one:
a7813a04
XL
478 //
479 // ```
480 // fn foo<'x>(x: &'x int) {
481 // let a = 1;
482 // let mut z = x;
483 // z = &a;
484 // }
485 // ```
486 //
487 // The reason we might get an error is that `z` might be
488 // assigned a type like `&'x int`, and then we would have
489 // a problem when we try to assign `&a` to `z`, because
490 // the lifetime of `&a` (i.e., the enclosing block) is
491 // shorter than `'x`.
492 //
493 // HOWEVER, this code works fine. The reason is that the
494 // expected type here is whatever type the user wrote, not
495 // the initializer's type. In this case the user wrote
496 // nothing, so we are going to create a type variable `Z`.
497 // Then we will assign the type of the initializer (`&'x
498 // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
499 // will instantiate `Z` as a type `&'0 int` where `'0` is
500 // a fresh region variable, with the constraint that `'x :
501 // '0`. So basically we're all set.
502 //
503 // Note that there are two tests to check that this remains true
504 // (`regions-reassign-{match,let}-bound-pointer.rs`).
505 //
506 // 2. Things go horribly wrong if we use subtype. The reason for
507 // THIS is a fairly subtle case involving bound regions. See the
abe05a73 508 // `givens` field in `region_constraints`, as well as the test
a7813a04
XL
509 // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
510 // for details. Short version is that we must sometimes detect
511 // relationships between specific region variables and regions
512 // bound in a closure signature, and that detection gets thrown
513 // off when we substitute fresh region variables here to enable
514 // subtyping.
d9579d0f 515 }
d9579d0f 516
48663c56
XL
517 fn borrow_pat_suggestion(
518 &self,
519 err: &mut DiagnosticBuilder<'_>,
520 pat: &Pat,
521 inner: &Pat,
522 expected: Ty<'tcx>,
523 ) {
524 let tcx = self.tcx;
525 if let PatKind::Binding(..) = inner.node {
526 let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
527 let parent = tcx.hir().get_by_hir_id(parent_id);
528 debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
529 match parent {
530 hir::Node::Item(hir::Item { node: hir::ItemKind::Fn(..), .. }) |
531 hir::Node::ForeignItem(hir::ForeignItem {
532 node: hir::ForeignItemKind::Fn(..), ..
533 }) |
534 hir::Node::TraitItem(hir::TraitItem { node: hir::TraitItemKind::Method(..), .. }) |
535 hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => {
536 // this pat is likely an argument
537 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
538 // FIXME: turn into structured suggestion, will need a span that also
539 // includes the the arg's type.
540 err.help(&format!("did you mean `{}: &{}`?", snippet, expected));
541 }
542 }
543 hir::Node::Expr(hir::Expr { node: hir::ExprKind::Match(..), .. }) |
544 hir::Node::Pat(_) => {
545 // rely on match ergonomics or it might be nested `&&pat`
546 if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
547 err.span_suggestion(
548 pat.span,
549 "you can probably remove the explicit borrow",
550 snippet,
551 Applicability::MaybeIncorrect,
552 );
553 }
554 }
555 _ => {} // don't provide suggestions in other cases #55175
556 }
557 }
558 }
559
a7813a04 560 pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
3157f602 561 if let PatKind::Binding(..) = inner.node {
2c00a5a8 562 if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
b7449926 563 if let ty::Dynamic(..) = mt.ty.sty {
a7813a04
XL
564 // This is "x = SomeTrait" being reduced from
565 // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
9e0c209e 566 let type_str = self.ty_to_string(expected);
2c00a5a8
XL
567 let mut err = struct_span_err!(
568 self.tcx.sess,
569 span,
570 E0033,
571 "type `{}` cannot be dereferenced",
572 type_str
573 );
574 err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
575 if self.tcx.sess.teach(&err.get_code().unwrap()) {
576 err.note("\
577This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
578pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
579this type has no compile-time size. Therefore, all accesses to trait types must be through \
580pointers. If you encounter this error you should try to avoid dereferencing the pointer.
581
582You can read more about trait objects in the Trait Objects section of the Reference: \
583https://doc.rust-lang.org/reference/types.html#trait-objects");
584 }
585 err.emit();
3157f602 586 return false
a7813a04 587 }
3157f602 588 }
54a0048b 589 }
3157f602 590 true
a7813a04 591 }
54a0048b 592
0731742a
XL
593 pub fn check_match(
594 &self,
595 expr: &'gcx hir::Expr,
596 discrim: &'gcx hir::Expr,
597 arms: &'gcx [hir::Arm],
598 expected: Expectation<'tcx>,
599 match_src: hir::MatchSource,
600 ) -> Ty<'tcx> {
a7813a04
XL
601 let tcx = self.tcx;
602
48663c56
XL
603 use hir::MatchSource::*;
604 let (source_if, if_no_else, if_desugar) = match match_src {
605 IfDesugar { contains_else_clause } => (true, !contains_else_clause, true),
606 IfLetDesugar { contains_else_clause } => (true, !contains_else_clause, false),
607 _ => (false, false, false),
608 };
609
610 // Type check the descriminant and get its type.
611 let discrim_ty = if if_desugar {
612 // Here we want to ensure:
613 //
614 // 1. That default match bindings are *not* accepted in the condition of an
615 // `if` expression. E.g. given `fn foo() -> &bool;` we reject `if foo() { .. }`.
616 //
617 // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
618 //
619 // FIXME(60707): Consider removing hack with principled solution.
620 self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
54a0048b 621 } else {
48663c56 622 self.demand_discriminant_type(arms, discrim)
54a0048b 623 };
cc61c64b 624
cc61c64b
XL
625 // If there are no arms, that is a diverging match; a special case.
626 if arms.is_empty() {
627 self.diverges.set(self.diverges.get() | Diverges::Always);
628 return tcx.types.never;
629 }
630
48663c56 631 self.warn_arms_when_scrutinee_diverges(arms, source_if);
0bf4aa26 632
cc61c64b
XL
633 // Otherwise, we have to union together the types that the
634 // arms produce and so forth.
476ff2be
SL
635 let discrim_diverges = self.diverges.get();
636 self.diverges.set(Diverges::Maybe);
1a4d82fc 637
13cf67c4
XL
638 // rust-lang/rust#55810: Typecheck patterns first (via eager
639 // collection into `Vec`), so we get types for all bindings.
640 let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
476ff2be 641 let mut all_pats_diverge = Diverges::WarnedAlways;
a7813a04 642 for p in &arm.pats {
476ff2be 643 self.diverges.set(Diverges::Maybe);
48663c56
XL
644 let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
645 self.check_pat_walk(&p, discrim_ty, binding_mode, Some(discrim.span));
476ff2be 646 all_pats_diverge &= self.diverges.get();
a7813a04 647 }
cc61c64b 648
32a655c1
SL
649 // As discussed with @eddyb, this is for disabling unreachable_code
650 // warnings on patterns (they're now subsumed by unreachable_patterns
651 // warnings).
652 match all_pats_diverge {
653 Diverges::Maybe => Diverges::Maybe,
654 Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
655 }
13cf67c4 656 }).collect();
1a4d82fc 657
a7813a04
XL
658 // Now typecheck the blocks.
659 //
660 // The result of the match is the common supertype of all the
661 // arms. Start out the value as bottom, since it's the, well,
662 // bottom the type lattice, and we'll be moving up the lattice as
663 // we process each arm. (Note that any match with 0 arms is matching
664 // on any empty type and is therefore unreachable; should the flow
665 // of execution reach it, we will panic, so bottom is an appropriate
666 // type in that case)
476ff2be 667 let mut all_arms_diverge = Diverges::WarnedAlways;
cc61c64b
XL
668
669 let expected = expected.adjust_for_branches(self);
670
671 let mut coercion = {
672 let coerce_first = match expected {
673 // We don't coerce to `()` so that if the match expression is a
674 // statement it's branches can have any consistent type. That allows
675 // us to give better error messages (pointing to a usually better
676 // arm for inconsistent arms or to the whole match when a `()` type
677 // is required).
b7449926 678 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety,
cc61c64b
XL
679 _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
680 };
681 CoerceMany::with_coercion_sites(coerce_first, arms)
54a0048b 682 };
9e0c209e 683
9fa01778
XL
684 let mut other_arms = vec![]; // used only for diagnostics
685 let mut prior_arm_ty = None;
476ff2be 686 for (i, (arm, pats_diverge)) in arms.iter().zip(all_arm_pats_diverge).enumerate() {
48663c56 687 if let Some(g) = &arm.guard {
476ff2be 688 self.diverges.set(pats_diverge);
b7449926
XL
689 match g {
690 hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
691 };
a7813a04 692 }
476ff2be
SL
693
694 self.diverges.set(pats_diverge);
9e0c209e 695 let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
476ff2be 696 all_arms_diverge &= self.diverges.get();
1a4d82fc 697
48663c56
XL
698 let span = expr.span;
699
700 if source_if {
701 let then_expr = &arms[0].body;
702 match (i, if_no_else) {
703 (0, _) => coercion.coerce(self, &self.misc(span), then_expr, arm_ty),
704 (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
705 (_, _) => {
706 let then_ty = prior_arm_ty.unwrap();
707 let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
708 coercion.coerce(self, &cause, &arm.body, arm_ty);
709 }
a7813a04 710 }
a7813a04 711 } else {
48663c56
XL
712 let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node {
713 // Point at the block expr instead of the entire block
714 blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span)
715 } else {
716 arm.body.span
717 };
718 let (span, code) = match i {
9fa01778
XL
719 // The reason for the first arm to fail is not that the match arms diverge,
720 // but rather that there's a prior obligation that doesn't hold.
48663c56
XL
721 0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
722 _ => (span, ObligationCauseCode::MatchExpressionArm {
9fa01778
XL
723 arm_span,
724 source: match_src,
725 prior_arms: other_arms.clone(),
726 last_ty: prior_arm_ty.unwrap(),
48663c56
XL
727 discrim_hir_id: discrim.hir_id,
728 }),
9fa01778 729 };
48663c56 730 let cause = self.cause(span, code);
94b46f34 731 coercion.coerce(self, &cause, &arm.body, arm_ty);
48663c56
XL
732 other_arms.push(arm_span);
733 if other_arms.len() > 5 {
734 other_arms.remove(0);
735 }
9fa01778
XL
736 }
737 prior_arm_ty = Some(arm_ty);
1a4d82fc 738 }
1a4d82fc 739
476ff2be
SL
740 // We won't diverge unless the discriminant or all arms diverge.
741 self.diverges.set(discrim_diverges | all_arms_diverge);
742
cc61c64b 743 coercion.complete(self)
92a42be0 744 }
92a42be0 745
48663c56
XL
746 /// When the previously checked expression (the scrutinee) diverges,
747 /// warn the user about the match arms being unreachable.
748 fn warn_arms_when_scrutinee_diverges(&self, arms: &'gcx [hir::Arm], source_if: bool) {
749 if self.diverges.get().always() {
750 let msg = if source_if { "block in `if` expression" } else { "arm" };
751 for arm in arms {
752 self.warn_if_unreachable(arm.body.hir_id, arm.body.span, msg);
753 }
754 }
755 }
756
757 /// Handle the fallback arm of a desugared if(-let) like a missing else.
758 fn if_fallback_coercion(
759 &self,
760 span: Span,
761 then_expr: &'gcx hir::Expr,
762 coercion: &mut CoerceMany<'gcx, 'tcx, '_, rustc::hir::Arm>,
763 ) {
764 // If this `if` expr is the parent's function return expr,
765 // the cause of the type coercion is the return type, point at it. (#25228)
766 let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
767 let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
768 coercion.coerce_forced_unit(self, &cause, &mut |err| {
769 if let Some((span, msg)) = &ret_reason {
770 err.span_label(*span, msg.as_str());
771 } else if let ExprKind::Block(block, _) = &then_expr.node {
772 if let Some(expr) = &block.expr {
773 err.span_label(expr.span, "found here".to_string());
774 }
775 }
776 err.note("`if` expressions without `else` evaluate to `()`");
777 err.help("consider adding an `else` block that evaluates to the expected type");
778 }, ret_reason.is_none());
779 }
780
781 fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
782 use hir::Node::{Block, Item, Local};
783
784 let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(
785 self.tcx.hir().get_parent_node_by_hir_id(hir_id),
786 ));
787 if let Block(block) = node {
788 // check that the body's parent is an fn
789 let parent = self.tcx.hir().get_by_hir_id(
790 self.tcx.hir().get_parent_node_by_hir_id(
791 self.tcx.hir().get_parent_node_by_hir_id(block.hir_id),
792 ),
793 );
794 if let (Some(expr), Item(hir::Item {
795 node: hir::ItemKind::Fn(..), ..
796 })) = (&block.expr, parent) {
797 // check that the `if` expr without `else` is the fn body's expr
798 if expr.span == span {
799 return self.get_fn_decl(hir_id).map(|(fn_decl, _)| (
800 fn_decl.output.span(),
801 format!("expected `{}` because of this return type", fn_decl.output),
802 ));
803 }
804 }
805 }
806 if let Local(hir::Local { ty: Some(_), pat, .. }) = node {
807 return Some((pat.span, "expected because of this assignment".to_string()));
808 }
809 None
810 }
811
812 fn if_cause(
813 &self,
814 span: Span,
815 then_expr: &'gcx hir::Expr,
816 else_expr: &'gcx hir::Expr,
817 then_ty: Ty<'tcx>,
818 else_ty: Ty<'tcx>,
819 ) -> ObligationCause<'tcx> {
820 let mut outer_sp = if self.tcx.sess.source_map().is_multiline(span) {
821 // The `if`/`else` isn't in one line in the output, include some context to make it
822 // clear it is an if/else expression:
823 // ```
824 // LL | let x = if true {
825 // | _____________-
826 // LL || 10i32
827 // || ----- expected because of this
828 // LL || } else {
829 // LL || 10u32
830 // || ^^^^^ expected i32, found u32
831 // LL || };
832 // ||_____- if and else have incompatible types
833 // ```
834 Some(span)
835 } else {
836 // The entire expression is in one line, only point at the arms
837 // ```
838 // LL | let x = if true { 10i32 } else { 10u32 };
839 // | ----- ^^^^^ expected i32, found u32
840 // | |
841 // | expected because of this
842 // ```
843 None
844 };
845
846 let mut remove_semicolon = None;
847 let error_sp = if let ExprKind::Block(block, _) = &else_expr.node {
848 if let Some(expr) = &block.expr {
849 expr.span
850 } else if let Some(stmt) = block.stmts.last() {
851 // possibly incorrect trailing `;` in the else arm
852 remove_semicolon = self.could_remove_semicolon(block, then_ty);
853 stmt.span
854 } else { // empty block, point at its entirety
855 // Avoid overlapping spans that aren't as readable:
856 // ```
857 // 2 | let x = if true {
858 // | _____________-
859 // 3 | | 3
860 // | | - expected because of this
861 // 4 | | } else {
862 // | |____________^
863 // 5 | ||
864 // 6 | || };
865 // | || ^
866 // | ||_____|
867 // | |______if and else have incompatible types
868 // | expected integer, found ()
869 // ```
870 // by not pointing at the entire expression:
871 // ```
872 // 2 | let x = if true {
873 // | ------- if and else have incompatible types
874 // 3 | 3
875 // | - expected because of this
876 // 4 | } else {
877 // | ____________^
878 // 5 | |
879 // 6 | | };
880 // | |_____^ expected integer, found ()
881 // ```
882 if outer_sp.is_some() {
883 outer_sp = Some(self.tcx.sess.source_map().def_span(span));
884 }
885 else_expr.span
886 }
887 } else { // shouldn't happen unless the parser has done something weird
888 else_expr.span
889 };
890
891 // Compute `Span` of `then` part of `if`-expression:
892 let then_sp = if let ExprKind::Block(block, _) = &then_expr.node {
893 if let Some(expr) = &block.expr {
894 expr.span
895 } else if let Some(stmt) = block.stmts.last() {
896 // possibly incorrect trailing `;` in the else arm
897 remove_semicolon = remove_semicolon.or(self.could_remove_semicolon(block, else_ty));
898 stmt.span
899 } else { // empty block, point at its entirety
900 outer_sp = None; // same as in `error_sp`, cleanup output
901 then_expr.span
902 }
903 } else { // shouldn't happen unless the parser has done something weird
904 then_expr.span
905 };
906
907 // Finally construct the cause:
908 self.cause(error_sp, ObligationCauseCode::IfExpression {
909 then: then_sp,
910 outer: outer_sp,
911 semicolon: remove_semicolon,
912 })
913 }
914
915 fn demand_discriminant_type(
916 &self,
917 arms: &'gcx [hir::Arm],
918 discrim: &'gcx hir::Expr,
919 ) -> Ty<'tcx> {
920 // Not entirely obvious: if matches may create ref bindings, we want to
921 // use the *precise* type of the discriminant, *not* some supertype, as
922 // the "discriminant type" (issue #23116).
923 //
924 // arielb1 [writes here in this comment thread][c] that there
925 // is certainly *some* potential danger, e.g., for an example
926 // like:
927 //
928 // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
929 //
930 // ```
931 // let Foo(x) = f()[0];
932 // ```
933 //
934 // Then if the pattern matches by reference, we want to match
935 // `f()[0]` as a lexpr, so we can't allow it to be
936 // coerced. But if the pattern matches by value, `f()[0]` is
937 // still syntactically a lexpr, but we *do* want to allow
938 // coercions.
939 //
940 // However, *likely* we are ok with allowing coercions to
941 // happen if there are no explicit ref mut patterns - all
942 // implicit ref mut patterns must occur behind a reference, so
943 // they will have the "correct" variance and lifetime.
944 //
945 // This does mean that the following pattern would be legal:
946 //
947 // ```
948 // struct Foo(Bar);
949 // struct Bar(u32);
950 // impl Deref for Foo {
951 // type Target = Bar;
952 // fn deref(&self) -> &Bar { &self.0 }
953 // }
954 // impl DerefMut for Foo {
955 // fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
956 // }
957 // fn foo(x: &mut Foo) {
958 // {
959 // let Bar(z): &mut Bar = x;
960 // *z = 42;
961 // }
962 // assert_eq!(foo.0.0, 42);
963 // }
964 // ```
965 //
966 // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
967 // is problematic as the HIR is being scraped, but ref bindings may be
968 // implicit after #42640. We need to make sure that pat_adjustments
969 // (once introduced) is populated by the time we get here.
970 //
971 // See #44848.
972 let contains_ref_bindings = arms.iter()
973 .filter_map(|a| a.contains_explicit_ref_binding())
974 .max_by_key(|m| match *m {
975 hir::MutMutable => 1,
976 hir::MutImmutable => 0,
977 });
978
979 if let Some(m) = contains_ref_bindings {
980 self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m))
981 } else {
982 // ...but otherwise we want to use any supertype of the
983 // discriminant. This is sort of a workaround, see note (*) in
984 // `check_pat` for some details.
985 let discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
986 self.check_expr_has_type_or_error(discrim, discrim_ty);
987 discrim_ty
988 }
989 }
990
0731742a
XL
991 fn check_pat_struct(
992 &self,
993 pat: &'gcx hir::Pat,
994 qpath: &hir::QPath,
995 fields: &'gcx [Spanned<hir::FieldPat>],
996 etc: bool,
997 expected: Ty<'tcx>,
998 def_bm: ty::BindingMode,
48663c56 999 discrim_span: Option<Span>,
0731742a 1000 ) -> Ty<'tcx>
5bcae85e
SL
1001 {
1002 // Resolve the path and check the definition for errors.
532ac7d7
XL
1003 let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
1004 {
5bcae85e
SL
1005 variant_ty
1006 } else {
5bcae85e 1007 for field in fields {
48663c56 1008 self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, discrim_span);
9cc50fc6 1009 }
9e0c209e 1010 return self.tcx.types.err;
a7813a04 1011 };
9cc50fc6 1012
0731742a 1013 // Type-check the path.
48663c56 1014 self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
5bcae85e 1015
0731742a 1016 // Type-check subpatterns.
532ac7d7
XL
1017 if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
1018 {
83c7162d
XL
1019 pat_ty
1020 } else {
1021 self.tcx.types.err
1022 }
d9579d0f
AL
1023 }
1024
0731742a
XL
1025 fn check_pat_path(
1026 &self,
1027 pat: &hir::Pat,
1028 qpath: &hir::QPath,
1029 expected: Ty<'tcx>,
1030 ) -> Ty<'tcx> {
a7813a04 1031 let tcx = self.tcx;
1a4d82fc 1032
5bcae85e 1033 // Resolve the path and check the definition for errors.
48663c56
XL
1034 let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1035 match res {
1036 Res::Err => {
5bcae85e 1037 self.set_tainted_by_errors();
9e0c209e 1038 return tcx.types.err;
5bcae85e 1039 }
48663c56
XL
1040 Res::Def(DefKind::Method, _) => {
1041 report_unexpected_variant_res(tcx, res, pat.span, qpath);
0731742a
XL
1042 return tcx.types.err;
1043 }
48663c56
XL
1044 Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
1045 Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1046 report_unexpected_variant_res(tcx, res, pat.span, qpath);
9e0c209e 1047 return tcx.types.err;
5bcae85e 1048 }
48663c56
XL
1049 Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
1050 Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {} // OK
1051 _ => bug!("unexpected pattern resolution: {:?}", res)
1a4d82fc 1052 }
1a4d82fc 1053
0731742a 1054 // Type-check the path.
48663c56 1055 let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
5bcae85e 1056 self.demand_suptype(pat.span, expected, pat_ty);
9e0c209e 1057 pat_ty
5bcae85e 1058 }
7453a54e 1059
0731742a
XL
1060 fn check_pat_tuple_struct(
1061 &self,
1062 pat: &hir::Pat,
1063 qpath: &hir::QPath,
1064 subpats: &'gcx [P<hir::Pat>],
1065 ddpos: Option<usize>,
1066 expected: Ty<'tcx>,
1067 def_bm: ty::BindingMode,
1068 match_arm_pat_span: Option<Span>,
1069 ) -> Ty<'tcx> {
5bcae85e
SL
1070 let tcx = self.tcx;
1071 let on_error = || {
3157f602 1072 for pat in subpats {
0731742a 1073 self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
1a4d82fc 1074 }
a7813a04 1075 };
48663c56 1076 let report_unexpected_res = |res: Res| {
c30ab7b3 1077 let msg = format!("expected tuple struct/variant, found {} `{}`",
48663c56 1078 res.descr(),
0731742a 1079 hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
c30ab7b3 1080 struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
7cac9316 1081 .span_label(pat.span, "not a tuple variant or struct").emit();
c30ab7b3 1082 on_error();
5bcae85e 1083 };
a7813a04 1084
5bcae85e 1085 // Resolve the path and check the definition for errors.
48663c56
XL
1086 let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
1087 if res == Res::Err {
b7449926
XL
1088 self.set_tainted_by_errors();
1089 on_error();
1090 return self.tcx.types.err;
1091 }
1092
0731742a 1093 // Type-check the path.
48663c56 1094 let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
532ac7d7 1095 pat.hir_id);
b7449926 1096 if !pat_ty.is_fn() {
48663c56 1097 report_unexpected_res(res);
b7449926
XL
1098 return self.tcx.types.err;
1099 }
b7449926 1100
48663c56
XL
1101 let variant = match res {
1102 Res::Err => {
5bcae85e
SL
1103 self.set_tainted_by_errors();
1104 on_error();
9e0c209e 1105 return tcx.types.err;
1a4d82fc 1106 }
48663c56
XL
1107 Res::Def(DefKind::AssociatedConst, _) | Res::Def(DefKind::Method, _) => {
1108 report_unexpected_res(res);
9e0c209e 1109 return tcx.types.err;
a7813a04 1110 }
48663c56
XL
1111 Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
1112 tcx.expect_variant_res(res)
a7813a04 1113 }
48663c56 1114 _ => bug!("unexpected pattern resolution: {:?}", res)
5bcae85e 1115 };
13cf67c4
XL
1116
1117 // Replace constructor type with constructed type for tuple struct patterns.
1118 let pat_ty = pat_ty.fn_sig(tcx).output();
a1dfa0c6 1119 let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
13cf67c4 1120
0731742a 1121 self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
13cf67c4 1122
0731742a 1123 // Type-check subpatterns.
3157f602
XL
1124 if subpats.len() == variant.fields.len() ||
1125 subpats.len() < variant.fields.len() && ddpos.is_some() {
5bcae85e 1126 let substs = match pat_ty.sty {
b7449926 1127 ty::Adt(_, substs) => substs,
532ac7d7 1128 _ => bug!("unexpected pattern type {:?}", pat_ty),
5bcae85e 1129 };
3157f602 1130 for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
5bcae85e 1131 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
0731742a 1132 self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
476ff2be 1133
532ac7d7 1134 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
3157f602
XL
1135 }
1136 } else {
c30ab7b3
SL
1137 let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
1138 let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
5bcae85e
SL
1139 struct_span_err!(tcx.sess, pat.span, E0023,
1140 "this pattern has {} field{}, but the corresponding {} has {} field{}",
48663c56 1141 subpats.len(), subpats_ending, res.descr(),
5bcae85e 1142 variant.fields.len(), fields_ending)
7cac9316 1143 .span_label(pat.span, format!("expected {} field{}, found {}",
0bf4aa26 1144 variant.fields.len(), fields_ending, subpats.len()))
5bcae85e
SL
1145 .emit();
1146 on_error();
9e0c209e 1147 return tcx.types.err;
a7813a04 1148 }
9e0c209e 1149 pat_ty
1a4d82fc
JJ
1150 }
1151
532ac7d7
XL
1152 fn check_struct_pat_fields(
1153 &self,
1154 adt_ty: Ty<'tcx>,
1155 pat_id: hir::HirId,
1156 span: Span,
1157 variant: &'tcx ty::VariantDef,
1158 fields: &'gcx [Spanned<hir::FieldPat>],
1159 etc: bool,
1160 def_bm: ty::BindingMode,
1161 ) -> bool {
a7813a04
XL
1162 let tcx = self.tcx;
1163
abe05a73 1164 let (substs, adt) = match adt_ty.sty {
b7449926 1165 ty::Adt(adt, substs) => (substs, adt),
9e0c209e
SL
1166 _ => span_bug!(span, "struct pattern is not an ADT")
1167 };
abe05a73 1168 let kind_name = adt.variant_descr();
9e0c209e 1169
a7813a04
XL
1170 // Index the struct fields' types.
1171 let field_map = variant.fields
1a4d82fc 1172 .iter()
83c7162d 1173 .enumerate()
94b46f34 1174 .map(|(i, field)| (field.ident.modern(), (i, field)))
476ff2be 1175 .collect::<FxHashMap<_, _>>();
a7813a04
XL
1176
1177 // Keep track of which fields have already appeared in the pattern.
0bf4aa26 1178 let mut used_fields = FxHashMap::default();
83c7162d 1179 let mut no_field_errors = true;
a7813a04 1180
0531ce1d 1181 let mut inexistent_fields = vec![];
a7813a04
XL
1182 // Typecheck each field.
1183 for &Spanned { node: ref field, span } in fields {
532ac7d7 1184 let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0;
83c7162d 1185 let field_ty = match used_fields.entry(ident) {
a7813a04 1186 Occupied(occupied) => {
c30ab7b3
SL
1187 struct_span_err!(tcx.sess, span, E0025,
1188 "field `{}` bound multiple times \
1189 in the pattern",
94b46f34 1190 field.ident)
c30ab7b3 1191 .span_label(span,
94b46f34
XL
1192 format!("multiple uses of `{}` in pattern", field.ident))
1193 .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
c30ab7b3 1194 .emit();
83c7162d 1195 no_field_errors = false;
a7813a04
XL
1196 tcx.types.err
1197 }
1198 Vacant(vacant) => {
1199 vacant.insert(span);
83c7162d
XL
1200 field_map.get(&ident)
1201 .map(|(i, f)| {
532ac7d7 1202 self.write_field_index(field.hir_id, *i);
0531ce1d 1203 self.tcx.check_stability(f.did, Some(pat_id), span);
476ff2be
SL
1204 self.field_ty(span, f, substs)
1205 })
a7813a04 1206 .unwrap_or_else(|| {
532ac7d7 1207 inexistent_fields.push(field.ident);
83c7162d 1208 no_field_errors = false;
a7813a04
XL
1209 tcx.types.err
1210 })
1211 }
1212 };
1213
0731742a 1214 self.check_pat_walk(&field.pat, field_ty, def_bm, None);
a7813a04 1215 }
0bf4aa26
XL
1216 let mut unmentioned_fields = variant.fields
1217 .iter()
1218 .map(|field| field.ident.modern())
1219 .filter(|ident| !used_fields.contains_key(&ident))
1220 .collect::<Vec<_>>();
532ac7d7 1221 if inexistent_fields.len() > 0 && !variant.recovered {
0531ce1d 1222 let (field_names, t, plural) = if inexistent_fields.len() == 1 {
532ac7d7 1223 (format!("a field named `{}`", inexistent_fields[0]), "this", "")
0531ce1d
XL
1224 } else {
1225 (format!("fields named {}",
1226 inexistent_fields.iter()
532ac7d7 1227 .map(|ident| format!("`{}`", ident))
0531ce1d
XL
1228 .collect::<Vec<String>>()
1229 .join(", ")), "these", "s")
1230 };
532ac7d7 1231 let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
0531ce1d
XL
1232 let mut err = struct_span_err!(tcx.sess,
1233 spans,
1234 E0026,
1235 "{} `{}` does not have {}",
1236 kind_name,
532ac7d7 1237 tcx.def_path_str(variant.def_id),
0531ce1d 1238 field_names);
532ac7d7
XL
1239 if let Some(ident) = inexistent_fields.last() {
1240 err.span_label(ident.span,
0531ce1d
XL
1241 format!("{} `{}` does not have {} field{}",
1242 kind_name,
532ac7d7 1243 tcx.def_path_str(variant.def_id),
0531ce1d
XL
1244 t,
1245 plural));
0bf4aa26
XL
1246 if plural == "" {
1247 let input = unmentioned_fields.iter().map(|field| &field.name);
1248 let suggested_name =
0731742a 1249 find_best_match_for_name(input, &ident.as_str(), None);
0bf4aa26 1250 if let Some(suggested_name) = suggested_name {
9fa01778 1251 err.span_suggestion(
532ac7d7
XL
1252 ident.span,
1253 "a field with a similar name exists",
9fa01778
XL
1254 suggested_name.to_string(),
1255 Applicability::MaybeIncorrect,
1256 );
1257
0bf4aa26
XL
1258 // we don't want to throw `E0027` in case we have thrown `E0026` for them
1259 unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
1260 }
1261 }
0531ce1d
XL
1262 }
1263 if tcx.sess.teach(&err.get_code().unwrap()) {
1264 err.note(
1265 "This error indicates that a struct pattern attempted to \
1266 extract a non-existent field from a struct. Struct fields \
1267 are identified by the name used before the colon : so struct \
1268 patterns should resemble the declaration of the struct type \
1269 being matched.\n\n\
1270 If you are using shorthand field patterns but want to refer \
1271 to the struct field by a different name, you should rename \
1272 it explicitly."
1273 );
1274 }
1275 err.emit();
1276 }
1277
abe05a73 1278 // Require `..` if struct has non_exhaustive attribute.
b7449926 1279 if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
abe05a73
XL
1280 span_err!(tcx.sess, span, E0638,
1281 "`..` required with {} marked as non-exhaustive",
1282 kind_name);
1283 }
1284
9e0c209e
SL
1285 // Report an error if incorrect number of the fields were specified.
1286 if kind_name == "union" {
1287 if fields.len() != 1 {
1288 tcx.sess.span_err(span, "union patterns should have exactly one field");
1289 }
1290 if etc {
1291 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
1292 }
1293 } else if !etc {
0531ce1d
XL
1294 if unmentioned_fields.len() > 0 {
1295 let field_names = if unmentioned_fields.len() == 1 {
1296 format!("field `{}`", unmentioned_fields[0])
1297 } else {
1298 format!("fields {}",
1299 unmentioned_fields.iter()
1300 .map(|name| format!("`{}`", name))
1301 .collect::<Vec<String>>()
1302 .join(", "))
1303 };
ea8adc8c 1304 let mut diag = struct_span_err!(tcx.sess, span, E0027,
0531ce1d
XL
1305 "pattern does not mention {}",
1306 field_names);
1307 diag.span_label(span, format!("missing {}", field_names));
ea8adc8c
XL
1308 if variant.ctor_kind == CtorKind::Fn {
1309 diag.note("trying to match a tuple variant with a struct variant pattern");
1310 }
2c00a5a8
XL
1311 if tcx.sess.teach(&diag.get_code().unwrap()) {
1312 diag.note(
1313 "This error indicates that a pattern for a struct fails to specify a \
1314 sub-pattern for every one of the struct's fields. Ensure that each field \
1315 from the struct's definition is mentioned in the pattern, or use `..` to \
1316 ignore unwanted fields."
1317 );
1318 }
ea8adc8c 1319 diag.emit();
a7813a04 1320 }
1a4d82fc 1321 }
83c7162d 1322 no_field_errors
1a4d82fc
JJ
1323 }
1324}