Rollup merge of #66351 - JohnTitor:tweak-range-err-msg, r=Centril
Tweak non-char/numeric in range pattern diagnostic Fixes #66283 r? @estebank
This commit is contained in:
commit
20c356263d
@ -362,37 +362,13 @@ fn check_pat_range(
|
||||
|| ty.is_char()
|
||||
|| ty.references_error()
|
||||
};
|
||||
let lhs_compat = numeric_or_char(lhs_ty);
|
||||
let rhs_compat = numeric_or_char(rhs_ty);
|
||||
let lhs_fail = !numeric_or_char(lhs_ty);
|
||||
let rhs_fail = !numeric_or_char(rhs_ty);
|
||||
|
||||
if !lhs_compat || !rhs_compat {
|
||||
let span = if !lhs_compat && !rhs_compat {
|
||||
span
|
||||
} else if !lhs_compat {
|
||||
begin.span
|
||||
} else {
|
||||
end.span
|
||||
};
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0029,
|
||||
"only char and numeric types are allowed in range patterns"
|
||||
if lhs_fail || rhs_fail {
|
||||
self.emit_err_pat_range(
|
||||
span, begin.span, end.span, lhs_fail, rhs_fail, lhs_ty, rhs_ty
|
||||
);
|
||||
err.span_label(span, "ranges require char or numeric types");
|
||||
err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
|
||||
err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(
|
||||
"In a match expression, only numbers and characters can be matched \
|
||||
against a range. This is because the compiler checks that the range \
|
||||
is non-empty at compile-time, and is unable to evaluate arbitrary \
|
||||
comparison functions. If you want to capture values of an orderable \
|
||||
type between two end-points, you can use a guard."
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -406,6 +382,62 @@ fn check_pat_range(
|
||||
Some(common_type)
|
||||
}
|
||||
|
||||
fn emit_err_pat_range(
|
||||
&self,
|
||||
span: Span,
|
||||
begin_span: Span,
|
||||
end_span: Span,
|
||||
lhs_fail: bool,
|
||||
rhs_fail: bool,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
rhs_ty: Ty<'tcx>,
|
||||
) {
|
||||
let span = if lhs_fail && rhs_fail {
|
||||
span
|
||||
} else if lhs_fail {
|
||||
begin_span
|
||||
} else {
|
||||
end_span
|
||||
};
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0029,
|
||||
"only char and numeric types are allowed in range patterns"
|
||||
);
|
||||
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)
|
||||
);
|
||||
}
|
||||
};
|
||||
if lhs_fail && rhs_fail {
|
||||
err.span_label(begin_span, &msg(lhs_ty));
|
||||
err.span_label(end_span, &msg(rhs_ty));
|
||||
} else if lhs_fail {
|
||||
one_side_err(begin_span, lhs_ty, end_span, rhs_ty);
|
||||
} else {
|
||||
one_side_err(end_span, rhs_ty, begin_span, lhs_ty);
|
||||
}
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(
|
||||
"In a match expression, only numbers and characters can be matched \
|
||||
against a range. This is because the compiler checks that the range \
|
||||
is non-empty at compile-time, and is unable to evaluate arbitrary \
|
||||
comparison functions. If you want to capture values of an orderable \
|
||||
type between two end-points, you can use a guard."
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn check_pat_ident(
|
||||
&self,
|
||||
pat: &Pat,
|
||||
|
@ -2,10 +2,11 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/E0029-teach.rs:7:9
|
||||
|
|
||||
LL | "hello" ..= "world" => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
||||
| -------^^^^^-------
|
||||
| | |
|
||||
| | this is of type `&'static str` but it should be `char` or numeric
|
||||
| this is of type `&'static str` but it should be `char` or numeric
|
||||
|
|
||||
= note: start type: &'static str
|
||||
= note: end type: &'static str
|
||||
= note: In a match expression, only numbers and characters can be matched against a range. This is because the compiler checks that the range is non-empty at compile-time, and is unable to evaluate arbitrary comparison functions. If you want to capture values of an orderable type between two end-points, you can use a guard.
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -2,10 +2,10 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/E0029.rs:5:9
|
||||
|
|
||||
LL | "hello" ..= "world" => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: &'static str
|
||||
= note: end type: &'static str
|
||||
| -------^^^^^-------
|
||||
| | |
|
||||
| | this is of type `&'static str` but it should be `char` or numeric
|
||||
| this is of type `&'static str` but it should be `char` or numeric
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,15 +3,16 @@ fn main() {
|
||||
"bar" ..= "foo" => { }
|
||||
};
|
||||
//~^^ ERROR only char and numeric types are allowed in range
|
||||
//~| start type: &'static str
|
||||
//~| end type: &'static str
|
||||
|
||||
match "wow" {
|
||||
10 ..= "what" => ()
|
||||
};
|
||||
//~^^ ERROR only char and numeric types are allowed in range
|
||||
//~| start type: {integer}
|
||||
//~| end type: &'static str
|
||||
|
||||
match "wow" {
|
||||
true ..= "what" => {}
|
||||
};
|
||||
//~^^ ERROR only char and numeric types are allowed in range
|
||||
|
||||
match 5 {
|
||||
'c' ..= 100 => { }
|
||||
|
@ -2,22 +2,30 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/match-range-fail.rs:3:9
|
||||
|
|
||||
LL | "bar" ..= "foo" => { }
|
||||
| ^^^^^^^^^^^^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: &'static str
|
||||
= note: end type: &'static str
|
||||
| -----^^^^^-----
|
||||
| | |
|
||||
| | this is of type `&'static str` but it should be `char` or numeric
|
||||
| this is of type `&'static str` but it should be `char` or numeric
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/match-range-fail.rs:10:16
|
||||
--> $DIR/match-range-fail.rs:8:16
|
||||
|
|
||||
LL | 10 ..= "what" => ()
|
||||
| ^^^^^^ ranges require char or numeric types
|
||||
| -- ^^^^^^ this is of type `&'static str` but it should be `char` or numeric
|
||||
| |
|
||||
| this is of type `{integer}`
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/match-range-fail.rs:13:9
|
||||
|
|
||||
= note: start type: {integer}
|
||||
= note: end type: &'static str
|
||||
LL | true ..= "what" => {}
|
||||
| ----^^^^^------
|
||||
| | |
|
||||
| | this is of type `&'static str` but it should be `char` or numeric
|
||||
| this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/match-range-fail.rs:17:9
|
||||
--> $DIR/match-range-fail.rs:18:9
|
||||
|
|
||||
LL | 'c' ..= 100 => { }
|
||||
| ^^^^^^^^^^^ expected integer, found char
|
||||
@ -25,7 +33,7 @@ LL | 'c' ..= 100 => { }
|
||||
= note: expected type `{integer}`
|
||||
found type `char`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0029, E0308.
|
||||
For more information about an error, try `rustc --explain E0029`.
|
||||
|
@ -401,19 +401,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:19:12
|
||||
|
|
||||
LL | if let true..Y = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: u8
|
||||
| ^^^^ - this is of type `u8`
|
||||
| |
|
||||
| this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:20:15
|
||||
|
|
||||
LL | if let X..true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: u8
|
||||
= note: end type: bool
|
||||
| - ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
| |
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:21:12
|
||||
@ -437,19 +435,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:32:12
|
||||
|
|
||||
LL | if let true..=Y = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: u8
|
||||
| ^^^^ - this is of type `u8`
|
||||
| |
|
||||
| this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:33:16
|
||||
|
|
||||
LL | if let X..=true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: u8
|
||||
= note: end type: bool
|
||||
| - ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
| |
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:34:12
|
||||
@ -473,19 +469,17 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:45:12
|
||||
|
|
||||
LL | if let true...Y = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: u8
|
||||
| ^^^^ - this is of type `u8`
|
||||
| |
|
||||
| this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:47:16
|
||||
|
|
||||
LL | if let X...true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: u8
|
||||
= note: end type: bool
|
||||
| - ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
| |
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:49:12
|
||||
@ -509,10 +503,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:60:12
|
||||
|
|
||||
LL | if let true.. = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: [type error]
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:62:12
|
||||
@ -527,10 +518,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:70:12
|
||||
|
|
||||
LL | if let true..= = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: [type error]
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:72:12
|
||||
@ -545,10 +533,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:82:12
|
||||
|
|
||||
LL | if let true... = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: bool
|
||||
= note: end type: [type error]
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:85:12
|
||||
@ -563,10 +548,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:94:14
|
||||
|
|
||||
LL | if let ..true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: [type error]
|
||||
= note: end type: bool
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:96:12
|
||||
@ -581,10 +563,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:104:15
|
||||
|
|
||||
LL | if let ..=true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: [type error]
|
||||
= note: end type: bool
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:106:12
|
||||
@ -599,10 +578,7 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:116:15
|
||||
|
|
||||
LL | if let ...true = 0 {}
|
||||
| ^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: [type error]
|
||||
= note: end type: bool
|
||||
| ^^^^ this is of type `bool` but it should be `char` or numeric
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:119:12
|
||||
|
@ -7,11 +7,11 @@ LL | Arith = 1 + 1,
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/patkind-litrange-no-expr.rs:20:13
|
||||
|
|
||||
LL | $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range
|
||||
| -- this is of type `{integer}`
|
||||
...
|
||||
LL | Arith = 1 + 1,
|
||||
| ^^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: {integer}
|
||||
= note: end type: {integer}
|
||||
| ^^^^^ this is of type `_` but it should be `char` or numeric
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -8,10 +8,9 @@ error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/qualified-path-params.rs:22:15
|
||||
|
|
||||
LL | 0 ..= <S as Tr>::A::f::<u8> => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ranges require char or numeric types
|
||||
|
|
||||
= note: start type: {integer}
|
||||
= note: end type: fn() {S::f::<u8>}
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^ this is of type `fn() {S::f::<u8>}` but it should be `char` or numeric
|
||||
| |
|
||||
| this is of type `{integer}`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user