Skip to content

Commit

Permalink
Unrolled build for rust-lang#135195
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#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 rust-lang#114317
fixes rust-lang#126182
  • Loading branch information
rust-timer authored Jan 9, 2025
2 parents 251206c + 84c8d4f commit 49017c7
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 175 deletions.
34 changes: 7 additions & 27 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -2262,25 +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.
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:?}"),
);
}
}
}

None
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.
.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> {
Expand Down Expand Up @@ -2454,13 +2440,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::Reported(err)) => {
ty::Const::new_error(tcx, err)
}
Err(LitToConstError::TypeError) => todo!(),
};
let ct = tcx.lit_to_const(lit_input);
(ct, ty)
}

Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -84,16 +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,
Reported(ErrorGuaranteed),
}

#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct AllocId(pub NonZero<u64>);

Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,6 @@ impl EraseType for Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::Layou
>()];
}

impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> {
type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()];
}

impl EraseType for Result<mir::Const<'_>, mir::interpret::LitToConstError> {
type Result = [u8; size_of::<Result<mir::Const<'static>, mir::interpret::LitToConstError>>()];
}

impl EraseType for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()];
}
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -1268,7 +1268,7 @@ rustc_queries! {
// FIXME get rid of this with valtrees
query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<ty::Const<'tcx>, LitToConstError> {
) -> ty::Const<'tcx> {
desc { "converting literal to const" }
}

Expand Down
52 changes: 21 additions & 31 deletions compiler/rustc_mir_build/src/builder/expr/as_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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_ }
}
Expand Down Expand Up @@ -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<Const<'tcx>, 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,
Expand All @@ -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()) {
Expand Down Expand Up @@ -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)
}
22 changes: 11 additions & 11 deletions compiler/rustc_mir_build/src/thir/constant.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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<ty::Const<'tcx>, 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| {
Expand All @@ -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()) {
Expand Down Expand Up @@ -57,20 +57,20 @@ 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()),
(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)),
_ => return Err(LitToConstError::TypeError),
(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)
}
9 changes: 3 additions & 6 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -669,11 +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::Reported(e)) => PatKind::Error(e),
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
}
}

Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_ty_utils/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -118,13 +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::Reported(guar)) => ty::Const::new_error(tcx, guar),
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);
Expand Down
6 changes: 0 additions & 6 deletions tests/crashes/114317.rs

This file was deleted.

10 changes: 0 additions & 10 deletions tests/crashes/126182.rs

This file was deleted.

22 changes: 22 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs
Original file line number Diff line number Diff line change
@@ -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<const B: () = 1, C>(C);
//~^ ERROR: generic parameters with a default must be trailing
//~| ERROR: mismatched types

struct Cond<const B: bool>;

struct Thing<T = Cond<0>>(T);
//~^ ERROR: mismatched types

impl Thing {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: generic parameters with a default must be trailing
--> $DIR/lit_type_mismatch.rs:11:16
|
LL | struct A<const B: () = 1, C>(C);
| ^

error[E0308]: mismatched types
--> $DIR/lit_type_mismatch.rs:11:24
|
LL | struct A<const B: () = 1, C>(C);
| ^ expected `()`, found integer

error[E0308]: mismatched types
--> $DIR/lit_type_mismatch.rs:17:23
|
LL | struct Thing<T = Cond<0>>(T);
| ^ expected `bool`, found integer

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
Loading

0 comments on commit 49017c7

Please sign in to comment.