From 7833cf7a4703099d32012848f682c1e7decc0f51 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 5 Dec 2024 17:32:26 +0000 Subject: [PATCH 1/5] Make `lit_to_mir_constant` infallible --- .../src/builder/expr/as_constant.rs | 52 ++++++++----------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 177c1e33a83bb..e4e452aff7553 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -3,13 +3,12 @@ use rustc_abi::Size; use rustc_ast as ast; use rustc_hir::LangItem; -use rustc_middle::mir::interpret::{ - Allocation, CTFE_ALLOC_SALT, LitToConstError, LitToConstInput, Scalar, -}; +use rustc_middle::mir::interpret::{Allocation, CTFE_ALLOC_SALT, LitToConstInput, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::{ - self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex, + self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt as _, + UserTypeAnnotationIndex, }; use rustc_middle::{bug, mir, span_bug}; use tracing::{instrument, trace}; @@ -50,16 +49,7 @@ pub(crate) fn as_constant_inner<'tcx>( let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; match *kind { ExprKind::Literal { lit, neg } => { - let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) - { - Ok(c) => c, - Err(LitToConstError::Reported(guar)) => { - Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar)) - } - Err(LitToConstError::TypeError) => { - bug!("encountered type error in `lit_to_mir_constant`") - } - }; + let const_ = lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }); ConstOperand { span, user_ty: None, const_ } } @@ -108,11 +98,13 @@ pub(crate) fn as_constant_inner<'tcx>( } #[instrument(skip(tcx, lit_input))] -fn lit_to_mir_constant<'tcx>( - tcx: TyCtxt<'tcx>, - lit_input: LitToConstInput<'tcx>, -) -> Result, LitToConstError> { +fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>) -> Const<'tcx> { let LitToConstInput { lit, ty, neg } = lit_input; + + if let Err(guar) = ty.error_reported() { + return Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar)); + } + let trunc = |n| { let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(layout) => layout.size, @@ -123,7 +115,7 @@ fn lit_to_mir_constant<'tcx>( trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); - Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) + ConstValue::Scalar(Scalar::from_uint(result, width)) }; let value = match (lit, ty.kind()) { @@ -154,20 +146,18 @@ fn lit_to_mir_constant<'tcx>( ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) } (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { - trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })? - } - (ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg) - .ok_or_else(|| { - LitToConstError::Reported( - tcx.dcx() - .delayed_bug(format!("couldn't parse float literal: {:?}", lit_input.lit)), - ) - })?, + trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() }) + } + (ast::LitKind::Float(n, _), ty::Float(fty)) => { + parse_float_into_constval(*n, *fty, neg).unwrap() + } (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), - (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)), - _ => return Err(LitToConstError::TypeError), + (ast::LitKind::Err(guar), _) => { + return Const::Ty(Ty::new_error(tcx, *guar), ty::Const::new_error(tcx, *guar)); + } + _ => bug!("invalid lit/ty combination in `lit_to_mir_constant`: {lit:?}: {ty:?}"), }; - Ok(Const::Val(value, ty)) + Const::Val(value, ty) } From 787af97babcb911f2ce70d3d28959cdccc7901bd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 7 Jan 2025 12:03:28 +0000 Subject: [PATCH 2/5] Use error constant instead of explicit error handling --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 3 --- compiler/rustc_middle/src/mir/interpret/mod.rs | 2 -- compiler/rustc_mir_build/src/thir/constant.rs | 6 +++--- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 1 - compiler/rustc_ty_utils/src/consts.rs | 1 - 5 files changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 0a41dad0dd837..5a65d5bafeec3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2456,9 +2456,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { LitToConstInput { lit: &lit.node, ty, neg: negated }; let ct = match tcx.lit_to_const(lit_input) { Ok(c) => c, - Err(LitToConstError::Reported(err)) => { - ty::Const::new_error(tcx, err) - } Err(LitToConstError::TypeError) => todo!(), }; (ct, ty) diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 8d73c9e76de1a..040390cb0aedb 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -16,7 +16,6 @@ use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size}; use rustc_ast::{LitKind, Mutability}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lock; -use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; @@ -91,7 +90,6 @@ pub enum LitToConstError { /// This is used for graceful error handling (`span_delayed_bug`) in /// type checking (`Const::from_anon_const`). TypeError, - Reported(ErrorGuaranteed), } #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index ce1c635d1b9f5..0e4efbdcbb029 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -62,13 +62,13 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Float(n, _), ty::Float(fty)) => { - let bits = parse_float_into_scalar(*n, *fty, neg).ok_or_else(|| { + let bits = parse_float_into_scalar(*n, *fty, neg).unwrap_or_else(|| { tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit)) - })?; + }); ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), - (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)), + (ast::LitKind::Err(guar), _) => return Ok(ty::Const::new_error(tcx, *guar)), _ => return Err(LitToConstError::TypeError), }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 242b62dfa8dde..8216f0a1ba29c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -671,7 +671,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg }; match self.tcx.at(expr.span).lit_to_const(lit_input) { Ok(constant) => self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind, - Err(LitToConstError::Reported(e)) => PatKind::Error(e), Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), } } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 637e239a57010..406e23eb879bb 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -120,7 +120,6 @@ fn recurse_build<'tcx>( let sp = node.span; match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { Ok(c) => c, - Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar), Err(LitToConstError::TypeError) => { bug!("encountered type error in lit_to_const") } From 07fcead0732d9460978dd3b428cd5edcfa299f9a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 7 Jan 2025 12:33:32 +0000 Subject: [PATCH 3/5] Always take the `Ok` path in `lit_to_const` and produce error constants instead --- .../src/hir_ty_lowering/mod.rs | 17 ++----- compiler/rustc_mir_build/src/thir/constant.rs | 2 +- tests/crashes/114317.rs | 6 --- tests/crashes/126182.rs | 10 ---- .../generic_const_exprs/lit_type_mismatch.rs | 22 +++++++++ .../lit_type_mismatch.stderr | 21 ++++++++ .../invalid-patterns.32bit.stderr | 48 +++++++++---------- .../invalid-patterns.64bit.stderr | 48 +++++++++---------- tests/ui/repeat-expr/repeat_count.stderr | 12 ++--- 9 files changed, 103 insertions(+), 83 deletions(-) delete mode 100644 tests/crashes/114317.rs delete mode 100644 tests/crashes/126182.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 5a65d5bafeec3..6ed5f92e99511 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2265,18 +2265,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Some(lit_input) = lit_input { // If an error occurred, ignore that it's a literal and leave reporting the error up to // mir. - match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return Some(c), - Err(_) if lit_input.ty.has_aliases() => { - // allow the `ty` to be an alias type, though we cannot handle it here - return None; - } - Err(e) => { - tcx.dcx().span_delayed_bug( - expr.span, - format!("try_lower_anon_const_lit: couldn't lit_to_const {e:?}"), - ); - } + + // Allow the `ty` to be an alias type, though we cannot handle it here, we just go through + // the more expensive anon const code path. + if !lit_input.ty.has_aliases() { + return Some(tcx.at(expr.span).lit_to_const(lit_input).unwrap()); } } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 0e4efbdcbb029..82830562c031a 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -69,7 +69,7 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (ast::LitKind::Err(guar), _) => return Ok(ty::Const::new_error(tcx, *guar)), - _ => return Err(LitToConstError::TypeError), + _ => return Ok(ty::Const::new_misc_error(tcx)), }; Ok(ty::Const::new_value(tcx, valtree, ty)) diff --git a/tests/crashes/114317.rs b/tests/crashes/114317.rs deleted file mode 100644 index 09fd2beeba8a5..0000000000000 --- a/tests/crashes/114317.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #114317 -#![feature(generic_const_exprs)] - -struct A; - -fn main() {} diff --git a/tests/crashes/126182.rs b/tests/crashes/126182.rs deleted file mode 100644 index 2219a6cb5fa19..0000000000000 --- a/tests/crashes/126182.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: rust-lang/rust#126182 - -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -struct Cond; - -struct Thing>(T); - -impl Thing {} diff --git a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs new file mode 100644 index 0000000000000..1ed0965e1bde1 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs @@ -0,0 +1,22 @@ +//! ICE regression test for #114317 and #126182 +//! Type mismatches of literals cause errors int typeck, +//! but those errors cannot be propagated to the various +//! `lit_to_const` call sites. Now `lit_to_const` just delays +//! a bug and produces an error constant on its own. + +#![feature(adt_const_params)] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct A(C); +//~^ ERROR: generic parameters with a default must be trailing +//~| ERROR: mismatched types + +struct Cond; + +struct Thing>(T); +//~^ ERROR: mismatched types + +impl Thing {} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr new file mode 100644 index 0000000000000..e4613e498b275 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr @@ -0,0 +1,21 @@ +error: generic parameters with a default must be trailing + --> $DIR/lit_type_mismatch.rs:11:16 + | +LL | struct A(C); + | ^ + +error[E0308]: mismatched types + --> $DIR/lit_type_mismatch.rs:11:24 + | +LL | struct A(C); + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/lit_type_mismatch.rs:17:23 + | +LL | struct Thing>(T); + | ^ expected `bool`, found integer + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr index be92429e3abc5..11a824ba73b2a 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr @@ -1,27 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:29:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:18 - | -LL | get_flag::<42, 0x5ad>(); - | ^^^^^ expected `char`, found `u8` - error[E0080]: evaluation of constant value failed --> $DIR/invalid-patterns.rs:38:32 | @@ -56,6 +32,30 @@ error[E0080]: evaluation of constant value failed LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:29:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + error: aborting due to 8 previous errors Some errors have detailed explanations: E0080, E0308. diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index be92429e3abc5..11a824ba73b2a 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -1,27 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:29:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:18 - | -LL | get_flag::<42, 0x5ad>(); - | ^^^^^ expected `char`, found `u8` - error[E0080]: evaluation of constant value failed --> $DIR/invalid-patterns.rs:38:32 | @@ -56,6 +32,30 @@ error[E0080]: evaluation of constant value failed LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:29:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + error: aborting due to 8 previous errors Some errors have detailed explanations: E0080, E0308. diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index 350ac287507a3..c4aebfb0e20d6 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -15,6 +15,12 @@ error[E0308]: mismatched types LL | let b = [0; ()]; | ^^ expected `usize`, found `()` +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:31:17 + | +LL | let g = [0; G { g: () }]; + | ^^^^^^^^^^^ expected `usize`, found `G` + error[E0308]: mismatched types --> $DIR/repeat_count.rs:10:17 | @@ -33,12 +39,6 @@ error[E0308]: mismatched types LL | let e = [0; "foo"]; | ^^^^^ expected `usize`, found `&str` -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:31:17 - | -LL | let g = [0; G { g: () }]; - | ^^^^^^^^^^^ expected `usize`, found `G` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:19:17 | From 8505904dccfb624e663aef3d50f2e5cefefa73d1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 7 Jan 2025 15:14:46 +0000 Subject: [PATCH 4/5] Remove the now-useless `Result` from `lit_to_const` --- .../src/hir_ty_lowering/mod.rs | 9 +++------ compiler/rustc_middle/src/mir/interpret/mod.rs | 9 --------- compiler/rustc_middle/src/query/erase.rs | 9 --------- compiler/rustc_middle/src/query/mod.rs | 4 ++-- compiler/rustc_mir_build/src/thir/constant.rs | 18 +++++++++--------- .../rustc_mir_build/src/thir/pattern/mod.rs | 8 +++----- compiler/rustc_ty_utils/src/consts.rs | 9 ++------- 7 files changed, 19 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 6ed5f92e99511..511ecc06e7966 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -35,7 +35,7 @@ use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::ty::fold::fold_regions; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ @@ -2269,7 +2269,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Allow the `ty` to be an alias type, though we cannot handle it here, we just go through // the more expensive anon const code path. if !lit_input.ty.has_aliases() { - return Some(tcx.at(expr.span).lit_to_const(lit_input).unwrap()); + return Some(tcx.at(expr.span).lit_to_const(lit_input)); } } @@ -2447,10 +2447,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::PatExprKind::Lit { lit, negated } => { let lit_input = LitToConstInput { lit: &lit.node, ty, neg: negated }; - let ct = match tcx.lit_to_const(lit_input) { - Ok(c) => c, - Err(LitToConstError::TypeError) => todo!(), - }; + let ct = tcx.lit_to_const(lit_input); (ct, ty) } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 040390cb0aedb..b88137544bca3 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -83,15 +83,6 @@ pub struct LitToConstInput<'tcx> { pub neg: bool, } -/// Error type for `tcx.lit_to_const`. -#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] -pub enum LitToConstError { - /// The literal's inferred type did not match the expected `ty` in the input. - /// This is used for graceful error handling (`span_delayed_bug`) in - /// type checking (`Const::from_anon_const`). - TypeError, -} - #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct AllocId(pub NonZero); diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index b72c0e776fe90..1676afb4b6ec4 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -141,14 +141,6 @@ impl EraseType for Result>, &ty::layout::Layou >()]; } -impl EraseType for Result, mir::interpret::LitToConstError> { - type Result = [u8; size_of::, mir::interpret::LitToConstError>>()]; -} - -impl EraseType for Result, mir::interpret::LitToConstError> { - type Result = [u8; size_of::, mir::interpret::LitToConstError>>()]; -} - impl EraseType for Result, mir::interpret::ErrorHandled> { type Result = [u8; size_of::, mir::interpret::ErrorHandled>>()]; } @@ -296,7 +288,6 @@ trivial! { rustc_middle::mir::interpret::AllocId, rustc_middle::mir::interpret::CtfeProvenance, rustc_middle::mir::interpret::ErrorHandled, - rustc_middle::mir::interpret::LitToConstError, rustc_middle::thir::ExprId, rustc_middle::traits::CodegenObligationError, rustc_middle::traits::EvaluationResult, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 95995b956cda5..283675573d4e5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -57,7 +57,7 @@ use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, use crate::middle::stability::{self, DeprecationEntry}; use crate::mir::interpret::{ EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, - EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput, + EvalToValTreeResult, GlobalId, LitToConstInput, }; use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem}; use crate::query::erase::{Erase, erase, restore}; @@ -1268,7 +1268,7 @@ rustc_queries! { // FIXME get rid of this with valtrees query lit_to_const( key: LitToConstInput<'tcx> - ) -> Result, LitToConstError> { + ) -> ty::Const<'tcx> { desc { "converting literal to const" } } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 82830562c031a..49db522cf0eed 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::bug; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _}; use tracing::trace; @@ -10,11 +10,11 @@ use crate::builder::parse_float_into_scalar; pub(crate) fn lit_to_const<'tcx>( tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>, -) -> Result, LitToConstError> { +) -> ty::Const<'tcx> { let LitToConstInput { lit, ty, neg } = lit_input; if let Err(guar) = ty.error_reported() { - return Ok(ty::Const::new_error(tcx, guar)); + return ty::Const::new_error(tcx, guar); } let trunc = |n| { @@ -28,8 +28,8 @@ pub(crate) fn lit_to_const<'tcx>( let result = width.truncate(n); trace!("trunc result: {}", result); - Ok(ScalarInt::try_from_uint(result, width) - .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result))) + ScalarInt::try_from_uint(result, width) + .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)) }; let valtree = match (lit, ty.kind()) { @@ -57,7 +57,7 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { let scalar_int = - trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })?; + trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() }); ty::ValTree::from_scalar_int(scalar_int) } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), @@ -68,9 +68,9 @@ pub(crate) fn lit_to_const<'tcx>( ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), - (ast::LitKind::Err(guar), _) => return Ok(ty::Const::new_error(tcx, *guar)), - _ => return Ok(ty::Const::new_misc_error(tcx)), + (ast::LitKind::Err(guar), _) => return ty::Const::new_error(tcx, *guar), + _ => return ty::Const::new_misc_error(tcx), }; - Ok(ty::Const::new_value(tcx, valtree, ty)) + ty::Const::new_value(tcx, valtree, ty) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 8216f0a1ba29c..44b038bb5faf1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -13,7 +13,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd}; use rustc_index::Idx; use rustc_lint as lint; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::thir::{ Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; @@ -669,10 +669,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let ct_ty = self.typeck_results.node_type(expr.hir_id); let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg }; - match self.tcx.at(expr.span).lit_to_const(lit_input) { - Ok(constant) => self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind, - Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), - } + let constant = self.tcx.at(expr.span).lit_to_const(lit_input); + self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind } } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 406e23eb879bb..51a7c976f600c 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -4,7 +4,7 @@ use rustc_abi::{FIRST_VARIANT, VariantIdx}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::mir::interpret::LitToConstInput; use rustc_middle::query::Providers; use rustc_middle::thir::visit; use rustc_middle::thir::visit::Visitor; @@ -118,12 +118,7 @@ fn recurse_build<'tcx>( } &ExprKind::Literal { lit, neg } => { let sp = node.span; - match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { - Ok(c) => c, - Err(LitToConstError::TypeError) => { - bug!("encountered type error in lit_to_const") - } - } + tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) } &ExprKind::NonHirLiteral { lit, user_ty: _ } => { let val = ty::ValTree::from_scalar_int(lit); From 84c8d4f52d5be135e2dec89379cb1d0f67be648c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 8 Jan 2025 12:40:02 +0000 Subject: [PATCH 5/5] Use option combinators instead of manual if/return --- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 511ecc06e7966..cb90fff782fb0 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2262,18 +2262,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { _ => None, }; - if let Some(lit_input) = lit_input { - // If an error occurred, ignore that it's a literal and leave reporting the error up to - // mir. - + lit_input // Allow the `ty` to be an alias type, though we cannot handle it here, we just go through // the more expensive anon const code path. - if !lit_input.ty.has_aliases() { - return Some(tcx.at(expr.span).lit_to_const(lit_input)); - } - } - - None + .filter(|l| !l.ty.has_aliases()) + .map(|l| tcx.at(expr.span).lit_to_const(l)) } fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {