Skip to content

Commit

Permalink
Unrolled build for rust-lang#136304
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rust-timer authored Feb 6, 2025
2 parents a9730c3 + f44794f commit 6e84ab8
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
12 changes: 10 additions & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
let ty = match &lt.kind {
rustc_hir::PatExprKind::Lit { lit, .. } => {
self.check_expr_lit(lit, Expectation::NoExpectation)
rustc_hir::PatExprKind::Lit { lit, negated } => {
let ty = self.check_expr_lit(lit, Expectation::NoExpectation);
if *negated {
self.register_bound(
ty,
self.tcx.require_lang_item(LangItem::Neg, Some(lt.span)),
ObligationCause::dummy_with_span(lt.span),
);
}
ty
}
rustc_hir::PatExprKind::ConstBlock(c) => {
self.check_expr_const_block(c, Expectation::NoExpectation)
Expand Down
24 changes: 24 additions & 0 deletions tests/ui/type/pattern_types/signed_ranges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![feature(pattern_types)]
#![feature(pattern_type_macro)]

use std::pat::pattern_type;

type Sign = pattern_type!(u32 is -10..);
//~^ ERROR: cannot apply unary operator `-`

type SignedChar = pattern_type!(char is -'A'..);
//~^ ERROR: cannot apply unary operator `-`

fn main() {
match 42_u8 {
-10..253 => {}
//~^ ERROR `u8: Neg` is not satisfied
_ => {}
}

match 'A' {
-'\0'..'a' => {}
//~^ ERROR `char: Neg` is not satisfied
_ => {}
}
}
41 changes: 41 additions & 0 deletions tests/ui/type/pattern_types/signed_ranges.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
error[E0277]: the trait bound `u8: Neg` is not satisfied
--> $DIR/signed_ranges.rs:14:9
|
LL | -10..253 => {}
| ^^^ the trait `Neg` is not implemented for `u8`
|
= help: the following other types implement trait `Neg`:
&f128
&f16
&f32
&f64
&i128
&i16
&i32
&i64
and 12 others

error[E0277]: the trait bound `char: Neg` is not satisfied
--> $DIR/signed_ranges.rs:20:9
|
LL | -'\0'..'a' => {}
| ^^^^^ the trait `Neg` is not implemented for `char`

error[E0600]: cannot apply unary operator `-` to type `u32`
--> $DIR/signed_ranges.rs:6:34
|
LL | type Sign = pattern_type!(u32 is -10..);
| ^^^ cannot apply unary operator `-`
|
= note: unsigned values cannot be negated

error[E0600]: cannot apply unary operator `-` to type `char`
--> $DIR/signed_ranges.rs:9:41
|
LL | type SignedChar = pattern_type!(char is -'A'..);
| ^^^^ cannot apply unary operator `-`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0277, E0600.
For more information about an error, try `rustc --explain E0277`.

0 comments on commit 6e84ab8

Please sign in to comment.