1
Fork 0

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
This commit is contained in:
Matthias Krüger 2025-01-09 14:34:41 +01:00 committed by GitHub
commit 8ff355aefe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 142 additions and 174 deletions

View file

@ -35,7 +35,7 @@ use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable; 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::fold::fold_regions;
use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
use rustc_middle::ty::{ use rustc_middle::ty::{
@ -2262,25 +2262,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
_ => None, _ => None,
}; };
if let Some(lit_input) = lit_input { lit_input
// If an error occurred, ignore that it's a literal and leave reporting the error up to // Allow the `ty` to be an alias type, though we cannot handle it here, we just go through
// mir. // the more expensive anon const code path.
match tcx.at(expr.span).lit_to_const(lit_input) { .filter(|l| !l.ty.has_aliases())
Ok(c) => return Some(c), .map(|l| tcx.at(expr.span).lit_to_const(l))
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
} }
fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
@ -2454,13 +2440,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::PatExprKind::Lit { lit, negated } => { hir::PatExprKind::Lit { lit, negated } => {
let lit_input = let lit_input =
LitToConstInput { lit: &lit.node, ty, neg: negated }; LitToConstInput { lit: &lit.node, ty, neg: negated };
let ct = match tcx.lit_to_const(lit_input) { let ct = 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) (ct, ty)
} }

View file

@ -16,7 +16,6 @@ use rustc_abi::{AddressSpace, Align, Endian, HasDataLayout, Size};
use rustc_ast::{LitKind, Mutability}; use rustc_ast::{LitKind, Mutability};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@ -84,16 +83,6 @@ pub struct LitToConstInput<'tcx> {
pub neg: bool, 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)] #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct AllocId(pub NonZero<u64>); pub struct AllocId(pub NonZero<u64>);

View file

