diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 4cce8343c02c8..f71cce8273c46 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -487,6 +487,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) { match cause.code { + ObligationCauseCode::MatchExpressionArmPattern { span, ty } => { + if ty.is_suggestable() { // don't show type `_` + err.span_label(span, format!("this match expression has type `{}`", ty)); + } + } ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source { hir::MatchSource::IfLetDesugar { .. } => { let msg = "`if let` arm with an incompatible type"; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7ce5960b9b3d6..7d9e80fd60f5c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1444,6 +1444,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { match *cause_code { ObligationCauseCode::ExprAssignable | ObligationCauseCode::MatchExpressionArm { .. } | + ObligationCauseCode::MatchExpressionArmPattern { .. } | ObligationCauseCode::IfExpression | ObligationCauseCode::IfExpressionWithNoElse | ObligationCauseCode::MainFunctionType | @@ -1451,8 +1452,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ObligationCauseCode::IntrinsicType | ObligationCauseCode::MethodReceiver | ObligationCauseCode::ReturnNoExpression | - ObligationCauseCode::MiscObligation => { - } + ObligationCauseCode::MiscObligation => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b42d742b7f841..14c25b77a1b82 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -220,8 +220,13 @@ pub enum ObligationCauseCode<'tcx> { ExprAssignable, /// Computing common supertype in the arms of a match expression - MatchExpressionArm { arm_span: Span, - source: hir::MatchSource }, + MatchExpressionArm { + arm_span: Span, + source: hir::MatchSource, + }, + + /// Computing common supertype in the pattern guard for the arms of a match expression + MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> }, /// Computing common supertype in an if expression IfExpression, diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index ae2b83e105773..277e2ed0e87d2 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -517,6 +517,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { arm_span, source: source, }), + super::MatchExpressionArmPattern { span, ty } => { + tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty }) + } super::IfExpression => Some(super::IfExpression), super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse), super::MainFunctionType => Some(super::MainFunctionType), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index b66c383edb51e..1767af4870d3b 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -20,21 +20,33 @@ use std::cmp; use super::report_unexpected_variant_def; impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - /// The `is_arg` argument indicates whether this pattern is the - /// *outermost* pattern in an argument (e.g., in `fn foo(&x: - /// &u32)`, it is true for the `&x` pattern but not `x`). This is - /// used to tailor error reporting. + /// `match_discrim_span` argument having a `Span` indicates that this pattern is part of + /// a match expression arm guard, and it points to the match discriminant to add context + /// in type errors. In the folloowing example, `match_discrim_span` corresponds to the + /// `a + b` expression: + /// + /// ```text + /// error[E0308]: mismatched types + /// --> src/main.rs:5:9 + /// | + /// 4 | let temp: usize = match a + b { + /// | ----- this expression has type `usize` + /// 5 | Ok(num) => num, + /// | ^^^^^^^ expected usize, found enum `std::result::Result` + /// | + /// = note: expected type `usize` + /// found type `std::result::Result<_, _>` + /// ``` pub fn check_pat_walk( &self, pat: &'gcx hir::Pat, mut expected: Ty<'tcx>, mut def_bm: ty::BindingMode, - is_arg: bool) - { + match_discrim_span: Option, + ) { let tcx = self.tcx; - debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?},is_arg={})", - pat, expected, def_bm, is_arg); + debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm); let is_non_ref_pat = match pat.node { PatKind::Struct(..) | @@ -210,8 +222,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let common_type = self.resolve_type_vars_if_possible(&lhs_ty); // subtyping doesn't matter here, as the value is some kind of scalar - self.demand_eqtype(pat.span, expected, lhs_ty); - self.demand_eqtype(pat.span, expected, rhs_ty); + self.demand_eqtype_pat(pat.span, expected, lhs_ty, match_discrim_span); + self.demand_eqtype_pat(pat.span, expected, rhs_ty, match_discrim_span); common_type } PatKind::Binding(ba, var_id, _, ref sub) => { @@ -240,13 +252,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is // required. However, we use equality, which is stronger. See (*) for // an explanation. - self.demand_eqtype(pat.span, region_ty, local_ty); + self.demand_eqtype_pat(pat.span, region_ty, local_ty, match_discrim_span); } // otherwise the type of x is the expected type T ty::BindByValue(_) => { // As above, `T <: typeof(x)` is required but we // use equality, see (*) below. - self.demand_eqtype(pat.span, expected, local_ty); + self.demand_eqtype_pat(pat.span, expected, local_ty, match_discrim_span); } } @@ -254,23 +266,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // what the type of the binding `x` ought to be if var_id != pat.id { let vt = self.local_ty(pat.span, var_id).decl_ty; - self.demand_eqtype(pat.span, vt, local_ty); + self.demand_eqtype_pat(pat.span, vt, local_ty, match_discrim_span); } if let Some(ref p) = *sub { - self.check_pat_walk(&p, expected, def_bm, true); + self.check_pat_walk(&p, expected, def_bm, match_discrim_span); } local_ty } PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => { - self.check_pat_tuple_struct(pat, qpath, &subpats, ddpos, expected, def_bm) + self.check_pat_tuple_struct( + pat, + qpath, + &subpats, + ddpos, + expected, + def_bm, + match_discrim_span, + ) } PatKind::Path(ref qpath) => { self.check_pat_path(pat, qpath, expected) } PatKind::Struct(ref qpath, ref fields, etc) => { - self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm) + self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, match_discrim_span) } PatKind::Tuple(ref elements, ddpos) => { let mut expected_len = elements.len(); @@ -295,12 +315,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // further errors being emitted when using the bindings. #50333 let element_tys_iter = (0..max_len).map(|_| tcx.types.err); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat_walk(elem, &tcx.types.err, def_bm, true); + self.check_pat_walk(elem, &tcx.types.err, def_bm, match_discrim_span); } tcx.mk_tup(element_tys_iter) } else { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat_walk(elem, &element_tys[i], def_bm, true); + self.check_pat_walk(elem, &element_tys[i], def_bm, match_discrim_span); } pat_ty } @@ -313,11 +333,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Here, `demand::subtype` is good enough, but I don't // think any errors can be introduced by using // `demand::eqtype`. - self.demand_eqtype(pat.span, expected, uniq_ty); - self.check_pat_walk(&inner, inner_ty, def_bm, true); + self.demand_eqtype_pat(pat.span, expected, uniq_ty, match_discrim_span); + self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span); uniq_ty } else { - self.check_pat_walk(&inner, tcx.types.err, def_bm, true); + self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span); tcx.types.err } } @@ -349,15 +369,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Look for a case like `fn foo(&foo: u32)` and suggest // `fn foo(foo: &u32)` if let Some(mut err) = err { - if is_arg { - if let PatKind::Binding(..) = inner.node { - if let Ok(snippet) = tcx.sess.source_map() - .span_to_snippet(pat.span) - { - err.help(&format!("did you mean `{}: &{}`?", - &snippet[1..], - expected)); - } + if let PatKind::Binding(..) = inner.node { + if let Ok(snippet) = tcx.sess.source_map() + .span_to_snippet(pat.span) + { + err.help(&format!("did you mean `{}: &{}`?", + &snippet[1..], + expected)); } } err.emit(); @@ -366,10 +384,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - self.check_pat_walk(&inner, inner_ty, def_bm, true); + self.check_pat_walk(&inner, inner_ty, def_bm, match_discrim_span); rptr_ty } else { - self.check_pat_walk(&inner, tcx.types.err, def_bm, true); + self.check_pat_walk(&inner, tcx.types.err, def_bm, match_discrim_span); tcx.types.err } } @@ -427,13 +445,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; for elt in before { - self.check_pat_walk(&elt, inner_ty, def_bm, true); + self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span); } if let Some(ref slice) = *slice { - self.check_pat_walk(&slice, slice_ty, def_bm, true); + self.check_pat_walk(&slice, slice_ty, def_bm, match_discrim_span); } for elt in after { - self.check_pat_walk(&elt, inner_ty, def_bm, true); + self.check_pat_walk(&elt, inner_ty, def_bm, match_discrim_span); } expected_ty } @@ -524,12 +542,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); true } - pub fn check_match(&self, - expr: &'gcx hir::Expr, - discrim: &'gcx hir::Expr, - arms: &'gcx [hir::Arm], - expected: Expectation<'tcx>, - match_src: hir::MatchSource) -> Ty<'tcx> { + pub fn check_match( + &self, + expr: &'gcx hir::Expr, + discrim: &'gcx hir::Expr, + arms: &'gcx [hir::Arm], + expected: Expectation<'tcx>, + match_src: hir::MatchSource, + ) -> Ty<'tcx> { let tcx = self.tcx; // Not entirely obvious: if matches may create ref bindings, we want to @@ -624,8 +644,12 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); let mut all_pats_diverge = Diverges::WarnedAlways; for p in &arm.pats { self.diverges.set(Diverges::Maybe); - self.check_pat_walk(&p, discrim_ty, - ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true); + self.check_pat_walk( + &p, + discrim_ty, + ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), + Some(discrim.span), + ); all_pats_diverge &= self.diverges.get(); } @@ -703,26 +727,34 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); coercion.complete(self) } - fn check_pat_struct(&self, - pat: &'gcx hir::Pat, - qpath: &hir::QPath, - fields: &'gcx [Spanned], - etc: bool, - expected: Ty<'tcx>, - def_bm: ty::BindingMode) -> Ty<'tcx> + fn check_pat_struct( + &self, + pat: &'gcx hir::Pat, + qpath: &hir::QPath, + fields: &'gcx [Spanned], + etc: bool, + expected: Ty<'tcx>, + def_bm: ty::BindingMode, + match_discrim_span: Option, + ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.id) { variant_ty } else { for field in fields { - self.check_pat_walk(&field.node.pat, self.tcx.types.err, def_bm, true); + self.check_pat_walk( + &field.node.pat, + self.tcx.types.err, + def_bm, + match_discrim_span, + ); } return self.tcx.types.err; }; // Type-check the path. - self.demand_eqtype(pat.span, expected, pat_ty); + self.demand_eqtype_pat(pat.span, expected, pat_ty, match_discrim_span); // Type-check subpatterns. if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) { @@ -732,11 +764,12 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } } - fn check_pat_path(&self, - pat: &hir::Pat, - qpath: &hir::QPath, - expected: Ty<'tcx>) -> Ty<'tcx> - { + fn check_pat_path( + &self, + pat: &hir::Pat, + qpath: &hir::QPath, + expected: Ty<'tcx>, + ) -> Ty<'tcx> { let tcx = self.tcx; // Resolve the path and check the definition for errors. @@ -767,18 +800,20 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); pat_ty } - fn check_pat_tuple_struct(&self, - pat: &hir::Pat, - qpath: &hir::QPath, - subpats: &'gcx [P], - ddpos: Option, - expected: Ty<'tcx>, - def_bm: ty::BindingMode) -> Ty<'tcx> - { + fn check_pat_tuple_struct( + &self, + pat: &hir::Pat, + qpath: &hir::QPath, + subpats: &'gcx [P], + ddpos: Option, + expected: Ty<'tcx>, + def_bm: ty::BindingMode, + match_arm_pat_span: Option, + ) -> Ty<'tcx> { let tcx = self.tcx; let on_error = || { for pat in subpats { - self.check_pat_walk(&pat, tcx.types.err, def_bm, true); + self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span); } }; let report_unexpected_def = |def: Def| { @@ -826,7 +861,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); let pat_ty = pat_ty.fn_sig(tcx).output(); let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); - self.demand_eqtype(pat.span, expected, pat_ty); + self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span); // Type-check subpatterns. if subpats.len() == variant.fields.len() || @@ -837,7 +872,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); - self.check_pat_walk(&subpat, field_ty, def_bm, true); + self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span); self.tcx.check_stability(variant.fields[i].did, Some(pat.id), subpat.span); } @@ -917,7 +952,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } }; - self.check_pat_walk(&field.pat, field_ty, def_bm, true); + self.check_pat_walk(&field.pat, field_ty, def_bm, None); } let mut unmentioned_fields = variant.fields .iter() diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 41f2b0ec7d24e..c0cedd77440d9 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -1,6 +1,6 @@ use check::FnCtxt; use rustc::infer::InferOk; -use rustc::traits::ObligationCause; +use rustc::traits::{ObligationCause, ObligationCauseCode}; use syntax::ast; use syntax::util::parser::PREC_POSTFIX; @@ -66,6 +66,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } + pub fn demand_eqtype_pat( + &self, + cause_span: Span, + expected: Ty<'tcx>, + actual: Ty<'tcx>, + match_expr_span: Option, + ) { + let cause = if let Some(span) = match_expr_span { + self.cause( + cause_span, + ObligationCauseCode::MatchExpressionArmPattern { span, ty: expected }, + ) + } else { + self.misc(cause_span) + }; + self.demand_eqtype_with_origin(&cause, expected, actual).map(|mut err| err.emit()); + } + + pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1a5d164873d32..438deecbe77d3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1084,8 +1084,12 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, // Add formal parameters. for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) { // Check the pattern. - fcx.check_pat_walk(&arg.pat, arg_ty, - ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), true); + fcx.check_pat_walk( + &arg.pat, + arg_ty, + ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), + None, + ); // Check that argument is Sized. // The check for a non-trivial pattern is a hack to avoid duplicate warnings @@ -4723,9 +4727,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - self.check_pat_walk(&local.pat, t, - ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), - true); + self.check_pat_walk( + &local.pat, + t, + ty::BindingMode::BindByValue(hir::Mutability::MutImmutable), + None, + ); let pat_ty = self.node_ty(local.pat.hir_id); if pat_ty.references_error() { self.write_ty(local.hir_id, pat_ty); diff --git a/src/test/ui/block-result/issue-13624.stderr b/src/test/ui/block-result/issue-13624.stderr index b38633b0ffeea..417667a5354fd 100644 --- a/src/test/ui/block-result/issue-13624.stderr +++ b/src/test/ui/block-result/issue-13624.stderr @@ -12,6 +12,8 @@ LL | Enum::EnumStructVariant { x: 1, y: 2, z: 3 } error[E0308]: mismatched types --> $DIR/issue-13624.rs:22:9 | +LL | match enum_struct_variant { + | ------------------- this match expression has type `()` LL | a::Enum::EnumStructVariant { x, y, z } => { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `a::Enum` | diff --git a/src/test/ui/error-codes/E0308-4.stderr b/src/test/ui/error-codes/E0308-4.stderr index 8117bc754b6b9..f69a389336590 100644 --- a/src/test/ui/error-codes/E0308-4.stderr +++ b/src/test/ui/error-codes/E0308-4.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/E0308-4.rs:4:9 | +LL | match x { + | - this match expression has type `u8` LL | 0u8..=3i8 => (), //~ ERROR E0308 | ^^^^^^^^^ expected u8, found i8 diff --git a/src/test/ui/issues/issue-11844.stderr b/src/test/ui/issues/issue-11844.stderr index 05d2685958eb8..683ad48ff52c0 100644 --- a/src/test/ui/issues/issue-11844.stderr +++ b/src/test/ui/issues/issue-11844.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-11844.rs:6:9 | +LL | match a { + | - this match expression has type `std::option::Option>` LL | Ok(a) => //~ ERROR: mismatched types | ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/issues/issue-12552.stderr index ca5efcdc4726a..768d11bf899a1 100644 --- a/src/test/ui/issues/issue-12552.stderr +++ b/src/test/ui/issues/issue-12552.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-12552.rs:6:5 | +LL | match t { + | - this match expression has type `std::result::Result<_, {integer}>` LL | Some(k) => match k { //~ ERROR mismatched types | ^^^^^^^ expected enum `std::result::Result`, found enum `std::option::Option` | diff --git a/src/test/ui/issues/issue-13466.stderr b/src/test/ui/issues/issue-13466.stderr index 2f60070337b77..66255891f469a 100644 --- a/src/test/ui/issues/issue-13466.stderr +++ b/src/test/ui/issues/issue-13466.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-13466.rs:8:9 | +LL | let _x: usize = match Some(1) { + | ------- this match expression has type `std::option::Option<{integer}>` LL | Ok(u) => u, | ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | @@ -10,6 +12,9 @@ LL | Ok(u) => u, error[E0308]: mismatched types --> $DIR/issue-13466.rs:14:9 | +LL | let _x: usize = match Some(1) { + | ------- this match expression has type `std::option::Option<{integer}>` +... LL | Err(e) => panic!(e) | ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | diff --git a/src/test/ui/issues/issue-15896.stderr b/src/test/ui/issues/issue-15896.stderr index cd629841fee83..de9757d5d32ed 100644 --- a/src/test/ui/issues/issue-15896.stderr +++ b/src/test/ui/issues/issue-15896.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/issue-15896.rs:11:11 | +LL | let u = match e { + | - this match expression has type `main::R` +LL | E::B( LL | Tau{t: x}, | ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau` | diff --git a/src/test/ui/issues/issue-16401.stderr b/src/test/ui/issues/issue-16401.stderr index a1cf6c98705aa..1779d0befd871 100644 --- a/src/test/ui/issues/issue-16401.stderr +++ b/src/test/ui/issues/issue-16401.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-16401.rs:8:9 | +LL | match () { + | -- this match expression has type `()` LL | Slice { data: data, len: len } => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found struct `Slice` | diff --git a/src/test/ui/issues/issue-3680.stderr b/src/test/ui/issues/issue-3680.stderr index 78c3f92fb53b5..51903cfadab15 100644 --- a/src/test/ui/issues/issue-3680.stderr +++ b/src/test/ui/issues/issue-3680.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-3680.rs:3:9 | +LL | match None { + | ---- this match expression has type `std::option::Option<_>` LL | Err(_) => () | ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr index a6f6229fe78d2..0a918a789703e 100644 --- a/src/test/ui/issues/issue-5100.stderr +++ b/src/test/ui/issues/issue-5100.stderr @@ -28,6 +28,8 @@ LL | (true, false, false) => () error[E0308]: mismatched types --> $DIR/issue-5100.rs:33:9 | +LL | match (true, false) { + | ------------- this match expression has type `(bool, bool)` LL | box (true, false) => () | ^^^^^^^^^^^^^^^^^ expected tuple, found struct `std::boxed::Box` | diff --git a/src/test/ui/issues/issue-5358-1.stderr b/src/test/ui/issues/issue-5358-1.stderr index dbbafb38e6580..649a0c1581a68 100644 --- a/src/test/ui/issues/issue-5358-1.stderr +++ b/src/test/ui/issues/issue-5358-1.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-5358-1.rs:6:9 | +LL | match S(Either::Left(5)) { + | ------------------ this match expression has type `S` LL | Either::Right(_) => {} | ^^^^^^^^^^^^^^^^ expected struct `S`, found enum `Either` | diff --git a/src/test/ui/issues/issue-7092.stderr b/src/test/ui/issues/issue-7092.stderr index aa24182e3a39d..7bb6820287487 100644 --- a/src/test/ui/issues/issue-7092.stderr +++ b/src/test/ui/issues/issue-7092.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-7092.rs:6:9 | +LL | match x { + | - this match expression has type `Whatever` LL | Some(field) => | ^^^^^^^^^^^ expected enum `Whatever`, found enum `std::option::Option` | diff --git a/src/test/ui/match/match-struct.stderr b/src/test/ui/match/match-struct.stderr index bad41485a53b1..2a24a293e9836 100644 --- a/src/test/ui/match/match-struct.stderr +++ b/src/test/ui/match/match-struct.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/match-struct.rs:6:9 | +LL | match (S { a: 1 }) { + | ------------ this match expression has type `S` LL | E::C(_) => (), | ^^^^^^^ expected struct `S`, found enum `E` | diff --git a/src/test/ui/match/match-tag-unary.stderr b/src/test/ui/match/match-tag-unary.stderr index c90029b2fa12e..53b6635136966 100644 --- a/src/test/ui/match/match-tag-unary.stderr +++ b/src/test/ui/match/match-tag-unary.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/match-tag-unary.rs:4:43 | LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } //~ ERROR mismatched types - | ^^^^^^^ expected enum `A`, found enum `B` + | - ^^^^^^^ expected enum `A`, found enum `B` + | | + | this match expression has type `A` | = note: expected type `A` found type `B` diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index c17d4b70f0b00..c2810d764c2ce 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -21,6 +21,8 @@ LL | A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:22:9 | +LL | match 'c' { + | --- this match expression has type `char` LL | S { .. } => (), | ^^^^^^^^ expected char, found struct `S` | diff --git a/src/test/ui/pattern/pattern-tyvar.stderr b/src/test/ui/pattern/pattern-tyvar.stderr index dae17fa516610..69cd552aabd1b 100644 --- a/src/test/ui/pattern/pattern-tyvar.stderr +++ b/src/test/ui/pattern/pattern-tyvar.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/pattern-tyvar.rs:5:18 | +LL | match t { + | - this match expression has type `std::option::Option>` LL | Bar::T1(_, Some::(x)) => { //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found isize | diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.stderr b/src/test/ui/structs/structure-constructor-type-mismatch.stderr index 3c1ed8e69a6bd..cc62316bec185 100644 --- a/src/test/ui/structs/structure-constructor-type-mismatch.stderr +++ b/src/test/ui/structs/structure-constructor-type-mismatch.stderr @@ -109,6 +109,8 @@ LL | PointF:: { .. } => {} //~ ERROR wrong number of type arguments error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:54:9 | +LL | match (Point { x: 1, y: 2 }) { + | ---------------------- this match expression has type `Point<{integer}>` LL | PointF:: { .. } => {} //~ ERROR wrong number of type arguments | ^^^^^^^^^^^^^^^^^^^^ expected integer, found f32 | @@ -118,6 +120,8 @@ LL | PointF:: { .. } => {} //~ ERROR wrong number of type arguments error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:59:9 | +LL | match (Point { x: 1, y: 2 }) { + | ---------------------- this match expression has type `Point<{integer}>` LL | PointF { .. } => {} //~ ERROR mismatched types | ^^^^^^^^^^^^^ expected integer, found f32 | @@ -127,6 +131,8 @@ LL | PointF { .. } => {} //~ ERROR mismatched types error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:67:9 | +LL | match (Pair { x: 1, y: 2 }) { + | --------------------- this match expression has type `Pair<{integer}, {integer}>` LL | PairF:: { .. } => {} //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^^^ expected integer, found f32 |