hi: mir::ConstantKind<'tcx>,
end: RangeEnd,
span: Span,
+ lo_expr: Option<&hir::Expr<'tcx>>,
+ hi_expr: Option<&hir::Expr<'tcx>>,
) -> PatKind<'tcx> {
assert_eq!(lo.ty(), ty);
assert_eq!(hi.ty(), ty);
let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env);
+ let max = || {
+ self.tcx
+ .layout_of(self.param_env.with_reveal_all_normalized(self.tcx).and(ty))
+ .ok()
+ .unwrap()
+ .size
+ .unsigned_int_max()
+ };
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, _) => {
- self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanUpper { span });
+ 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 });
+ }
PatKind::Wild
}
// `x..=y` where `x == y`.
}
// `x..=y` where `x > y` hence the range is empty => error.
(RangeEnd::Included, _) => {
- self.tcx.sess.emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper {
- span,
- teach: if self.tcx.sess.teach(&error_code!(E0030)) { Some(()) } else { None },
- });
+ 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
+ },
+ });
+ }
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) {
- Some((lc, hc)) => self.lower_pattern_range(ty, lc, hc, end, lo_span),
+ Some((lc, hc)) => {
+ self.lower_pattern_range(ty, lc, hc, end, lo_span, lo_expr, hi_expr)
+ }
None => {
let msg = &format!(
"found bad range pattern `{:?}` outside of error recovery",
--- /dev/null
+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
+