diff options
| author | bors <bors@rust-lang.org> | 2023-01-11 23:05:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-01-11 23:05:58 +0000 |
| commit | 56ee65aeb6d1fad67d903d5ee1359abcf7b94231 (patch) | |
| tree | 2ddda23b3e396ddddfa76f9f282647e3233e0898 /compiler/rustc_mir_build/src | |
| parent | 1e4f90061cc4bc566f99ab21b1f101182b10cf0c (diff) | |
| parent | 106df9ec98012c6fbeb0ffe636f5f566333cfaa1 (diff) | |
| download | rust-56ee65aeb6d1fad67d903d5ee1359abcf7b94231.tar.gz rust-56ee65aeb6d1fad67d903d5ee1359abcf7b94231.zip | |
Auto merge of #106743 - matthiaskrgr:rollup-q5dpxms, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106620 (Detect struct literal needing parentheses) - #106622 (Detect out of bounds range pattern value) - #106703 (Note predicate span on `ImplDerivedObligation`) - #106705 (Report fulfillment errors in new trait solver) - #106726 (Fix some typos in code comments.) - #106734 (Deny having src/test exisiting in tidy) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_mir_build/src')
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/mod.rs | 68 |
2 files changed, 72 insertions, 6 deletions
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 68179001b91..233eecbd5b4 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -494,6 +494,16 @@ pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { } #[derive(Diagnostic)] +#[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)] #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")] pub struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 2c775b39718..7d4353c5292 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -129,10 +129,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { 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`. @@ -141,7 +151,27 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } // `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`. @@ -152,10 +182,34 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } // `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 } } @@ -201,7 +255,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { 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", |
