Skip to content

Commit 8ff355a

Browse files
authored
Rollup merge of #135195 - oli-obk:push-toyoyrupruko, r=lcnr
Make `lit_to_mir_constant` and `lit_to_const` infallible My motivation for this change is just that it's annoying to check everywhere, especially since all but one call site was just ICEing on errors anyway right there. They can still fail, but now just return an error constant instead of having the caller handle the error. fixes #114317 fixes #126182
2 parents d487294 + 84c8d4f commit 8ff355a

File tree

15 files changed

+143
-175
lines changed

15 files changed

+143
-175
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+7-27
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
3535
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3636
use rustc_infer::traits::ObligationCause;
3737
use rustc_middle::middle::stability::AllowUnstable;
38-
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
38+
use rustc_middle::mir::interpret::LitToConstInput;
3939
use rustc_middle::ty::fold::fold_regions;
4040
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
4141
use rustc_middle::ty::{
@@ -2262,25 +2262,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22622262
_ => None,
22632263
};
22642264

2265-
if let Some(lit_input) = lit_input {
2266-
// If an error occurred, ignore that it's a literal and leave reporting the error up to
2267-
// mir.
2268-
match tcx.at(expr.span).lit_to_const(lit_input) {
2269-
Ok(c) => return Some(c),
2270-
Err(_) if lit_input.ty.has_aliases() => {
2271-
// allow the `ty` to be an alias type, though we cannot handle it here
2272-
return None;
2273-
}
2274-
Err(e) => {
2275-
tcx.dcx().span_delayed_bug(
2276-
expr.span,
2277-
format!("try_lower_anon_const_lit: couldn't lit_to_const {e:?}"),
2278-
);
2279-
}
2280-
}
2281-
}
2282-
2283-
None
2265+
lit_input
2266+
// Allow the `ty` to be an alias type, though we cannot handle it here, we just go through
2267+
// the more expensive anon const code path.
2268+
.filter(|l| !l.ty.has_aliases())
2269+
.map(|l| tcx.at(expr.span).lit_to_const(l))
22842270
}
22852271

22862272
fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
@@ -2454,13 +2440,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24542440
hir::PatExprKind::Lit { lit, negated } => {
24552441
let lit_input =
24562442
LitToConstInput { lit: &lit.node, ty, neg: negated };
2457-
let ct = match tcx.lit_to_const(lit_input) {
2458-
Ok(c) => c,
2459-
Err(LitToConstError::Reported(err)) => {
2460-
ty::Const::new_error(tcx, err)
2461-
}
2462-
Err(LitToConstError::TypeError) => todo!(),
2463-
};
2443+
let ct = tcx.lit_to_const(lit_input);
24642444
(ct, ty)
24652445
}
24662446

compiler/rustc_middle/src/mir/interpret/mod.rs

-11
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size};
1616
use rustc_ast::{LitKind, Mutability};
1717
use rustc_data_structures::fx::FxHashMap;
1818
use rustc_data_structures::sync::Lock;
19-
use rustc_errors::ErrorGuaranteed;
2019
use rustc_hir::def::DefKind;
2120
use rustc_hir::def_id::{DefId, LocalDefId};
2221
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -84,16 +83,6 @@ pub struct LitToConstInput<'tcx> {
8483
pub neg: bool,
8584
}
8685

87-
/// Error type for `tcx.lit_to_const`.
88-
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
89-
pub enum LitToConstError {
90-
/// The literal's inferred type did not match the expected `ty` in the input.
91-
/// This is used for graceful error handling (`span_delayed_bug`) in
92-
/// type checking (`Const::from_anon_const`).
93-
TypeError,
94-
Reported(ErrorGuaranteed),
95-
}
96-
9786
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
9887
pub struct AllocId(pub NonZero<u64>);
9988

compiler/rustc_middle/src/query/erase.rs

-9
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,6 @@ impl EraseType for Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::Layou
141141
>()];
142142
}
143143

144-
impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> {
145-
type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()];
146-
}
147-
148-
impl EraseType for Result<mir::Const<'_>, mir::interpret::LitToConstError> {
149-
type Result = [u8; size_of::<Result<mir::Const<'static>, mir::interpret::LitToConstError>>()];
150-
}
151-
152144
impl EraseType for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
153145
type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()];
154146
}
@@ -296,7 +288,6 @@ trivial! {
296288
rustc_middle::mir::interpret::AllocId,
297289
rustc_middle::mir::interpret::CtfeProvenance,
298290
rustc_middle::mir::interpret::ErrorHandled,
299-
rustc_middle::mir::interpret::LitToConstError,
300291
rustc_middle::thir::ExprId,
301292
rustc_middle::traits::CodegenObligationError,
302293
rustc_middle::traits::EvaluationResult,

compiler/rustc_middle/src/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars,
5757
use crate::middle::stability::{self, DeprecationEntry};
5858
use crate::mir::interpret::{
5959
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
60-
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
60+
EvalToValTreeResult, GlobalId, LitToConstInput,
6161
};
6262
use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem};
6363
use crate::query::erase::{Erase, erase, restore};
@@ -1268,7 +1268,7 @@ rustc_queries! {
12681268
// FIXME get rid of this with valtrees
12691269
query lit_to_const(
12701270
key: LitToConstInput<'tcx>
1271-
) -> Result<ty::Const<'tcx>, LitToConstError> {
1271+
) -> ty::Const<'tcx> {
12721272
desc { "converting literal to const" }
12731273
}
12741274

