diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index ced3bcad2293a..0765ccf384af9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -66,7 +66,8 @@ pub(crate) struct TypeConstParser; impl NoArgsAttributeParser for TypeConstParser { const PATH: &[Symbol] = &[sym::type_const]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocConst)]); + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Const), Allow(Target::AssocConst)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 62013958c7e55..4cdfc752d9895 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3065,7 +3065,7 @@ macro_rules! expect_methods_self_kind { $( #[track_caller] pub fn $name(&self) -> $ret_ty { - let $pat = &self.kind else { expect_failed(stringify!($ident), self) }; + let $pat = &self.kind else { expect_failed(stringify!($name), self) }; $ret_val } )* @@ -3077,7 +3077,7 @@ macro_rules! expect_methods_self { $( #[track_caller] pub fn $name(&self) -> $ret_ty { - let $pat = self else { expect_failed(stringify!($ident), self) }; + let $pat = self else { expect_failed(stringify!($name), self) }; $ret_val } )* @@ -4790,6 +4790,11 @@ impl<'hir> Node<'hir> { ForeignItemKind::Static(ty, ..) => Some(ty), _ => None, }, + Node::GenericParam(param) => match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { default, .. } => default, + GenericParamKind::Const { ty, .. } => Some(ty), + }, _ => None, } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1e12adbbfc6e0..7fa8f9563622c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -757,22 +757,18 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), } match tcx.def_kind(def_id) { - def_kind @ (DefKind::Static { .. } | DefKind::Const) => { + DefKind::Static { .. } => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); - match def_kind { - DefKind::Static { .. } => { - check_static_inhabited(tcx, def_id); - check_static_linkage(tcx, def_id); - let ty = tcx.type_of(def_id).instantiate_identity(); - res = res.and(wfcheck::check_static_item( - tcx, def_id, ty, /* should_check_for_sync */ true, - )); - } - DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)), - _ => unreachable!(), - } + + check_static_inhabited(tcx, def_id); + check_static_linkage(tcx, def_id); + let ty = tcx.type_of(def_id).instantiate_identity(); + res = res.and(wfcheck::check_static_item( + tcx, def_id, ty, /* should_check_for_sync */ true, + )); + // Only `Node::Item` and `Node::ForeignItem` still have HIR based // checks. Returning early here does not miss any checks and // avoids this query from having a direct dependency edge on the HIR @@ -900,6 +896,39 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // avoids this query from having a direct dependency edge on the HIR return res; } + DefKind::Const => { + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + + res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty_span = tcx.ty_span(def_id); + let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); + wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into()); + wfcx.register_bound( + traits::ObligationCause::new( + ty_span, + def_id, + ObligationCauseCode::SizedConstOrStatic, + ), + tcx.param_env(def_id), + ty, + tcx.require_lang_item(LangItem::Sized, ty_span), + ); + check_where_clauses(wfcx, def_id); + + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + wfcheck::check_type_const(wfcx, def_id, ty, true)?; + } + Ok(()) + })); + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; + } DefKind::TyAlias => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); @@ -920,6 +949,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), })); check_variances_for_type_defn(tcx, def_id); } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::ForeignMod => { let it = tcx.hir_expect_item(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 74bf68362fc5f..6a07d2988fdfc 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -6,9 +6,10 @@ use hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::VisitorExt; -use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit}; +use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, find_attr, intravisit}; use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -1984,12 +1985,46 @@ fn compare_impl_const<'tcx>( trait_const_item: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + compare_type_const(tcx, impl_const_item, trait_const_item)?; compare_number_of_generics(tcx, impl_const_item, trait_const_item, false)?; compare_generic_param_kinds(tcx, impl_const_item, trait_const_item, false)?; check_region_bounds_on_impl_item(tcx, impl_const_item, trait_const_item, false)?; compare_const_predicate_entailment(tcx, impl_const_item, trait_const_item, impl_trait_ref) } +fn compare_type_const<'tcx>( + tcx: TyCtxt<'tcx>, + impl_const_item: ty::AssocItem, + trait_const_item: ty::AssocItem, +) -> Result<(), ErrorGuaranteed> { + let impl_is_type_const = + find_attr!(tcx.get_all_attrs(impl_const_item.def_id), AttributeKind::TypeConst(_)); + let trait_type_const_span = find_attr!( + tcx.get_all_attrs(trait_const_item.def_id), + AttributeKind::TypeConst(sp) => *sp + ); + + if let Some(trait_type_const_span) = trait_type_const_span + && !impl_is_type_const + { + return Err(tcx + .dcx() + .struct_span_err( + tcx.def_span(impl_const_item.def_id), + "implementation of `#[type_const]` const must be marked with `#[type_const]`", + ) + .with_span_note( + MultiSpan::from_spans(vec![ + tcx.def_span(trait_const_item.def_id), + trait_type_const_span, + ]), + "trait declaration of const is marked with `#[type_const]`", + ) + .emit()); + } + Ok(()) +} + /// The equivalent of [compare_method_predicate_entailment], but for associated constants /// instead of associated functions. // FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`. diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f3d6398b20853..ccae524352a59 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -6,10 +6,11 @@ use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{AmbigArg, ItemKind}; +use rustc_hir::{AmbigArg, ItemKind, find_attr}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt}; use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; @@ -925,11 +926,11 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er #[instrument(level = "debug", skip(tcx))] pub(crate) fn check_associated_item( tcx: TyCtxt<'_>, - item_id: LocalDefId, + def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let loc = Some(WellFormedLoc::Ty(item_id)); - enter_wf_checking_ctxt(tcx, item_id, |wfcx| { - let item = tcx.associated_item(item_id); + let loc = Some(WellFormedLoc::Ty(def_id)); + enter_wf_checking_ctxt(tcx, def_id, |wfcx| { + let item = tcx.associated_item(def_id); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. @@ -942,27 +943,36 @@ pub(crate) fn check_associated_item( } }; - let span = tcx.def_span(item_id); + let span = tcx.def_span(def_id); match item.kind { ty::AssocKind::Const { .. } => { - let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); - check_sized_if_body( - wfcx, - item.def_id.expect_local(), - ty, - Some(span), - ObligationCauseCode::SizedConstOrStatic, - ); + + let has_value = item.defaultness(tcx).has_value(); + if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) { + check_type_const(wfcx, def_id, ty, has_value)?; + } + + if has_value { + let code = ObligationCauseCode::SizedConstOrStatic; + wfcx.register_bound( + ObligationCause::new(span, def_id, code), + wfcx.param_env, + ty, + tcx.require_lang_item(LangItem::Sized, span), + ); + } + Ok(()) } ty::AssocKind::Fn { .. } => { - let sig = tcx.fn_sig(item.def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity(); let hir_sig = - tcx.hir_node_by_def_id(item_id).fn_sig().expect("bad signature for method"); - check_fn_or_method(wfcx, sig, hir_sig.decl, item_id); + tcx.hir_node_by_def_id(def_id).fn_sig().expect("bad signature for method"); + check_fn_or_method(wfcx, sig, hir_sig.decl, def_id); check_method_receiver(wfcx, hir_sig, item, self_ty) } ty::AssocKind::Type { .. } => { @@ -970,8 +980,8 @@ pub(crate) fn check_associated_item( check_associated_type_bounds(wfcx, item, span) } if item.defaultness(tcx).has_value() { - let ty = tcx.type_of(item.def_id).instantiate_identity(); - let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } Ok(()) @@ -1222,28 +1232,36 @@ pub(crate) fn check_static_item<'tcx>( }) } -pub(crate) fn check_const_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { - enter_wf_checking_ctxt(tcx, def_id, |wfcx| { - let ty = tcx.type_of(def_id).instantiate_identity(); - let ty_span = tcx.ty_span(def_id); - let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); +#[instrument(level = "debug", skip(wfcx))] +pub(super) fn check_type_const<'tcx>( + wfcx: &WfCheckingCtxt<'_, 'tcx>, + def_id: LocalDefId, + item_ty: Ty<'tcx>, + has_value: bool, +) -> Result<(), ErrorGuaranteed> { + let tcx = wfcx.tcx(); + let span = tcx.def_span(def_id); - wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into()); - wfcx.register_bound( - traits::ObligationCause::new( - ty_span, - wfcx.body_def_id, - ObligationCauseCode::SizedConstOrStatic, - ), - wfcx.param_env, - ty, - tcx.require_lang_item(LangItem::Sized, ty_span), - ); + wfcx.register_bound( + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), + wfcx.param_env, + item_ty, + tcx.require_lang_item(LangItem::ConstParamTy, span), + ); - check_where_clauses(wfcx, def_id); + if has_value { + let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); + let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct); + wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into()); - Ok(()) - }) + wfcx.register_obligation(Obligation::new( + tcx, + ObligationCause::new(span, def_id, ObligationCauseCode::WellFormed(None)), + wfcx.param_env, + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)), + )); + } + Ok(()) } #[instrument(level = "debug", skip(tcx, impl_))] @@ -1583,33 +1601,16 @@ fn check_fn_or_method<'tcx>( } // If the function has a body, additionally require that the return type is sized. - check_sized_if_body( - wfcx, - def_id, - sig.output(), - match hir_decl.output { - hir::FnRetTy::Return(ty) => Some(ty.span), - hir::FnRetTy::DefaultReturn(_) => None, - }, - ObligationCauseCode::SizedReturnType, - ); -} - -fn check_sized_if_body<'tcx>( - wfcx: &WfCheckingCtxt<'_, 'tcx>, - def_id: LocalDefId, - ty: Ty<'tcx>, - maybe_span: Option, - code: ObligationCauseCode<'tcx>, -) { - let tcx = wfcx.tcx(); if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { - let span = maybe_span.unwrap_or(body.value.span); + let span = match hir_decl.output { + hir::FnRetTy::Return(ty) => ty.span, + hir::FnRetTy::DefaultReturn(_) => body.value.span, + }; wfcx.register_bound( - ObligationCause::new(span, def_id, code), + ObligationCause::new(span, def_id, ObligationCauseCode::SizedReturnType), wfcx.param_env, - ty, + sig.output(), tcx.require_lang_item(LangItem::Sized, span), ); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 84b0c20aaa109..2acccc1ae78e7 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1600,8 +1600,12 @@ fn const_of_item<'tcx>( }; let ct_arg = match ct_rhs { hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg, - hir::ConstItemRhs::Body(body_id) => { - bug!("cannot call const_of_item on a non-type_const {body_id:?}") + hir::ConstItemRhs::Body(_) => { + let e = tcx.dcx().span_delayed_bug( + tcx.def_span(def_id), + "cannot call const_of_item on a non-type_const", + ); + return ty::EarlyBinder::bind(Const::new_error(tcx, e)); } }; let icx = ItemCtxt::new(tcx, def_id); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 463338ee1fb5d..1a422e3083026 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -150,9 +150,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::ProcMacroDerive { .. }) => { self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } - &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { - self.check_type_const(hir_id, attr_span, target) - } Attribute::Parsed( AttributeKind::Stability { span: attr_span, @@ -243,6 +240,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::ParenSugar(..) | AttributeKind::AllowIncoherentImpl(..) | AttributeKind::Confusables { .. } + | AttributeKind::TypeConst{..} // `#[doc]` is actually a lot more than just doc comments, so is checked below | AttributeKind::DocComment {..} // handled below this loop and elsewhere @@ -2115,16 +2113,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, _hir_id: HirId, attr_span: Span, target: Target) { - if matches!(target, Target::AssocConst | Target::Const) { - return; - } else { - self.dcx() - .struct_span_err(attr_span, "`#[type_const]` must only be applied to const items") - .emit(); - } - } - fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) { if !find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent)) .unwrap_or(false) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d2f2c92dda080..c282f42042600 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1286,12 +1286,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> Diag<'a> { - let param = obligation.cause.body_id; - let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } = - self.tcx.hir_node_by_def_id(param).expect_generic_param().kind - else { - bug!() - }; + let def_id = obligation.cause.body_id; + let span = self.tcx.ty_span(def_id); let mut file = None; let ty_str = self.tcx.short_string(ty, &mut file); diff --git a/tests/crashes/140729.rs b/tests/crashes/140729.rs deleted file mode 100644 index a436ec58e8e83..0000000000000 --- a/tests/crashes/140729.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #140729 -#![feature(min_generic_const_args)] - -const C: usize = 0; -pub struct A {} -impl A { - fn fun1() {} -} -impl A { - fn fun1() {} -} diff --git a/tests/crashes/140860.rs b/tests/crashes/140860.rs deleted file mode 100644 index 04da6bd832c3a..0000000000000 --- a/tests/crashes/140860.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #140860 -#![feature(min_generic_const_args)] -#![feature(unsized_const_params)] -#![feature(with_negative_coherence, negative_impls)] -trait a < const b : &'static str> {} trait c {} struct d< e >(e); -impl c for e where e: a<""> {} -impl c for d {} -impl !a for e {} -const f : &str = ""; -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs index d433af6bdd57d..2ff5a0353a0a6 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs @@ -1,7 +1,7 @@ // We used to say "ambiguous associated type" on ambiguous associated consts. // Ensure that we now use the correct label. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait0: Parent0 + Parent0 {} diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index f6240ead0b9bd..5232b895803e8 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -1,9 +1,16 @@ // Check that we eventually catch types of assoc const bounds // (containing late-bound vars) that are ill-formed. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait { +use std::marker::ConstParamTy_; + +trait Trait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index b629bb4d3f8c7..a0329e2b15d17 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = { () } | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:14:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 | LL | K = { () } | ^^^^^^ @@ -13,7 +13,7 @@ LL | K = { () } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:19:13 | LL | _: impl Trait< | _____________^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index 36b3d8a648fd8..ef8077b9f44a5 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -3,10 +3,17 @@ // //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait { +use std::marker::ConstParamTy_; + +trait Trait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 3f48b3bfbb6d1..1ab93ea596a76 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -1,6 +1,6 @@ // Detect and reject escaping late-bound generic params in // the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait<'a> { diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 5b0438e95695c..0afb95a0b0336 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -1,14 +1,21 @@ // Regression test for issue #108271. // Detect and reject generic params in the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] -trait Trait<'a, T: 'a, const N: usize> { +use std::marker::ConstParamTy_; + +trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { #[type_const] const K: &'a [T; N]; } -fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} +fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~^ ERROR the type of the associated constant `K` must not depend on generic parameters //~| NOTE its type must not depend on the lifetime parameter `'r` //~| NOTE the lifetime parameter `'r` is defined here @@ -22,7 +29,7 @@ fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} //~| NOTE the const parameter `Q` is defined here //~| NOTE `K` has type `&'r [A; Q]` -trait Project { +trait Project: ConstParamTy_ { #[type_const] const SELF: Self; } @@ -38,7 +45,7 @@ fn take2>(_: P) {} //~| NOTE the type parameter `P` is defined here //~| NOTE `SELF` has type `P` -trait Iface<'r> { +trait Iface<'r>: ConstParamTy_ { //~^ NOTE the lifetime parameter `'r` is defined here //~| NOTE the lifetime parameter `'r` is defined here type Assoc: Trait<'r, Self, Q, K = { loop {} }> diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index 7ba1d638baa88..229dd10c0bebf 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -1,31 +1,31 @@ error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:11:61 + --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 | -LL | fn take0<'r, A: 'r, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} + | - ^ its type must not depend on the const parameter `Q` + | | + | the const parameter `Q` is defined here | = note: `K` has type `&'r [A; Q]` error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:30:26 + --> $DIR/assoc-const-eq-param-in-ty.rs:37:26 | LL | fn take1(_: impl Project) {} | -------------^^^^------ @@ -34,7 +34,7 @@ LL | fn take1(_: impl Project) {} | the `impl Trait` is specified here error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:35:21 + --> $DIR/assoc-const-eq-param-in-ty.rs:42:21 | LL | fn take2>(_: P) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -44,9 +44,9 @@ LL | fn take2>(_: P) {} = note: `SELF` has type `P` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | -LL | trait Iface<'r> { +LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> @@ -55,7 +55,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -63,7 +63,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -73,9 +73,9 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: `K` has type `&'r [Self; Q]` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | -LL | trait Iface<'r> { +LL | trait Iface<'r>: ConstParamTy_ { | -- the lifetime parameter `'r` is defined here ... LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> @@ -85,7 +85,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | ^ its type must not depend on `Self` @@ -94,7 +94,7 @@ LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:44:52 + --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 | LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index 301ddf2d01047..d9b8a8cd43d7d 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -3,12 +3,19 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature( + associated_const_equality, + min_generic_const_args, + adt_const_params, + unsized_const_params, +)] #![allow(incomplete_features)] +use std::marker::ConstParamTy_; + trait Trait: SuperTrait {} trait SuperTrait: SuperSuperTrait {} -trait SuperSuperTrait { +trait SuperSuperTrait { #[type_const] const K: T; } diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs index febd838e2c2ee..41857eca87de6 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs +++ b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs @@ -5,7 +5,7 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] trait Trait: SuperTrait { diff --git a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs new file mode 100644 index 0000000000000..37f9c31feaa55 --- /dev/null +++ b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs @@ -0,0 +1,26 @@ +//@ check-pass + +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +pub trait Tr { + #[type_const] + const N1: usize; + #[type_const] + const N2: usize; + #[type_const] + const N3: usize; +} + +pub struct S; + +impl Tr for S { + #[type_const] + const N1: usize = 0; + #[type_const] + const N2: usize = 1; + #[type_const] + const N3: usize = 2; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs new file mode 100644 index 0000000000000..68aa30bd65bbe --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs @@ -0,0 +1,17 @@ +// Regression test for #140729 + +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +const C: usize = 0; +pub struct A {} +impl A { + fn fun1() {} + //~^ ERROR duplicate definitions with name `fun1` +} +impl A { + //~^ ERROR missing generics for struct `A` + fn fun1() {} +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr new file mode 100644 index 0000000000000..3d74d1db206e1 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr @@ -0,0 +1,29 @@ +error[E0107]: missing generics for struct `A` + --> $DIR/const-arg-coherence-conflicting-methods.rs:12:6 + | +LL | impl A { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `M` + --> $DIR/const-arg-coherence-conflicting-methods.rs:7:12 + | +LL | pub struct A {} + | ^ -------------- +help: add missing generic argument + | +LL | impl A { + | +++ + +error[E0592]: duplicate definitions with name `fun1` + --> $DIR/const-arg-coherence-conflicting-methods.rs:9:5 + | +LL | fn fun1() {} + | ^^^^^^^^^ duplicate definitions for `fun1` +... +LL | fn fun1() {} + | --------- other definition for `fun1` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0107, E0592. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs new file mode 100644 index 0000000000000..8d2eae71d330d --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -0,0 +1,23 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +#[type_const] +const FREE: u32 = 5_usize; +//~^ ERROR mismatched types + +#[type_const] +const FREE2: isize = FREE; +//~^ ERROR the constant `5` is not of type `isize` + +trait Tr { + #[type_const] + const N: usize; +} + +impl Tr for () { + #[type_const] + const N: usize = false; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr new file mode 100644 index 0000000000000..4029bb7b6bff2 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -0,0 +1,27 @@ +error: the constant `5` is not of type `isize` + --> $DIR/type_const-mismatched-types.rs:9:1 + | +LL | const FREE2: isize = FREE; + | ^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:5:19 + | +LL | const FREE: u32 = 5_usize; + | ^^^^^^^ expected `u32`, found `usize` + | +help: change the type of the numeric literal from `usize` to `u32` + | +LL - const FREE: u32 = 5_usize; +LL + const FREE: u32 = 5_u32; + | + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:19:22 + | +LL | const N: usize = false; + | ^^^^^ expected `usize`, found `bool` + +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/type_const-not-constparamty.rs b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs new file mode 100644 index 0000000000000..27b446e6a40d2 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs @@ -0,0 +1,26 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +struct S; + +// FIXME(mgca): need support for ctors without anon const +// (we use double-braces to trigger an anon const here) +#[type_const] +const FREE: S = { { S } }; +//~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + +trait Tr { + #[type_const] + const N: S; + //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter +} + +impl Tr for S { + // FIXME(mgca): need support for ctors without anon const + // (we use double-braces to trigger an anon const here) + #[type_const] + const N: S = { { S } }; + //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr new file mode 100644 index 0000000000000..6b13917a95cd1 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr @@ -0,0 +1,39 @@ +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:9:13 + | +LL | const FREE: S = { { S } }; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:22:14 + | +LL | const N: S = { { S } }; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/type_const-not-constparamty.rs:14:14 + | +LL | const N: S; + | ^ + | +help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct + | +LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct S; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs new file mode 100644 index 0000000000000..d38d5ab7a59f8 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -0,0 +1,34 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +#[type_const] +const FREE1: usize = std::mem::size_of::(); +//~^ ERROR generic parameters may not be used in const operations +#[type_const] +const FREE2: usize = I + 1; +//~^ ERROR generic parameters may not be used in const operations + +pub trait Tr { + #[type_const] + const N1: usize; + #[type_const] + const N2: usize; + #[type_const] + const N3: usize; +} + +pub struct S; + +impl Tr for S { + #[type_const] + const N1: usize = std::mem::size_of::(); + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N2: usize = I + 1; + //~^ ERROR generic parameters may not be used in const operations + #[type_const] + const N3: usize = 2 & X; + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr new file mode 100644 index 0000000000000..76638f27e96cf --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -0,0 +1,47 @@ +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:5:45 + | +LL | const FREE1: usize = std::mem::size_of::(); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:8:38 + | +LL | const FREE2: usize = I + 1; + | ^ cannot perform const operation using `I` + | + = help: const parameters may only be used as standalone arguments here, i.e. `I` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:24:46 + | +LL | const N1: usize = std::mem::size_of::(); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:27:39 + | +LL | const N2: usize = I + 1; + | ^ cannot perform const operation using `I` + | + = help: const parameters may only be used as standalone arguments here, i.e. `I` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic-expr.rs:30:27 + | +LL | const N3: usize = 2 & X; + | ^ cannot perform const operation using `X` + | + = help: const parameters may only be used as standalone arguments here, i.e. `X` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 5 previous errors + diff --git a/tests/crashes/mgca/type_const-only-in-trait.rs b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs similarity index 73% rename from tests/crashes/mgca/type_const-only-in-trait.rs rename to tests/ui/const-generics/mgca/type_const-only-in-trait.rs index 109cf0ec670c4..8c8ff6259cae5 100644 --- a/tests/crashes/mgca/type_const-only-in-trait.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs @@ -1,7 +1,3 @@ -//@ known-bug: #132980 -// Move this test to tests/ui/const-generics/mgca/type_const-only-in-trait.rs -// once fixed. - #![expect(incomplete_features)] #![feature(associated_const_equality, min_generic_const_args)] @@ -14,6 +10,7 @@ struct BadS; impl GoodTr for BadS { const NUM: usize = 42; + //~^ ERROR implementation of `#[type_const]` const must be marked with `#[type_const]` } fn accept_good_tr>(_x: &T) {} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr new file mode 100644 index 0000000000000..29f1b724960aa --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr @@ -0,0 +1,16 @@ +error: implementation of `#[type_const]` const must be marked with `#[type_const]` + --> $DIR/type_const-only-in-trait.rs:12:5 + | +LL | const NUM: usize = 42; + | ^^^^^^^^^^^^^^^^ + | +note: trait declaration of const is marked with `#[type_const]` + --> $DIR/type_const-only-in-trait.rs:5:5 + | +LL | #[type_const] + | ^^^^^^^^^^^^^ +LL | const NUM: usize; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/crashes/119783.rs b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs similarity index 54% rename from tests/crashes/119783.rs rename to tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs index efde7f89ade2e..554e078ccd49c 100644 --- a/tests/crashes/119783.rs +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs @@ -1,9 +1,12 @@ -//@ known-bug: #119783 +// Regression test for #119783 + +#![expect(incomplete_features)] #![feature(associated_const_equality, min_generic_const_args)] trait Trait { #[type_const] const F: fn(); + //~^ ERROR using function pointers as const generic parameters is forbidden } fn take(_: impl Trait) {} diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr new file mode 100644 index 0000000000000..09d1063081fe1 --- /dev/null +++ b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr @@ -0,0 +1,9 @@ +error[E0741]: using function pointers as const generic parameters is forbidden + --> $DIR/using-fnptr-as-type_const.rs:8:14 + | +LL | const F: fn(); + | ^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 57b748a6b4756..7f4926fa2b71f 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] pub struct NoPin; diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs index 0620998188b26..6f5d4985ae539 100644 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ b/tests/ui/generic-const-items/associated-const-equality.rs @@ -9,8 +9,8 @@ trait Owner { const C: u32; #[type_const] const K: u32; - #[type_const] - const Q: Maybe; + // #[type_const] + // const Q: Maybe; } impl Owner for () { @@ -18,13 +18,15 @@ impl Owner for () { const C: u32 = N; #[type_const] const K: u32 = 99 + 1; - #[type_const] - const Q: Maybe = Maybe::Nothing; + // FIXME(mgca): re-enable once we properly support ctors and generics on paths + // #[type_const] + // const Q: Maybe = Maybe::Nothing; } fn take0(_: impl Owner = { N }>) {} fn take1(_: impl Owner = 100>) {} -fn take2(_: impl Owner = { Maybe::Just(()) }>) {} +// FIXME(mgca): re-enable once we properly support ctors and generics on paths +// fn take2(_: impl Owner = { Maybe::Just(()) }>) {} fn main() { take0::<128>(());