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