From 5898b00ba49379f9dba4b931d9e61403c1296a9e Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Tue, 3 Feb 2026 01:08:44 +0900 Subject: [PATCH 1/2] mGCA: Validate const literal against expected type Co-authored-by: Boxy --- .../src/hir_ty_lowering/mod.rs | 27 ++++-- .../rustc_middle/src/mir/interpret/mod.rs | 38 ++++++++ compiler/rustc_middle/src/queries.rs | 2 +- compiler/rustc_middle/src/query/erase.rs | 4 + compiler/rustc_mir_build/src/thir/constant.rs | 89 ++++++++++++------- .../rustc_mir_build/src/thir/pattern/mod.rs | 25 +++++- compiler/rustc_ty_utils/src/consts.rs | 5 +- .../byte-string-u8-validation.rs | 2 +- .../byte-string-u8-validation.stderr | 18 ++-- .../mismatch-raw-ptr-in-adt.stderr | 8 +- .../mgca/generic_const_type_mismatch.rs | 20 +++++ .../mgca/generic_const_type_mismatch.stderr | 8 ++ .../mgca/nonsensical-negated-literal.rs | 26 ++++++ .../mgca/nonsensical-negated-literal.stderr | 38 ++++++++ .../mgca/tuple_expr_type_mismatch.rs | 22 +++++ .../mgca/tuple_expr_type_mismatch.stderr | 38 ++++++++ .../mgca/type_const-mismatched-types.rs | 1 - .../mgca/type_const-mismatched-types.stderr | 10 +-- .../invalid-patterns.32bit.stderr | 52 +++++------ .../invalid-patterns.64bit.stderr | 48 +++++----- tests/ui/issues/issue-34373.rs | 1 + tests/ui/issues/issue-34373.stderr | 23 ++++- tests/ui/repeat-expr/repeat_count.stderr | 12 +-- ...ce-hir-wf-check-anon-const-issue-122989.rs | 2 + ...ir-wf-check-anon-const-issue-122989.stderr | 22 ++++- 25 files changed, 410 insertions(+), 131 deletions(-) create mode 100644 tests/ui/const-generics/mgca/generic_const_type_mismatch.rs create mode 100644 tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr create mode 100644 tests/ui/const-generics/mgca/nonsensical-negated-literal.rs create mode 100644 tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr create mode 100644 tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs create mode 100644 tests/ui/const-generics/mgca/tuple_expr_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 f58461e5d0e13..e22aa990c3e7e 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_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::DynCompatibilityViolation; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::middle::stability::AllowUnstable; -use rustc_middle::mir::interpret::LitToConstInput; +use rustc_middle::mir::interpret::{LitToConstInput, const_lit_matches_ty}; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, @@ -2803,8 +2803,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Const<'tcx> { let tcx = self.tcx(); + if let LitKind::Err(guar) = *kind { + return ty::Const::new_error(tcx, guar); + } let input = LitToConstInput { lit: *kind, ty, neg }; - tcx.at(span).lit_to_const(input) + match tcx.at(span).lit_to_const(input) { + Some(value) => ty::Const::new_value(tcx, value.valtree, value.ty), + None => { + let e = tcx.dcx().span_err(span, "type annotations needed for the literal"); + ty::Const::new_error(tcx, e) + } + } } #[instrument(skip(self), level = "debug")] @@ -2833,11 +2842,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { _ => 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)) + lit_input.and_then(|l| { + if const_lit_matches_ty(tcx, &l.lit, l.ty, l.neg) { + tcx.at(expr.span) + .lit_to_const(l) + .map(|value| ty::Const::new_value(tcx, value.valtree, value.ty)) + } else { + None + } + }) } fn require_type_const_attribute( diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 9762e0f21da9f..f31610cd5e142 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -84,6 +84,44 @@ pub struct LitToConstInput<'tcx> { pub neg: bool, } +pub fn const_lit_matches_ty<'tcx>( + tcx: TyCtxt<'tcx>, + kind: &LitKind, + ty: Ty<'tcx>, + neg: bool, +) -> bool { + match (*kind, ty.kind()) { + (LitKind::Str(..), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => true, + (LitKind::Str(..), ty::Str) if tcx.features().deref_patterns() => true, + (LitKind::ByteStr(..), ty::Ref(_, inner_ty, _)) + if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind() + && matches!(ty.kind(), ty::Uint(ty::UintTy::U8)) => + { + true + } + (LitKind::ByteStr(..), ty::Slice(inner_ty) | ty::Array(inner_ty, _)) + if tcx.features().deref_patterns() + && matches!(inner_ty.kind(), ty::Uint(ty::UintTy::U8)) => + { + true + } + (LitKind::Byte(..), ty::Uint(ty::UintTy::U8)) => true, + (LitKind::CStr(..), ty::Ref(_, inner_ty, _)) + if matches!(inner_ty.kind(), ty::Adt(def, _) + if tcx.is_lang_item(def.did(), rustc_hir::LangItem::CStr)) => + { + true + } + (LitKind::Int(..), ty::Uint(_)) if !neg => true, + (LitKind::Int(..), ty::Int(_)) => true, + (LitKind::Bool(..), ty::Bool) => true, + (LitKind::Float(..), ty::Float(_)) => true, + (LitKind::Char(..), ty::Char) => true, + (LitKind::Err(..), _) => true, + _ => false, + } +} + #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct AllocId(pub NonZero); diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 771c300989f2a..60a03cc66d72b 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1412,7 +1412,7 @@ rustc_queries! { // FIXME get rid of this with valtrees query lit_to_const( key: LitToConstInput<'tcx> - ) -> ty::Const<'tcx> { + ) -> Option> { desc { "converting literal to const" } } diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 99b1f6d8c2515..fe0368525e277 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -256,6 +256,10 @@ impl Erasable for Option>> { type Storage = [u8; size_of::>>>()]; } +impl Erasable for Option> { + type Storage = [u8; size_of::>>()]; +} + impl Erasable for rustc_hir::MaybeOwner<'_> { type Storage = [u8; size_of::>()]; } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 96248499044aa..6b93cf8ec8f49 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -3,7 +3,7 @@ use rustc_ast::{self as ast, UintTy}; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::mir::interpret::LitToConstInput; -use rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _}; +use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt as _}; use tracing::trace; use crate::builder::parse_float_into_scalar; @@ -11,11 +11,11 @@ use crate::builder::parse_float_into_scalar; pub(crate) fn lit_to_const<'tcx>( tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>, -) -> ty::Const<'tcx> { - let LitToConstInput { lit, ty, neg } = lit_input; +) -> Option> { + let LitToConstInput { lit, ty: expected_ty, neg } = lit_input; - if let Err(guar) = ty.error_reported() { - return ty::Const::new_error(tcx, guar); + if expected_ty.error_reported().is_err() { + return None; } let trunc = |n, width: ty::UintTy| { @@ -32,22 +32,17 @@ pub(crate) fn lit_to_const<'tcx>( .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)) }; - let valtree = match (lit, ty.kind()) { - (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { + let (valtree, valtree_ty) = match (lit, expected_ty.kind()) { + (ast::LitKind::Str(s, _), _) => { let str_bytes = s.as_str().as_bytes(); - ty::ValTree::from_raw_bytes(tcx, str_bytes) - } - (ast::LitKind::Str(s, _), ty::Str) if tcx.features().deref_patterns() => { - // String literal patterns may have type `str` if `deref_patterns` is enabled, in order - // to allow `deref!("..."): String`. - let str_bytes = s.as_str().as_bytes(); - ty::ValTree::from_raw_bytes(tcx, str_bytes) + let valtree_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_); + (ty::ValTree::from_raw_bytes(tcx, str_bytes), valtree_ty) } (ast::LitKind::ByteStr(byte_sym, _), ty::Ref(_, inner_ty, _)) if let ty::Slice(ty) | ty::Array(ty, _) = inner_ty.kind() && let ty::Uint(UintTy::U8) = ty.kind() => { - ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()) + (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty) } (ast::LitKind::ByteStr(byte_sym, _), ty::Slice(inner_ty) | ty::Array(inner_ty, _)) if tcx.features().deref_patterns() @@ -55,40 +50,66 @@ pub(crate) fn lit_to_const<'tcx>( { // Byte string literal patterns may have type `[u8]` or `[u8; N]` if `deref_patterns` is // enabled, in order to allow, e.g., `deref!(b"..."): Vec`. - ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()) + (ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()), expected_ty) } - (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { - ty::ValTree::from_scalar_int(tcx, n.into()) + (ast::LitKind::ByteStr(byte_sym, _), _) => { + let valtree = ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()); + let valtree_ty = Ty::new_array(tcx, tcx.types.u8, byte_sym.as_byte_str().len() as u64); + (valtree, valtree_ty) } - (ast::LitKind::CStr(byte_sym, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) => + (ast::LitKind::Byte(n), _) => (ty::ValTree::from_scalar_int(tcx, n.into()), tcx.types.u8), + (ast::LitKind::CStr(byte_sym, _), _) + if let Some(cstr_def_id) = tcx.lang_items().get(LangItem::CStr) => { // A CStr is a newtype around a byte slice, so we create the inner slice here. // We need a branch for each "level" of the data structure. + let cstr_ty = tcx.type_of(cstr_def_id).skip_binder(); let bytes = ty::ValTree::from_raw_bytes(tcx, byte_sym.as_byte_str()); - ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, bytes, *inner_ty)]) + let valtree = + ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, bytes, cstr_ty)]); + let valtree_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, cstr_ty); + (valtree, valtree_ty) } - (ast::LitKind::Int(n, _), ty::Uint(ui)) if !neg => { + (ast::LitKind::Int(n, ast::LitIntType::Unsigned(ui)), _) if !neg => { + let scalar_int = trunc(n.get(), ui); + (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_uint(tcx, ui)) + } + (ast::LitKind::Int(_, ast::LitIntType::Unsigned(_)), _) if neg => return None, + (ast::LitKind::Int(n, ast::LitIntType::Signed(i)), _) => { + let scalar_int = + trunc(if neg { u128::wrapping_neg(n.get()) } else { n.get() }, i.to_unsigned()); + (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_int(tcx, i)) + } + (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), ty::Uint(ui)) if !neg => { let scalar_int = trunc(n.get(), *ui); - ty::ValTree::from_scalar_int(tcx, scalar_int) + (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_uint(tcx, *ui)) } - (ast::LitKind::Int(n, _), ty::Int(i)) => { + (ast::LitKind::Int(n, ast::LitIntType::Unsuffixed), ty::Int(i)) => { // Unsigned "negation" has the same bitwise effect as signed negation, // which gets the result we want without additional casts. let scalar_int = trunc(if neg { u128::wrapping_neg(n.get()) } else { n.get() }, i.to_unsigned()); - ty::ValTree::from_scalar_int(tcx, scalar_int) + (ty::ValTree::from_scalar_int(tcx, scalar_int), Ty::new_int(tcx, *i)) + } + (ast::LitKind::Bool(b), _) => (ty::ValTree::from_scalar_int(tcx, b.into()), tcx.types.bool), + (ast::LitKind::Float(n, ast::LitFloatType::Suffixed(fty)), _) => { + let fty = match fty { + ast::FloatTy::F16 => ty::FloatTy::F16, + ast::FloatTy::F32 => ty::FloatTy::F32, + ast::FloatTy::F64 => ty::FloatTy::F64, + ast::FloatTy::F128 => ty::FloatTy::F128, + }; + let bits = parse_float_into_scalar(n, fty, neg)?; + (ty::ValTree::from_scalar_int(tcx, bits), Ty::new_float(tcx, fty)) } - (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int(tcx, b.into()), - (ast::LitKind::Float(n, _), ty::Float(fty)) => { - 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(tcx, bits) + (ast::LitKind::Float(n, ast::LitFloatType::Unsuffixed), ty::Float(fty)) => { + let bits = parse_float_into_scalar(n, *fty, neg)?; + (ty::ValTree::from_scalar_int(tcx, bits), Ty::new_float(tcx, *fty)) } - (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int(tcx, c.into()), - (ast::LitKind::Err(guar), _) => return ty::Const::new_error(tcx, guar), - _ => return ty::Const::new_misc_error(tcx), + (ast::LitKind::Char(c), _) => (ty::ValTree::from_scalar_int(tcx, c.into()), tcx.types.char), + (ast::LitKind::Err(_), _) => return None, + _ => return None, }; - ty::Const::new_value(tcx, valtree, ty) + Some(ty::Value { ty: valtree_ty, valtree }) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 3641561567bce..dfc3e4e7e3a7a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -8,13 +8,14 @@ use std::cmp::Ordering; use std::sync::Arc; use rustc_abi::{FieldIdx, Integer}; +use rustc_ast::LitKind; use rustc_data_structures::assert_matches; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, RangeEnd}; use rustc_index::Idx; -use rustc_middle::mir::interpret::LitToConstInput; +use rustc_middle::mir::interpret::{LitToConstInput, const_lit_matches_ty}; use rustc_middle::thir::{ Ascription, DerefPatBorrowMode, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary, }; @@ -197,8 +198,6 @@ impl<'tcx> PatCtxt<'tcx> { expr: Option<&'tcx hir::PatExpr<'tcx>>, ty: Ty<'tcx>, ) -> Result<(), ErrorGuaranteed> { - use rustc_ast::ast::LitKind; - let Some(expr) = expr else { return Ok(()); }; @@ -696,7 +695,25 @@ impl<'tcx> PatCtxt<'tcx> { let pat_ty = self.typeck_results.node_type(pat.hir_id); let lit_input = LitToConstInput { lit: lit.node, ty: pat_ty, neg: *negated }; - let constant = self.tcx.at(expr.span).lit_to_const(lit_input); + let error_const = || { + if let Some(guar) = self.typeck_results.tainted_by_errors { + ty::Const::new_error(self.tcx, guar) + } else { + ty::Const::new_error_with_message( + self.tcx, + expr.span, + "literal does not match expected type", + ) + } + }; + let constant = if const_lit_matches_ty(self.tcx, &lit.node, pat_ty, *negated) { + match self.tcx.at(expr.span).lit_to_const(lit_input) { + Some(value) => ty::Const::new_value(self.tcx, value.valtree, pat_ty), + None => error_const(), + } + } else { + error_const() + }; self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span) } } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index f6d08bd458bdd..5029b33e5b6c2 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -59,7 +59,10 @@ fn recurse_build<'tcx>( } &ExprKind::Literal { lit, neg } => { let sp = node.span; - tcx.at(sp).lit_to_const(LitToConstInput { lit: lit.node, ty: node.ty, neg }) + match tcx.at(sp).lit_to_const(LitToConstInput { lit: lit.node, ty: node.ty, neg }) { + Some(value) => ty::Const::new_value(tcx, value.valtree, value.ty), + None => ty::Const::new_misc_error(tcx), + } } &ExprKind::NonHirLiteral { lit, user_ty: _ } => { let val = ty::ValTree::from_scalar_int(tcx, lit); diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs index 703e63ae047ff..063a38c8aa01d 100644 --- a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs @@ -8,7 +8,7 @@ struct ConstBytes //~^ ERROR rustc_dump_predicates //~| NOTE Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } -//~| NOTE Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } +//~| NOTE Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } where ConstBytes: Sized; //~^ ERROR mismatched types diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr index f5f8a420a703e..d4b8ac7f021d0 100644 --- a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr @@ -1,12 +1,3 @@ -error: rustc_dump_predicates - --> $DIR/byte-string-u8-validation.rs:8:1 - | -LL | struct ConstBytes - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } - = note: Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } - error[E0308]: mismatched types --> $DIR/byte-string-u8-validation.rs:13:16 | @@ -16,6 +7,15 @@ LL | ConstBytes: Sized; = note: expected reference `&'static [*mut u8; 3]` found reference `&'static [u8; 3]` +error: rustc_dump_predicates + --> $DIR/byte-string-u8-validation.rs:8:1 + | +LL | struct ConstBytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } + = note: Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr index 717e680ee5368..d7eec45bae0f3 100644 --- a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr +++ b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr @@ -8,19 +8,19 @@ LL | struct ConstBytes; = note: `[*mut u8; 3]` must implement `ConstParamTy_`, but it does not error[E0308]: mismatched types - --> $DIR/mismatch-raw-ptr-in-adt.rs:9:46 + --> $DIR/mismatch-raw-ptr-in-adt.rs:9:23 | LL | let _: ConstBytes = ConstBytes::; - | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` | = note: expected reference `&'static [*mut u8; 3]` found reference `&'static [u8; 3]` error[E0308]: mismatched types - --> $DIR/mismatch-raw-ptr-in-adt.rs:9:23 + --> $DIR/mismatch-raw-ptr-in-adt.rs:9:46 | LL | let _: ConstBytes = ConstBytes::; - | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` | = note: expected reference `&'static [*mut u8; 3]` found reference `&'static [u8; 3]` diff --git a/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs new file mode 100644 index 0000000000000..ffde84522a269 --- /dev/null +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs @@ -0,0 +1,20 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature( + generic_const_items, + generic_const_parameter_types, + min_generic_const_args, + unsized_const_params +)] +use std::marker::ConstParamTy_; + +struct Foo { + field: T, +} + +#[type_const] +const WRAP : T = { + Foo::{field : 1} //~ ERROR: type annotations needed for the literal +}; + +fn main() {} diff --git a/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr new file mode 100644 index 0000000000000..10e37b327eec2 --- /dev/null +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr @@ -0,0 +1,8 @@ +error: type annotations needed for the literal + --> $DIR/generic_const_type_mismatch.rs:17:22 + | +LL | Foo::{field : 1} + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs new file mode 100644 index 0000000000000..cd68a2c0d4301 --- /dev/null +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs @@ -0,0 +1,26 @@ +#![feature(adt_const_params, min_generic_const_args)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo { + field: isize +} + +fn foo() {} + +fn main() { + foo::<{ Foo { field: -1_usize } }>(); + //~^ ERROR: type annotations needed for the literal + foo::<{ Foo { field: { -1_usize } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + foo::<{ Foo { field: -true } }>(); + //~^ ERROR: the constant `true` is not of type `isize` + foo::<{ Foo { field: { -true } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + foo::<{ Foo { field: -"<3" } }>(); + //~^ ERROR: the constant `"<3"` is not of type `isize` + foo::<{ Foo { field: { -"<3" } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr new file mode 100644 index 0000000000000..43ed4b71e33e7 --- /dev/null +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr @@ -0,0 +1,38 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:16:26 + | +LL | foo::<{ Foo { field: { -1_usize } } }>(); + | ^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:20:26 + | +LL | foo::<{ Foo { field: { -true } } }>(); + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:24:26 + | +LL | foo::<{ Foo { field: { -"<3" } } }>(); + | ^^^^^^^^^ + +error: type annotations needed for the literal + --> $DIR/nonsensical-negated-literal.rs:14:26 + | +LL | foo::<{ Foo { field: -1_usize } }>(); + | ^^^^^^^^ + +error: the constant `true` is not of type `isize` + --> $DIR/nonsensical-negated-literal.rs:18:13 + | +LL | foo::<{ Foo { field: -true } }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `"<3"` is not of type `isize` + --> $DIR/nonsensical-negated-literal.rs:22:13 + | +LL | foo::<{ Foo { field: -"<3" } }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&'static str` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs new file mode 100644 index 0000000000000..373cce1d62201 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs @@ -0,0 +1,22 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature( + adt_const_params, + min_generic_const_args, + unsized_const_params +)] +fn foo() {} +fn bar() {} +fn qux() {} + +fn main() { + foo::<{ (1, true) }>(); + //~^ ERROR: type annotations needed for the literal + //~| ERROR: mismatched types: expected `i32`, found `bool` + bar::<{ (1_u32, [1, 2]) }>(); + //~^ ERROR: expected `i32`, found const array + //~| ERROR: mismatched types: expected `[u8; 2]`, found `u32` + qux::<{ (1i32, 'a') }>(); + //~^ ERROR: mismatched types: expected `char`, found `i32` + //~| ERROR: mismatched types: expected `i32`, found `char` +} diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr new file mode 100644 index 0000000000000..13e2789ccb67a --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr @@ -0,0 +1,38 @@ +error: type annotations needed for the literal + --> $DIR/tuple_expr_type_mismatch.rs:13:14 + | +LL | foo::<{ (1, true) }>(); + | ^ + +error: mismatched types: expected `i32`, found `bool` + --> $DIR/tuple_expr_type_mismatch.rs:13:17 + | +LL | foo::<{ (1, true) }>(); + | ^^^^ + +error: mismatched types: expected `[u8; 2]`, found `u32` + --> $DIR/tuple_expr_type_mismatch.rs:16:14 + | +LL | bar::<{ (1_u32, [1, 2]) }>(); + | ^^^^^ + +error: expected `i32`, found const array + --> $DIR/tuple_expr_type_mismatch.rs:16:21 + | +LL | bar::<{ (1_u32, [1, 2]) }>(); + | ^^^^^^ + +error: mismatched types: expected `char`, found `i32` + --> $DIR/tuple_expr_type_mismatch.rs:19:14 + | +LL | qux::<{ (1i32, 'a') }>(); + | ^^^^ + +error: mismatched types: expected `i32`, found `char` + --> $DIR/tuple_expr_type_mismatch.rs:19:20 + | +LL | qux::<{ (1i32, 'a') }>(); + | ^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs index 460c5d7b21998..deac97383b04a 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -5,7 +5,6 @@ type const FREE: u32 = 5_usize; //~^ ERROR mismatched types type const FREE2: isize = FREE; -//~^ ERROR the constant `5` is not of type `isize` trait Tr { type const N: usize; diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr index 152dd9ec0cca1..1c04ac5085693 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -1,9 +1,3 @@ -error: the constant `5` is not of type `isize` - --> $DIR/type_const-mismatched-types.rs:7:1 - | -LL | type const FREE2: isize = FREE; - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` - error[E0308]: mismatched types --> $DIR/type_const-mismatched-types.rs:4:24 | @@ -17,11 +11,11 @@ LL + type const FREE: u32 = 5_u32; | error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:15:27 + --> $DIR/type_const-mismatched-types.rs:18:22 | LL | type const N: usize = false; | ^^^^^ expected `usize`, found `bool` -error: aborting due to 3 previous errors +error: aborting due to 2 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 cc6a813b747d9..b85856db9287e 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,4 +1,28 @@ -error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + +error[E0080]: reading memory at ALLOC6[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::(); @@ -30,7 +54,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character 42 │ B } -error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory +error[E0080]: reading memory at ALLOC12[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:44:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); @@ -40,30 +64,6 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character ff __ __ __ │ .░░░ } -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35: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 cc6a813b747d9..df7c2a0a86292 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,3 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | @@ -40,30 +64,6 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character ff __ __ __ │ .░░░ } -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35: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/issues/issue-34373.rs b/tests/ui/issues/issue-34373.rs index 5b05811a4eb3f..019cab42c6433 100644 --- a/tests/ui/issues/issue-34373.rs +++ b/tests/ui/issues/issue-34373.rs @@ -6,6 +6,7 @@ trait Trait { pub struct Foo>>; //~ ERROR cycle detected //~^ ERROR `T` is never used +//~| ERROR cycle detected type DefaultFoo = Foo; fn main() { diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 03d7719313416..49365a701ceee 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -5,7 +5,26 @@ LL | pub struct Foo>>; | ^^^^^^^^^^ | note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:9:19 + --> $DIR/issue-34373.rs:10:1 + | +LL | type DefaultFoo = Foo; + | ^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `Foo::T`, completing the cycle +note: cycle used when checking that `Foo` is well-formed + --> $DIR/issue-34373.rs:7:1 + | +LL | pub struct Foo>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `Foo::T` + --> $DIR/issue-34373.rs:7:34 + | +LL | pub struct Foo>>; + | ^^^^^^^^^^ + | +note: ...which requires expanding type alias `DefaultFoo`... + --> $DIR/issue-34373.rs:10:19 | LL | type DefaultFoo = Foo; | ^^^ @@ -26,7 +45,7 @@ LL | pub struct Foo>>; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0391, E0392. For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index cf94ad41ee363..8d8702e981e6f 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -16,12 +16,6 @@ error[E0308]: mismatched types LL | let b = [0; ()]; | ^^ expected `usize`, found `()` -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:33:17 - | -LL | let g = [0; G { g: () }]; - | ^^^^^^^^^^^ expected `usize`, found `G` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:12:17 | @@ -68,6 +62,12 @@ LL - let f = [0; 4u8]; LL + let f = [0; 4usize]; | +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:33:17 + | +LL | let g = [0; G { g: () }]; + | ^^^^^^^^^^^ expected `usize`, found `G` + error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0435. diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index f2b9f037ea5f3..13d7a800c51fd 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -4,11 +4,13 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` + //~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter fn func() {} } trait Bar> {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//~| ERROR `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index 4024f57af4ffd..f9a855d3b93b7 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -13,7 +13,7 @@ LL | trait Foo> { | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 | LL | trait Bar> {} | ^^^^^^ @@ -32,7 +32,7 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^ | note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 | LL | trait Bar> {} | ^^^^^^^^^^^^^^^ @@ -44,6 +44,22 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error; 2 warnings emitted +error: `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:20 + | +LL | trait Foo> { + | ^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 + | +LL | trait Bar> {} + | ^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: aborting due to 3 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0391`. From 177b1b0b8051f2c9570da5f64f8cbbc584da29b6 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Tue, 10 Feb 2026 16:01:13 +0000 Subject: [PATCH 2/2] modify error comment and bless test, delete tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs --- tests/crashes/133966.rs | 3 -- .../byte-string-u8-validation.rs | 2 + .../byte-string-u8-validation.stderr | 2 +- .../generic_const_exprs/issue-105257.rs | 6 +-- .../generic_const_exprs/lit_type_mismatch.rs | 22 ----------- .../lit_type_mismatch.stderr | 21 ---------- .../mgca/generic_const_type_mismatch.rs | 7 ++-- .../mgca/generic_const_type_mismatch.stderr | 6 +-- .../mgca/tuple_expr_type_mismatch.rs | 6 +-- .../mgca/tuple_expr_type_mismatch.stderr | 28 ++++--------- .../mgca/type_const-mismatched-types.rs | 4 +- .../mgca/type_const-mismatched-types.stderr | 26 +++++++++---- .../invalid-patterns.32bit.stderr | 4 +- .../type-dependent/type-mismatch.full.stderr | 14 ++++++- .../type-dependent/type-mismatch.min.stderr | 14 ++++++- .../type-dependent/type-mismatch.rs | 3 +- .../const-eval/array-len-mismatch-type.rs | 8 ++++ .../const-eval/array-len-mismatch-type.stderr | 39 +++++++++++++++++++ tests/ui/issues/issue-34373.rs | 6 +-- tests/ui/issues/issue-34373.stderr | 21 +--------- tests/ui/repeat-expr/repeat_count.rs | 19 +++++---- tests/ui/repeat-expr/repeat_count.stderr | 34 +++++++++------- 22 files changed, 158 insertions(+), 137 deletions(-) delete mode 100644 tests/crashes/133966.rs delete mode 100644 tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs delete mode 100644 tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr create mode 100644 tests/ui/consts/const-eval/array-len-mismatch-type.rs create mode 100644 tests/ui/consts/const-eval/array-len-mismatch-type.stderr diff --git a/tests/crashes/133966.rs b/tests/crashes/133966.rs deleted file mode 100644 index 25a881ae99b4f..0000000000000 --- a/tests/crashes/133966.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ known-bug: #133966 -pub struct Data([[&'static str]; 5_i32]); -const _: &'static Data = unsafe { &*(&[] as *const Data) }; diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs index 063a38c8aa01d..d49fb49d253cb 100644 --- a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs @@ -9,10 +9,12 @@ struct ConstBytes //~^ ERROR rustc_dump_predicates //~| NOTE Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } //~| NOTE Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } + where ConstBytes: Sized; //~^ ERROR mismatched types //~| NOTE expected `&[*mut u8; 3]`, found `&[u8; 3]` //~| NOTE expected reference `&'static [*mut u8; 3]` +//~| NOTE found reference `&'static [u8; 3]` fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr index d4b8ac7f021d0..1273a74102a24 100644 --- a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/byte-string-u8-validation.rs:13:16 + --> $DIR/byte-string-u8-validation.rs:14:16 | LL | ConstBytes: Sized; | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs index 85a28f2b3303b..947410cbe0dcc 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs @@ -2,9 +2,9 @@ #![expect(incomplete_features)] trait Trait { - fn fnc(&self) {} //~ERROR defaults for generic parameters are not allowed here - //~^ ERROR: mismatched types - fn foo() }>(&self) {} //~ERROR defaults for generic parameters are not allowed here + fn fnc(&self) {} //~ ERROR defaults for generic parameters are not allowed here + //~^ ERROR mismatched types + fn foo() }>(&self) {} //~ ERROR defaults for generic parameters are not allowed here } fn main() {} 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 deleted file mode 100644 index 1ed0965e1bde1..0000000000000 --- a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! 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 deleted file mode 100644 index e4613e498b275..0000000000000 --- a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr +++ /dev/null @@ -1,21 +0,0 @@ -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/mgca/generic_const_type_mismatch.rs b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs index ffde84522a269..948b8ce72148f 100644 --- a/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs @@ -1,6 +1,7 @@ //! Regression test for #![expect(incomplete_features)] #![feature( + adt_const_params, generic_const_items, generic_const_parameter_types, min_generic_const_args, @@ -12,9 +13,7 @@ struct Foo { field: T, } -#[type_const] -const WRAP : T = { - Foo::{field : 1} //~ ERROR: type annotations needed for the literal -}; +type const WRAP : T = Foo::{field : 1}; +//~^ ERROR: type annotations needed for the literal fn main() {} diff --git a/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr index 10e37b327eec2..fdb0995bff5d4 100644 --- a/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr @@ -1,8 +1,8 @@ error: type annotations needed for the literal - --> $DIR/generic_const_type_mismatch.rs:17:22 + --> $DIR/generic_const_type_mismatch.rs:16:59 | -LL | Foo::{field : 1} - | ^ +LL | type const WRAP : T = Foo::{field : 1}; + | ^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs index 373cce1d62201..4bf62b3a30708 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs @@ -12,11 +12,9 @@ fn qux() {} fn main() { foo::<{ (1, true) }>(); //~^ ERROR: type annotations needed for the literal - //~| ERROR: mismatched types: expected `i32`, found `bool` bar::<{ (1_u32, [1, 2]) }>(); //~^ ERROR: expected `i32`, found const array - //~| ERROR: mismatched types: expected `[u8; 2]`, found `u32` qux::<{ (1i32, 'a') }>(); - //~^ ERROR: mismatched types: expected `char`, found `i32` - //~| ERROR: mismatched types: expected `i32`, found `char` + //~^ ERROR: the constant `1` is not of type `char` + //~| ERROR: the constant `'a'` is not of type `i32 } diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr index 13e2789ccb67a..4136c7337cd4e 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr @@ -4,35 +4,23 @@ error: type annotations needed for the literal LL | foo::<{ (1, true) }>(); | ^ -error: mismatched types: expected `i32`, found `bool` - --> $DIR/tuple_expr_type_mismatch.rs:13:17 - | -LL | foo::<{ (1, true) }>(); - | ^^^^ - -error: mismatched types: expected `[u8; 2]`, found `u32` - --> $DIR/tuple_expr_type_mismatch.rs:16:14 - | -LL | bar::<{ (1_u32, [1, 2]) }>(); - | ^^^^^ - error: expected `i32`, found const array - --> $DIR/tuple_expr_type_mismatch.rs:16:21 + --> $DIR/tuple_expr_type_mismatch.rs:15:21 | LL | bar::<{ (1_u32, [1, 2]) }>(); | ^^^^^^ -error: mismatched types: expected `char`, found `i32` - --> $DIR/tuple_expr_type_mismatch.rs:19:14 +error: the constant `1` is not of type `char` + --> $DIR/tuple_expr_type_mismatch.rs:17:13 | LL | qux::<{ (1i32, 'a') }>(); - | ^^^^ + | ^^^^^^^^^^^ expected `char`, found `i32` -error: mismatched types: expected `i32`, found `char` - --> $DIR/tuple_expr_type_mismatch.rs:19:20 +error: the constant `'a'` is not of type `i32` + --> $DIR/tuple_expr_type_mismatch.rs:17:13 | LL | qux::<{ (1i32, 'a') }>(); - | ^^^ + | ^^^^^^^^^^^ expected `i32`, found `char` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs index deac97383b04a..c73785f9a3e38 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -2,9 +2,11 @@ #![feature(min_generic_const_args)] type const FREE: u32 = 5_usize; -//~^ ERROR mismatched types +//~^ ERROR the constant `5` is not of type `u32` +//~| ERROR mismatched types type const FREE2: isize = FREE; +//~^ ERROR the constant `5` is not of type `isize` trait Tr { type const N: usize; diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr index 1c04ac5085693..f7f64c535f602 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -1,3 +1,21 @@ +error: the constant `5` is not of type `u32` + --> $DIR/type_const-mismatched-types.rs:4:1 + | +LL | type const FREE: u32 = 5_usize; + | ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `5` is not of type `isize` + --> $DIR/type_const-mismatched-types.rs:8:1 + | +LL | type const FREE2: isize = FREE; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `usize` + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:16:27 + | +LL | type const N: usize = false; + | ^^^^^ expected `usize`, found `bool` + error[E0308]: mismatched types --> $DIR/type_const-mismatched-types.rs:4:24 | @@ -10,12 +28,6 @@ LL - type const FREE: u32 = 5_usize; LL + type const FREE: u32 = 5_u32; | -error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:18:22 - | -LL | type const N: usize = false; - | ^^^^^ expected `usize`, found `bool` - -error: aborting due to 2 previous errors +error: aborting due to 4 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 b85856db9287e..df7c2a0a86292 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 @@ -22,7 +22,7 @@ error[E0308]: mismatched types LL | get_flag::<42, 0x5ad>(); | ^^^^^ expected `char`, found `u8` -error[E0080]: reading memory at ALLOC6[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::(); @@ -54,7 +54,7 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character 42 │ B } -error[E0080]: reading memory at ALLOC12[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory +error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:44:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr index 95d20de1b432e..9de140dab9eb6 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -1,3 +1,15 @@ +error: the constant `1` is not of type `u8` + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +note: required by a const generic parameter in `R::method` + --> $DIR/type-mismatch.rs:5:15 + | +LL | fn method(&self) -> u8 { N } + | ^^^^^^^^^^^ required by this const generic parameter in `R::method` + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -10,6 +22,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr index 95d20de1b432e..9de140dab9eb6 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -1,3 +1,15 @@ +error: the constant `1` is not of type `u8` + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +note: required by a const generic parameter in `R::method` + --> $DIR/type-mismatch.rs:5:15 + | +LL | fn method(&self) -> u8 { N } + | ^^^^^^^^^^^ required by this const generic parameter in `R::method` + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -10,6 +22,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.rs b/tests/ui/const-generics/type-dependent/type-mismatch.rs index 6ed5fdca30ae3..fc7ae994184be 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.rs +++ b/tests/ui/const-generics/type-dependent/type-mismatch.rs @@ -6,5 +6,6 @@ impl R { } fn main() { assert_eq!(R.method::<1u16>(), 1); - //~^ ERROR mismatched types + //~^ ERROR the constant `1` is not of type `u8` + //~| ERROR mismatched types } diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.rs b/tests/ui/consts/const-eval/array-len-mismatch-type.rs new file mode 100644 index 0000000000000..463572c13e104 --- /dev/null +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.rs @@ -0,0 +1,8 @@ +//! Regression test for +pub struct Data([[&'static str]; 5_i32]); +//~^ ERROR the constant `5` is not of type `usize` +//~| ERROR the size for values of type `[&'static str]` cannot be known at compilation time +//~| ERROR mismatched types +const _: &'static Data = unsafe { &*(&[] as *const Data) }; +//~^ ERROR the type `[[&str]; 5]` has an unknown layout +fn main() {} diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr new file mode 100644 index 0000000000000..0f03006f00326 --- /dev/null +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr @@ -0,0 +1,39 @@ +error: the constant `5` is not of type `usize` + --> $DIR/array-len-mismatch-type.rs:2:17 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + | + = note: the length of array `[[&'static str]; 5]` must be type `usize` + +error[E0277]: the size for values of type `[&'static str]` cannot be known at compilation time + --> $DIR/array-len-mismatch-type.rs:2:17 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static str]` + = note: slice and array elements must have `Sized` type + +error[E0080]: the type `[[&str]; 5]` has an unknown layout + --> $DIR/array-len-mismatch-type.rs:6:39 + | +LL | const _: &'static Data = unsafe { &*(&[] as *const Data) }; + | ^^ evaluation of `_` failed here + +error[E0308]: mismatched types + --> $DIR/array-len-mismatch-type.rs:2:34 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^ expected `usize`, found `i32` + | +help: change the type of the numeric literal from `i32` to `usize` + | +LL - pub struct Data([[&'static str]; 5_i32]); +LL + pub struct Data([[&'static str]; 5_usize]); + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0277, E0308. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/issues/issue-34373.rs index 019cab42c6433..765bfc20a4517 100644 --- a/tests/ui/issues/issue-34373.rs +++ b/tests/ui/issues/issue-34373.rs @@ -4,9 +4,9 @@ trait Trait { fn foo(_: T) {} } -pub struct Foo>>; //~ ERROR cycle detected -//~^ ERROR `T` is never used -//~| ERROR cycle detected +pub struct Foo>>; +//~^ ERROR cycle detected when computing type of `Foo::T` +//~| ERROR type parameter `T` is never used type DefaultFoo = Foo; fn main() { diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 49365a701ceee..6d68de8fb3b8a 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -1,22 +1,3 @@ -error[E0391]: cycle detected when computing type of `Foo::T` - --> $DIR/issue-34373.rs:7:34 - | -LL | pub struct Foo>>; - | ^^^^^^^^^^ - | -note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:10:1 - | -LL | type DefaultFoo = Foo; - | ^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `Foo::T`, completing the cycle -note: cycle used when checking that `Foo` is well-formed - --> $DIR/issue-34373.rs:7:1 - | -LL | pub struct Foo>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - error[E0391]: cycle detected when computing type of `Foo::T` --> $DIR/issue-34373.rs:7:34 | @@ -45,7 +26,7 @@ LL | pub struct Foo>>; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0391, E0392. For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/repeat-expr/repeat_count.rs b/tests/ui/repeat-expr/repeat_count.rs index 2febcdc07c2a1..b1e3a9d8cb3b6 100644 --- a/tests/ui/repeat-expr/repeat_count.rs +++ b/tests/ui/repeat-expr/repeat_count.rs @@ -21,16 +21,21 @@ fn main() { let f = [0; -4_isize]; //~^ ERROR mismatched types //~| NOTE expected `usize`, found `isize` - let f = [0_usize; -1_isize]; + //~| NOTE `-4_isize` cannot fit into type `usize` + let g = [0_usize; -1_isize]; //~^ ERROR mismatched types //~| NOTE expected `usize`, found `isize` - let f = [0; 4u8]; - //~^ ERROR mismatched types + //~| NOTE `-1_isize` cannot fit into type `usize` + let h = [0; 4u8]; + //~^ ERROR the constant `4` is not of type `usize` + //~| NOTE expected `usize`, found `u8` + //~| NOTE the length of array `[{integer}; 4]` must be type `usize` + //~| ERROR mismatched types //~| NOTE expected `usize`, found `u8` - struct G { - g: (), + struct I { + i: (), } - let g = [0; G { g: () }]; + let i = [0; I { i: () }]; //~^ ERROR mismatched types - //~| NOTE expected `usize`, found `G` + //~| NOTE expected `usize`, found `I` } diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index 8d8702e981e6f..5da9dbe032098 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -43,32 +43,40 @@ LL | let f = [0; -4_isize]; = note: `-4_isize` cannot fit into type `usize` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:24:23 + --> $DIR/repeat_count.rs:25:23 | -LL | let f = [0_usize; -1_isize]; +LL | let g = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | = note: `-1_isize` cannot fit into type `usize` +error: the constant `4` is not of type `usize` + --> $DIR/repeat_count.rs:29:13 + | +LL | let h = [0; 4u8]; + | ^^^^^^^^ expected `usize`, found `u8` + | + = note: the length of array `[{integer}; 4]` must be type `usize` + error[E0308]: mismatched types - --> $DIR/repeat_count.rs:27:17 + --> $DIR/repeat_count.rs:38:17 | -LL | let f = [0; 4u8]; +LL | let i = [0; I { i: () }]; + | ^^^^^^^^^^^ expected `usize`, found `I` + +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:29:17 + | +LL | let h = [0; 4u8]; | ^^^ expected `usize`, found `u8` | help: change the type of the numeric literal from `u8` to `usize` | -LL - let f = [0; 4u8]; -LL + let f = [0; 4usize]; - | - -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:33:17 +LL - let h = [0; 4u8]; +LL + let h = [0; 4usize]; | -LL | let g = [0; G { g: () }]; - | ^^^^^^^^^^^ expected `usize`, found `G` -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0308, E0435. For more information about an error, try `rustc --explain E0308`.