compiler/rustc_mir_build/src/builder/expr/as_constant.rs

+21-31
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
use rustc_abi::Size;
44
use rustc_ast as ast;
55
use rustc_hir::LangItem;
6-
use rustc_middle::mir::interpret::{
7-
Allocation, CTFE_ALLOC_SALT, LitToConstError, LitToConstInput, Scalar,
8-
};
6+
use rustc_middle::mir::interpret::{Allocation, CTFE_ALLOC_SALT, LitToConstInput, Scalar};
97
use rustc_middle::mir::*;
108
use rustc_middle::thir::*;
119
use rustc_middle::ty::{
12-
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
10+
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt as _,
11+
UserTypeAnnotationIndex,
1312
};
1413
use rustc_middle::{bug, mir, span_bug};
1514
use tracing::{instrument, trace};
@@ -50,16 +49,7 @@ pub(crate) fn as_constant_inner<'tcx>(
5049
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
5150
match *kind {
5251
ExprKind::Literal { lit, neg } => {
53-
let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg })
54-
{
55-
Ok(c) => c,
56-
Err(LitToConstError::Reported(guar)) => {
57-
Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar))
58-
}
59-
Err(LitToConstError::TypeError) => {
60-
bug!("encountered type error in `lit_to_mir_constant`")
61-
}
62-
};
52+
let const_ = lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg });
6353

6454
ConstOperand { span, user_ty: None, const_ }
6555
}
@@ -108,11 +98,13 @@ pub(crate) fn as_constant_inner<'tcx>(
10898
}
10999

110100
#[instrument(skip(tcx, lit_input))]
111-
fn lit_to_mir_constant<'tcx>(
112-
tcx: TyCtxt<'tcx>,
113-
lit_input: LitToConstInput<'tcx>,
114-
) -> Result<Const<'tcx>, LitToConstError> {
101+
fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>) -> Const<'tcx> {
115102
let LitToConstInput { lit, ty, neg } = lit_input;
103+
104+
if let Err(guar) = ty.error_reported() {
105+
return Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar));
106+
}
107+
116108
let trunc = |n| {
117109
let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
118110
Ok(layout) => layout.size,
@@ -123,7 +115,7 @@ fn lit_to_mir_constant<'tcx>(
123115
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
124116
let result = width.truncate(n);
125117
trace!("trunc result: {}", result);
126-
Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
118+
ConstValue::Scalar(Scalar::from_uint(result, width))
127119
};
128120

129121
let value = match (lit, ty.kind()) {
@@ -154,20 +146,18 @@ fn lit_to_mir_constant<'tcx>(
154146
ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
155147
}
156148
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
157-
trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })?
158-
}
159-
(ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float_into_constval(*n, *fty, neg)
160-
.ok_or_else(|| {
161-
LitToConstError::Reported(
162-
tcx.dcx()
163-
.delayed_bug(format!("couldn't parse float literal: {:?}", lit_input.lit)),
164-
)
165-
})?,
149+
trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })
150+
}
151+
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
152+
parse_float_into_constval(*n, *fty, neg).unwrap()
153+
}
166154
(ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
167155
(ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
168-
(ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
169-
_ => return Err(LitToConstError::TypeError),
156+
(ast::LitKind::Err(guar), _) => {
157+
return Const::Ty(Ty::new_error(tcx, *guar), ty::Const::new_error(tcx, *guar));
158+
}
159+
_ => bug!("invalid lit/ty combination in `lit_to_mir_constant`: {lit:?}: {ty:?}"),
170160
};
171161

172-
Ok(Const::Val(value, ty))
162+
Const::Val(value, ty)
173163
}

compiler/rustc_mir_build/src/thir/constant.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc_ast as ast;
22
use rustc_hir::LangItem;
33
use rustc_middle::bug;
4-
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
4+
use rustc_middle::mir::interpret::LitToConstInput;
55
use rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _};
66
use tracing::trace;
77

@@ -10,11 +10,11 @@ use crate::builder::parse_float_into_scalar;
1010
pub(crate) fn lit_to_const<'tcx>(
1111
tcx: TyCtxt<'tcx>,
1212
lit_input: LitToConstInput<'tcx>,
13-
) -> Result<ty::Const<'tcx>, LitToConstError> {
13+
) -> ty::Const<'tcx> {
1414
let LitToConstInput { lit, ty, neg } = lit_input;
1515

