diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 3fb6d5227f77b..c6378ac2d0b1b 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -353,13 +353,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_range( &self, span: Span, - begin: &'tcx hir::Expr<'tcx>, - end: &'tcx hir::Expr<'tcx>, + lhs: &'tcx hir::Expr<'tcx>, + rhs: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, discrim_span: Option, ) -> Option> { - let lhs_ty = self.check_expr(begin); - let rhs_ty = self.check_expr(end); + let lhs_ty = self.check_expr(lhs); + let rhs_ty = self.check_expr(rhs); // Check that both end-points are of numeric or char type. let numeric_or_char = |ty: Ty<'_>| ty.is_numeric() || ty.is_char() || ty.references_error(); @@ -367,7 +367,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rhs_fail = !numeric_or_char(rhs_ty); if lhs_fail || rhs_fail { - self.emit_err_pat_range(span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty); + self.emit_err_pat_range(span, lhs.span, rhs.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty); return None; } @@ -376,11 +376,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let common_type = self.resolve_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, discrim_span); - self.demand_eqtype_pat(span, expected, rhs_ty, discrim_span); + let demand_eqtype = |x_span, y_span, x_ty, y_ty| { + self.demand_eqtype_pat_diag(x_span, expected, x_ty, discrim_span).map(|mut err| { + self.endpoint_has_type(&mut err, y_span, y_ty); + err.emit(); + }); + }; + demand_eqtype(lhs.span, rhs.span, lhs_ty, rhs_ty); + demand_eqtype(rhs.span, lhs.span, rhs_ty, lhs_ty); + Some(common_type) } + fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) { + if !ty.references_error() { + err.span_label(span, &format!("this is of type `{}`", ty)); + } + } + fn emit_err_pat_range( &self, span: Span, @@ -408,9 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = |ty| format!("this is of type `{}` but it should be `char` or numeric", ty); let mut one_side_err = |first_span, first_ty, second_span, second_ty: Ty<'_>| { err.span_label(first_span, &msg(first_ty)); - if !second_ty.references_error() { - err.span_label(second_span, &format!("this is of type `{}`", second_ty)); - } + self.endpoint_has_type(&mut err, second_span, second_ty); }; if lhs_fail && rhs_fail { err.span_label(begin_span, &msg(lhs_ty)); diff --git a/src/test/ui/error-codes/E0308-4.stderr b/src/test/ui/error-codes/E0308-4.stderr index 127fdaadbc5dd..46805d6e13b7c 100644 --- a/src/test/ui/error-codes/E0308-4.stderr +++ b/src/test/ui/error-codes/E0308-4.stderr @@ -1,10 +1,12 @@ error[E0308]: mismatched types - --> $DIR/E0308-4.rs:4:9 + --> $DIR/E0308-4.rs:4:15 | LL | match x { | - this match expression has type `u8` LL | 0u8..=3i8 => (), - | ^^^^^^^^^ expected `u8`, found `i8` + | --- ^^^ expected `u8`, found `i8` + | | + | this is of type `u8` error: aborting due to previous error diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 2029cfaf75dfe..04538cd74b195 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -10,7 +10,7 @@ error[E0308]: mismatched types LL | match [5..4, 99..105, 43..44] { | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [_, 99.., _] => {}, - | ^^^^ expected struct `std::ops::Range`, found integer + | ^^ expected struct `std::ops::Range`, found integer | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index 6a88d05837a87..c918d0a385c75 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -16,7 +16,7 @@ error[E0308]: mismatched types LL | match [5..4, 99..105, 43..44] { | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [_, 99..] => {}, - | ^^^^ expected struct `std::ops::Range`, found integer + | ^^ expected struct `std::ops::Range`, found integer | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs index 95e58b1d48c88..1557f592b2a9b 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs @@ -6,6 +6,7 @@ fn main() { //~^ ERROR `..X` range patterns are not supported //~| ERROR mismatched types //~| ERROR mismatched types + //~| ERROR mismatched types _ => {}, } } diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index 5c49fbe4c5c94..e6ee3817b3558 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -5,12 +5,12 @@ LL | [..9, 99..100, _] => {}, | ^^^ help: try using the minimum value for the type: `MIN..9` error[E0308]: mismatched types - --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10 + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 | LL | match [5..4, 99..105, 43..44] { | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [..9, 99..100, _] => {}, - | ^^^ expected struct `std::ops::Range`, found integer + | ^ expected struct `std::ops::Range`, found integer | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` @@ -21,11 +21,26 @@ error[E0308]: mismatched types LL | match [5..4, 99..105, 43..44] { | ----------------------- this match expression has type `std::ops::Range<{integer}>` LL | [..9, 99..100, _] => {}, - | ^^^^^^^ expected struct `std::ops::Range`, found integer + | ^^ --- this is of type `{integer}` + | | + | expected struct `std::ops::Range`, found integer + | + = note: expected struct `std::ops::Range<{integer}>` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19 + | +LL | match [5..4, 99..105, 43..44] { + | ----------------------- this match expression has type `std::ops::Range<{integer}>` +LL | [..9, 99..100, _] => {}, + | -- ^^^ expected struct `std::ops::Range`, found integer + | | + | this is of type `{integer}` | = note: expected struct `std::ops::Range<{integer}>` found type `{integer}` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/match/match-range-fail.stderr b/src/test/ui/match/match-range-fail.stderr index adaaf29aae4c8..64105dc73d3f5 100644 --- a/src/test/ui/match/match-range-fail.stderr +++ b/src/test/ui/match/match-range-fail.stderr @@ -28,7 +28,9 @@ error[E0308]: mismatched types --> $DIR/match-range-fail.rs:18:9 | LL | 'c' ..= 100 => { } - | ^^^^^^^^^^^ expected integer, found `char` + | ^^^ --- this is of type `{integer}` + | | + | expected integer, found `char` error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index 3579a2c4e0951..5b0253cd2738a 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -19,7 +19,7 @@ error[E0308]: mismatched types LL | match (0, 1) { | ------ this match expression has type `({integer}, {integer})` LL | (PAT ..) => {} - | ^^^^^^ expected tuple, found `u8` + | ^^^ expected tuple, found `u8` | = note: expected tuple `({integer}, {integer})` found type `u8` diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index af03b577548f7..50a44192707f0 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -417,13 +417,17 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:21:12 | LL | if let .0..Y = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ - this is of type `u8` + | | + | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:23:12 + --> $DIR/recover-range-pats.rs:23:16 | LL | if let X.. .0 = 0 {} - | ^^^^^^ expected integer, found floating-point number + | - ^^ expected integer, found floating-point number + | | + | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:32:12 @@ -445,13 +449,17 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:34:12 | LL | if let .0..=Y = 0 {} - | ^^^^^^ expected integer, found floating-point number + | ^^ - this is of type `u8` + | | + | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:36:12 + --> $DIR/recover-range-pats.rs:36:16 | LL | if let X..=.0 = 0 {} - | ^^^^^^ expected integer, found floating-point number + | - ^^ expected integer, found floating-point number + | | + | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:45:12 @@ -473,13 +481,17 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:49:12 | LL | if let .0...Y = 0 {} - | ^^^^^^ expected integer, found floating-point number + | ^^ - this is of type `u8` + | | + | expected integer, found floating-point number error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:52:12 + --> $DIR/recover-range-pats.rs:52:17 | LL | if let X... .0 = 0 {} - | ^^^^^^^ expected integer, found floating-point number + | - ^^ expected integer, found floating-point number + | | + | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:60:12 @@ -491,7 +503,7 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:62:12 | LL | if let .0.. = 0 {} - | ^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:70:12 @@ -503,7 +515,7 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:72:12 | LL | if let .0..= = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:82:12 @@ -515,7 +527,7 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:85:12 | LL | if let .0... = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:94:14 @@ -524,10 +536,10 @@ LL | if let ..true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:96:12 + --> $DIR/recover-range-pats.rs:96:15 | LL | if let .. .0 = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:104:15 @@ -536,10 +548,10 @@ LL | if let ..=true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:106:12 + --> $DIR/recover-range-pats.rs:106:15 | LL | if let ..=.0 = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:116:15 @@ -548,10 +560,10 @@ LL | if let ...true = 0 {} | ^^^^ this is of type `bool` but it should be `char` or numeric error[E0308]: mismatched types - --> $DIR/recover-range-pats.rs:119:12 + --> $DIR/recover-range-pats.rs:119:15 | LL | if let ....3 = 0 {} - | ^^^^^ expected integer, found floating-point number + | ^^ expected integer, found floating-point number error: aborting due to 85 previous errors