Change:
For a match where I'm matching on a , I put on accident, and then rather than saying that 256 is out of range for , it decided to wrap 256 to 0 and then error that 251 is lower than the end of the range: Clearly this is not a good situation. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I'd like to fix this claim
Triage: I'm going to release assignment due to inactivity. If you're still interested in this, feel free to re-claim. release-assignment
Explanation on how to solve this in

Discussion:
.label = lower bound larger than upper bound .teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. <ins> mir_build_literal_in_range_out_of_bounds = literal out of range for `{$ty}` .label = this value doesn't fit in `{$ty}` whose maximum value is `{$max}` </ins> mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper mir_build_leading_irrefutable_let_patterns = leading irrefutable {$count ->

} #[derive(Diagnostic)] <ins> #[diag(mir_build_literal_in_range_out_of_bounds)] pub struct LiteralOutOfRange<'tcx> { #[primary_span] #[label] pub span: Span, pub ty: Ty<'tcx>, pub max: u128, } #[derive(Diagnostic)] </ins> #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")] pub struct LowerRangeBoundMustBeLessThanUpper { #[primary_span]

hi: mir::ConstantKind<'tcx>, end: RangeEnd, span: Span, <ins> lo_expr: Option<&hir::Expr<'tcx>>, hi_expr: Option<&hir::Expr<'tcx>>, </ins> ) -> PatKind<'tcx> { assert_eq!(lo.ty(), ty); assert_eq!(hi.ty(), ty); let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env); <ins> let max = || { self.tcx .layout_of(self.param_env.with_reveal_all_normalized(self.tcx).and(ty)) .ok() .unwrap() .size .unsigned_int_max() }; </ins> match (end, cmp) { // `x..y` where `x < y`. // Non-empty because the range includes at least `x`.

} // `x..y` where `x >= y`. The range is empty => error. (RangeEnd::Excluded, _) => { <del> self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanUpper { span }); </del> <ins> let mut lower_overflow = false; let mut higher_overflow = false; if let Some(hir::Expr { kind: hir::ExprKind::Lit(lit), .. }) = lo_expr && let rustc_ast::ast::LitKind::Int(val, _) = lit.node { if lo.eval_bits(self.tcx, self.param_env, ty) != val { lower_overflow = true; self.tcx.sess.emit_err(LiteralOutOfRange { span: lit.span, ty, max: max() }); } } if let Some(hir::Expr { kind: hir::ExprKind::Lit(lit), .. }) = hi_expr && let rustc_ast::ast::LitKind::Int(val, _) = lit.node { if hi.eval_bits(self.tcx, self.param_env, ty) != val { higher_overflow = true; self.tcx.sess.emit_err(LiteralOutOfRange { span: lit.span, ty, max: max() }); } } if !lower_overflow && !higher_overflow { self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanUpper { span }); } </ins> PatKind::Wild } // `x..=y` where `x == y`.

} // `x..=y` where `x > y` hence the range is empty => error. (RangeEnd::Included, _) => { <del> self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper { span, teach: if self.tcx.sess.teach(&error_code!(E0030)) { Some(()) } else { None }, }); </del> <ins> let mut lower_overflow = false; let mut higher_overflow = false; if let Some(hir::Expr { kind: hir::ExprKind::Lit(lit), .. }) = lo_expr && let rustc_ast::ast::LitKind::Int(val, _) = lit.node { if lo.eval_bits(self.tcx, self.param_env, ty) != val { lower_overflow = true; self.tcx.sess.emit_err(LiteralOutOfRange { span: lit.span, ty, max: max() }); } } if let Some(hir::Expr { kind: hir::ExprKind::Lit(lit), .. }) = hi_expr && let rustc_ast::ast::LitKind::Int(val, _) = lit.node { if hi.eval_bits(self.tcx, self.param_env, ty) != val { higher_overflow = true; self.tcx.sess.emit_err(LiteralOutOfRange { span: lit.span, ty, max: max() }); } } if !lower_overflow && !higher_overflow { self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper { span, teach: if self.tcx.sess.teach(&error_code!(E0030)) { Some(()) } else { None }, }); } </ins> PatKind::Wild } }

let (lp, hp) = (lo.as_ref().map(|(x, _)| x), hi.as_ref().map(|(x, _)| x)); let mut kind = match self.normalize_range_pattern_ends(ty, lp, hp) { <del> Some((lc, hc)) => self.lower_pattern_range(ty, lc, hc, end, lo_span), </del> <ins> Some((lc, hc)) => { self.lower_pattern_range(ty, lc, hc, end, lo_span, lo_expr, hi_expr) } </ins> None => { let msg = &format!( "found bad range pattern `{:?}` outside of error recovery",

<ins> #![feature(exclusive_range_pattern)] #![allow(unreachable_patterns)] fn main() { match 0u8 { 251..257 => {} //~^ ERROR literal out of range //~| ERROR literal out of range 251..=256 => {} //~^ ERROR literal out of range //~| ERROR literal out of range _ => {} } } </ins>

<ins> error: literal out of range for `u8` --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:5:14 | LL |         251..257 => {} |              ^^^ this value doesn't fit in `u8` whose maximum value is `255` error: literal out of range for `u8` --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:8:15 | LL |         251..=256 => {} |               ^^^ this value doesn't fit in `u8` whose maximum value is `255` error: literal out of range for `u8` --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:5:14 | LL |         251..257 => {} |              ^^^ this value doesn't fit in `u8` whose maximum value is `255` error: literal out of range for `u8` --> $DIR/range-pattern-out-of-bounds-issue-68972.rs:8:15 | LL |         251..=256 => {} |               ^^^ this value doesn't fit in `u8` whose maximum value is `255` error: aborting due to 4 previous errors </ins>