@ -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> { impl EraseType for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()]; type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()];
} }
@ -296,7 +288,6 @@ trivial! {
rustc_middle::mir::interpret::AllocId, rustc_middle::mir::interpret::AllocId,
rustc_middle::mir::interpret::CtfeProvenance, rustc_middle::mir::interpret::CtfeProvenance,
rustc_middle::mir::interpret::ErrorHandled, rustc_middle::mir::interpret::ErrorHandled,
rustc_middle::mir::interpret::LitToConstError,
rustc_middle::thir::ExprId, rustc_middle::thir::ExprId,
rustc_middle::traits::CodegenObligationError, rustc_middle::traits::CodegenObligationError,
rustc_middle::traits::EvaluationResult, rustc_middle::traits::EvaluationResult,

View file

@ -57,7 +57,7 @@ use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars,
use crate::middle::stability::{self, DeprecationEntry}; use crate::middle::stability::{self, DeprecationEntry};
use crate::mir::interpret::{ use crate::mir::interpret::{
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult, EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput, EvalToValTreeResult, GlobalId, LitToConstInput,
}; };
use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem}; use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem};
use crate::query::erase::{Erase, erase, restore}; use crate::query::erase::{Erase, erase, restore};
@ -1268,7 +1268,7 @@ rustc_queries! {
// FIXME get rid of this with valtrees // FIXME get rid of this with valtrees
query lit_to_const( query lit_to_const(
key: LitToConstInput<'tcx> key: LitToConstInput<'tcx>
) -> Result<ty::Const<'tcx>, LitToConstError> { ) -> ty::Const<'tcx> {
desc { "converting literal to const" } desc { "converting literal to const" }
} }

View file

@ -3,13 +3,12 @@
use rustc_abi::Size; use rustc_abi::Size;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{Allocation, CTFE_ALLOC_SALT, LitToConstInput, Scalar};
Allocation, CTFE_ALLOC_SALT, LitToConstError, LitToConstInput, Scalar,
};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::thir::*; use rustc_middle::thir::*;
use rustc_middle::ty::{ 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 rustc_middle::{bug, mir, span_bug};
use tracing::{instrument, trace}; use tracing::{instrument, trace};
@ -50,16 +49,7 @@ pub(crate) fn as_constant_inner<'tcx>(
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
match *kind { match *kind {
ExprKind::Literal { lit, neg } => { ExprKind::Literal { lit, neg } => {
let const_ = match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) let const_ = 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`")
}
};
ConstOperand { span, user_ty: None, const_ } ConstOperand { span, user_ty: None, const_ }
} }
@ -108,11 +98,13 @@ pub(crate) fn as_constant_inner<'tcx>(
} }
#[instrument(skip(tcx, lit_input))] #[instrument(skip(tcx, lit_input))]
fn lit_to_mir_constant<'tcx>( fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>) -> Const<'tcx> {
tcx: TyCtxt<'tcx>,
lit_input: LitToConstInput<'tcx>,
) -> Result<Const<'tcx>, LitToConstError> {
let LitToConstInput { lit, ty, neg } = lit_input; 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 trunc = |n| {
let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
Ok(layout) => layout.size, 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()); trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
let result = width.truncate(n); let result = width.truncate(n);
trace!("trunc result: {}", result); 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()) { 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))) ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
} }
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { (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() })? 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::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)),
)
})?,
(ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), (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::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
(ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)), (ast::LitKind::Err(guar), _) => {
_ => return Err(LitToConstError::TypeError), 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)
} }

View file

@ -1,7 +1,7 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::bug; 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 rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _};
use tracing::trace; use tracing::trace;
@ -10,11 +10,11 @@ use crate::builder::parse_float_into_scalar;
pub(crate) fn lit_to_const<'tcx>( pub(crate) fn lit_to_const<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
lit_input: LitToConstInput<'tcx>, lit_input: LitToConstInput<'tcx>,
) -> Result<ty::Const<'tcx>, LitToConstError> { ) -> ty::Const<'tcx> {
let LitToConstInput { lit, ty, neg } = lit_input; let LitToConstInput { lit, ty, neg } = lit_input;
if let Err(guar) = ty.error_reported() { 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| { let trunc = |n| {
@ -28,8 +28,8 @@ pub(crate) fn lit_to_const<'tcx>(
let result = width.truncate(n); let result = width.truncate(n);
trace!("trunc result: {}", result); trace!("trunc result: {}", result);
Ok(ScalarInt::try_from_uint(result, width) ScalarInt::try_from_uint(result, width)
.unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result))) .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result))
}; };
let valtree = match (lit, ty.kind()) { let valtree = match (lit, ty.kind()) {
@ -57,20 +57,20 @@ pub(crate) fn lit_to_const<'tcx>(
} }
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => { (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
let scalar_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) ty::ValTree::from_scalar_int(scalar_int)
} }
(ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
(ast::LitKind::Float(n, _), ty::Float(fty)) => { (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)) tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit))
})?; });
ty::ValTree::from_scalar_int(bits) ty::ValTree::from_scalar_int(bits)
} }
(ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), (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 ty::Const::new_error(tcx, *guar),
_ => return Err(LitToConstError::TypeError), _ => return ty::Const::new_misc_error(tcx),
}; };
Ok(ty::Const::new_value(tcx, valtree, ty)) ty::Const::new_value(tcx, valtree, ty)
} }

View file

@ -13,7 +13,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd}; use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd};
use rustc_index::Idx; use rustc_index::Idx;
use rustc_lint as lint; use rustc_lint as lint;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::mir::interpret::LitToConstInput;
use rustc_middle::thir::{ use rustc_middle::thir::{
Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
}; };
@ -669,11 +669,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let ct_ty = self.typeck_results.node_type(expr.hir_id); let ct_ty = self.typeck_results.node_type(expr.hir_id);
let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg }; let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
match self.tcx.at(expr.span).lit_to_const(lit_input) { let constant = 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, 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"),
}
} }
} }

View file

@ -4,7 +4,7 @@ use rustc_abi::{FIRST_VARIANT, VariantIdx};
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId; 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::query::Providers;
use rustc_middle::thir::visit; use rustc_middle::thir::visit;
use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::visit::Visitor;
@ -118,13 +118,7 @@ fn recurse_build<'tcx>(
} }
&ExprKind::Literal { lit, neg } => { &ExprKind::Literal { lit, neg } => {
let sp = node.span; let sp = node.span;
match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { 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")
}
}
} }
&ExprKind::NonHirLiteral { lit, user_ty: _ } => { &ExprKind::NonHirLiteral { lit, user_ty: _ } => {
let val = ty::ValTree::from_scalar_int(lit); let val = ty::ValTree::from_scalar_int(lit);

View file

@ -1,6 +0,0 @@
//@ known-bug: #114317
#![feature(generic_const_exprs)]
struct A<const B: str = 1, C>;
fn main() {}

View file

@ -1,10 +0,0 @@
//@ known-bug: rust-lang/rust#126182
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
struct Cond<const B: bool>;
struct Thing<T = Cond<0>>(T);
impl Thing {}

View file

@ -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() {}

View file

@ -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`.

View file

@ -1,27 +1,3 @@
error[E0308]: mismatched types
--> $DIR/invalid-patterns.rs:29:21
|
LL | get_flag::<false, 0xFF>();
| ^^^^ 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 error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:38:32 --> $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 } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0308]: mismatched types
--> $DIR/invalid-patterns.rs:29:21
|
LL | get_flag::<false, 0xFF>();
| ^^^^ 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 error: aborting due to 8 previous errors
Some errors have detailed explanations: E0080, E0308. Some errors have detailed explanations: E0080, E0308.

View file

@ -1,27 +1,3 @@
error[E0308]: mismatched types
--> $DIR/invalid-patterns.rs:29:21
|
LL | get_flag::<false, 0xFF>();
| ^^^^ 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 error[E0080]: evaluation of constant value failed
--> $DIR/invalid-patterns.rs:38:32 --> $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 } }>(); LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
| ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | ^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0308]: mismatched types
--> $DIR/invalid-patterns.rs:29:21
|
LL | get_flag::<false, 0xFF>();
| ^^^^ 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 error: aborting due to 8 previous errors
Some errors have detailed explanations: E0080, E0308. Some errors have detailed explanations: E0080, E0308.

View file

@ -15,6 +15,12 @@ error[E0308]: mismatched types
LL | let b = [0; ()]; LL | let b = [0; ()];
| ^^ expected `usize`, found `()` | ^^ 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 error[E0308]: mismatched types
--> $DIR/repeat_count.rs:10:17 --> $DIR/repeat_count.rs:10:17
| |
@ -33,12 +39,6 @@ error[E0308]: mismatched types
LL | let e = [0; "foo"]; LL | let e = [0; "foo"];
| ^^^^^ expected `usize`, found `&str` | ^^^^^ 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 error[E0308]: mismatched types
--> $DIR/repeat_count.rs:19:17 --> $DIR/repeat_count.rs:19:17
| |