Skip to content

Commit 6e84ab8

Browse files
authored
Unrolled build for rust-lang#136304
Rollup merge of rust-lang#136304 - oli-obk:push-ymxoklvzrpvx, r=Nadrieril Reject negative literals for unsigned or char types in pattern ranges and literals It sucks a bit that we have to duplicate the work here (normal expressions just get this for free from the `ExprKind::UnOp(UnOp::Neg, ...)` typeck logic. In rust-lang#134228 I caused ```rust fn main() { match 42_u8 { -10..255 => {}, _ => {} } } ``` to just compile without even a lint. I can't believe we didn't have tests for this Amusingly rust-lang#136302 will also register a delayed bug in `lit_to_const` for this, so we'll have a redundancy if something like this fails again.
2 parents a9730c3 + f44794f commit 6e84ab8

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
570570

571571
fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
572572
let ty = match &lt.kind {
573-
rustc_hir::PatExprKind::Lit { lit, .. } => {
574-
self.check_expr_lit(lit, Expectation::NoExpectation)
573+
rustc_hir::PatExprKind::Lit { lit, negated } => {
574+
let ty = self.check_expr_lit(lit, Expectation::NoExpectation);
575+
if *negated {
576+
self.register_bound(
577+
ty,
578+
self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)),
579+
ObligationCause::dummy_with_span(lt.span),
580+
);
581+
}
582+
ty
575583
}
576584
rustc_hir::PatExprKind::ConstBlock(c) => {
577585
self.check_expr_const_block(c, Expectation::NoExpectation)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(pattern_types)]
2+
#![feature(pattern_type_macro)]
3+
4+
use std::pat::pattern_type;
5+
6+
type Sign = pattern_type!(u32 is -10..);
7+
//~^ ERROR: cannot apply unary operator `-`
8+
9+
type SignedChar = pattern_type!(char is -'A'..);
10+
//~^ ERROR: cannot apply unary operator `-`
11+
12+
fn main() {
13+
match 42_u8 {
14+
-10..253 => {}
15+
//~^ ERROR `u8: Neg` is not satisfied
16+
_ => {}
17+
}
18+
19+
match 'A' {
20+
-'\0'..'a' => {}
21+
//~^ ERROR `char: Neg` is not satisfied
22+
_ => {}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0277]: the trait bound `u8: Neg` is not satisfied
2+
--> $DIR/signed_ranges.rs:14:9
3+
|
4+
LL | -10..253 => {}
5+
| ^^^ the trait `Neg` is not implemented for `u8`
6+
|
7+
= help: the following other types implement trait `Neg`:
8+
&f128
9+
&f16
10+
&f32
11+
&f64
12+
&i128
13+
&i16
14+
&i32
15+
&i64
16+
and 12 others
17+
18+
error[E0277]: the trait bound `char: Neg` is not satisfied
19+
--> $DIR/signed_ranges.rs:20:9
20+
|
21+
LL | -'\0'..'a' => {}
22+
| ^^^^^ the trait `Neg` is not implemented for `char`
23+
24+
error[E0600]: cannot apply unary operator `-` to type `u32`
25+
--> $DIR/signed_ranges.rs:6:34
26+
|
27+
LL | type Sign = pattern_type!(u32 is -10..);
28+
| ^^^ cannot apply unary operator `-`
29+
|
30+
= note: unsigned values cannot be negated
31+
32+
error[E0600]: cannot apply unary operator `-` to type `char`
33+
--> $DIR/signed_ranges.rs:9:41
34+
|
35+
LL | type SignedChar = pattern_type!(char is -'A'..);
36+
| ^^^^ cannot apply unary operator `-`
37+
38+
error: aborting due to 4 previous errors
39+
40+
Some errors have detailed explanations: E0277, E0600.
41+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)