1616
if let Err(guar) = ty.error_reported() {
17-
return Ok(ty::Const::new_error(tcx, guar));
17+
return ty::Const::new_error(tcx, guar);
1818
}
1919

2020
let trunc = |n| {
@@ -28,8 +28,8 @@ pub(crate) fn lit_to_const<'tcx>(
2828
let result = width.truncate(n);
2929
trace!("trunc result: {}", result);
3030

31-
Ok(ScalarInt::try_from_uint(result, width)
32-
.unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)))
31+
ScalarInt::try_from_uint(result, width)
32+
.unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result))
3333
};
3434

3535
let valtree = match (lit, ty.kind()) {
@@ -57,20 +57,20 @@ pub(crate) fn lit_to_const<'tcx>(
5757
}
5858
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
5959
let scalar_int =
60-
trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() })?;
60+
trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() });
6161
ty::ValTree::from_scalar_int(scalar_int)
6262
}
6363
(ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
6464
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
65-
let bits = parse_float_into_scalar(*n, *fty, neg).ok_or_else(|| {
65+
let bits = parse_float_into_scalar(*n, *fty, neg).unwrap_or_else(|| {
6666
tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit))
67-
})?;
67+
});
6868
ty::ValTree::from_scalar_int(bits)
6969
}
7070
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
71-
(ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
72-
_ => return Err(LitToConstError::TypeError),
71+
(ast::LitKind::Err(guar), _) => return ty::Const::new_error(tcx, *guar),
72+
_ => return ty::Const::new_misc_error(tcx),
7373
};
7474

75-
Ok(ty::Const::new_value(tcx, valtree, ty))
75+
ty::Const::new_value(tcx, valtree, ty)
7676
}

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
1313
use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd};
1414
use rustc_index::Idx;
1515
use rustc_lint as lint;
16-
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
16+
use rustc_middle::mir::interpret::LitToConstInput;
1717
use rustc_middle::thir::{
1818
Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
1919
};
@@ -669,11 +669,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
669669

670670
let ct_ty = self.typeck_results.node_type(expr.hir_id);
671671
let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
672-
match self.tcx.at(expr.span).lit_to_const(lit_input) {
673-
Ok(constant) => self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind,
674-
Err(LitToConstError::Reported(e)) => PatKind::Error(e),
675-
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
676-
}
672+
let constant = self.tcx.at(expr.span).lit_to_const(lit_input);
673+
self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
677674
}
678675
}
679676

compiler/rustc_ty_utils/src/consts.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_abi::{FIRST_VARIANT, VariantIdx};
44
use rustc_errors::ErrorGuaranteed;
55
use rustc_hir::def::DefKind;
66
use rustc_hir::def_id::LocalDefId;
7-
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
7+
use rustc_middle::mir::interpret::LitToConstInput;
88
use rustc_middle::query::Providers;
99
use rustc_middle::thir::visit;
1010
use rustc_middle::thir::visit::Visitor;
@@ -118,13 +118,7 @@ fn recurse_build<'tcx>(
118118
}
119119
&ExprKind::Literal { lit, neg } => {
120120
let sp = node.span;
121-
match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) {
122-
Ok(c) => c,
123-
Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar),
124-
Err(LitToConstError::TypeError) => {
125-
bug!("encountered type error in lit_to_const")
126-
}
127-
}
121+
tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg })
128122
}
129123
&ExprKind::NonHirLiteral { lit, user_ty: _ } => {
130124
let val = ty::ValTree::from_scalar_int(lit);

tests/crashes/114317.rs

-6
This file was deleted.

tests/crashes/126182.rs

-10
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! ICE regression test for #114317 and #126182
2+
//! Type mismatches of literals cause errors int typeck,
3+
//! but those errors cannot be propagated to the various
4+
//! `lit_to_const` call sites. Now `lit_to_const` just delays
5+
//! a bug and produces an error constant on its own.
6+
7+
#![feature(adt_const_params)]
8+
#![feature(generic_const_exprs)]
9+
#![allow(incomplete_features)]
10+
11+
struct A<const B: () = 1, C>(C);
12+
//~^ ERROR: generic parameters with a default must be trailing
13+
//~| ERROR: mismatched types
14+
15+
struct Cond<const B: bool>;
16+
17+
struct Thing<T = Cond<0>>(T);
18+
//~^ ERROR: mismatched types
19+
20+
impl Thing {}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: generic parameters with a default must be trailing
2+
--> $DIR/lit_type_mismatch.rs:11:16
3+
|
4+
LL | struct A<const B: () = 1, C>(C);
5+
| ^
6+
7+
error[E0308]: mismatched types
8+
--> $DIR/lit_type_mismatch.rs:11:24
9+
|
10+
LL | struct A<const B: () = 1, C>(C);
11+
| ^ expected `()`, found integer
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/lit_type_mismatch.rs:17:23
15+
|
16+
LL | struct Thing<T = Cond<0>>(T);
17+
| ^ expected `bool`, found integer
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)