1
Fork 0

Rollup merge of #137617 - BoxyUwU:generic_const_parameter_types, r=lcnr

Introduce `feature(generic_const_parameter_types)`

Allows to define const generic parameters whose type depends on other generic parameters, e.g. `Foo<const N: usize, const ARR: [u8; N]>;`

Wasn't going to implement for this for a while until we could implement it with `bad_inference.rs` resolved but apparently the project simd folks would like to be able to use this for some intrinsics and the inference issue isn't really a huge problem there aiui. (cc ``@workingjubilee`` )
This commit is contained in:
Matthias Krüger 2025-03-01 11:33:58 +01:00 committed by GitHub
commit 415b207b7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 419 additions and 154 deletions

View file

@ -508,6 +508,8 @@ declare_features! (
(incomplete, generic_const_exprs, "1.56.0", Some(76560)), (incomplete, generic_const_exprs, "1.56.0", Some(76560)),
/// Allows generic parameters and where-clauses on free & associated const items. /// Allows generic parameters and where-clauses on free & associated const items.
(incomplete, generic_const_items, "1.73.0", Some(113521)), (incomplete, generic_const_items, "1.73.0", Some(113521)),
/// Allows the type of const generics to depend on generic parameters
(incomplete, generic_const_parameter_types, "CURRENT_RUSTC_VERSION", Some(137626)),
/// Allows any generic constants being used as pattern type range ends /// Allows any generic constants being used as pattern type range ends
(incomplete, generic_pattern_types, "1.86.0", Some(136574)), (incomplete, generic_pattern_types, "1.86.0", Some(136574)),
/// Allows registering static items globally, possibly across crates, to iterate over at runtime. /// Allows registering static items globally, possibly across crates, to iterate over at runtime.

View file

@ -966,7 +966,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
let ty = tcx.type_of(param.def_id).instantiate_identity(); let ty = tcx.type_of(param.def_id).instantiate_identity();
if tcx.features().unsized_const_params() { if tcx.features().unsized_const_params() {
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| {
wfcx.register_bound( wfcx.register_bound(
ObligationCause::new( ObligationCause::new(
hir_ty.span, hir_ty.span,
@ -980,7 +980,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
Ok(()) Ok(())
}) })
} else if tcx.features().adt_const_params() { } else if tcx.features().adt_const_params() {
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| { enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| {
wfcx.register_bound( wfcx.register_bound(
ObligationCause::new( ObligationCause::new(
hir_ty.span, hir_ty.span,

View file

@ -1822,6 +1822,9 @@ fn const_param_default<'tcx>(
), ),
}; };
let icx = ItemCtxt::new(tcx, def_id); let icx = ItemCtxt::new(tcx, def_id);
let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id())); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let ct = icx
.lowerer()
.lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
ty::EarlyBinder::bind(ct) ty::EarlyBinder::bind(ct)
} }

View file

@ -223,10 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
hir::GenericParamKind::Const { .. } => { hir::GenericParamKind::Const { .. } => {
let param_def_id = param.def_id.to_def_id(); let param_def_id = param.def_id.to_def_id();
let ct_ty = tcx let ct_ty = tcx.type_of(param_def_id).instantiate_identity();
.type_of(param_def_id)
.no_bound_vars()
.expect("const parameters cannot be generic");
let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id); let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id);
predicates predicates
.insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span)); .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));

View file

@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
// We lower to an infer even when the feature gate is not enabled // We lower to an infer even when the feature gate is not enabled
// as it is useful for diagnostics to be able to see a `ConstKind::Infer` // as it is useful for diagnostics to be able to see a `ConstKind::Infer`
args.push(ctx.provided_kind(param, arg)); args.push(ctx.provided_kind(&args, param, arg));
args_iter.next(); args_iter.next();
params.next(); params.next();
} }

View file

@ -232,12 +232,15 @@ impl AssocItemQSelf {
/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the /// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
/// desired behavior. /// desired behavior.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum FeedConstTy { pub enum FeedConstTy<'a, 'tcx> {
/// Feed the type. /// Feed the type.
/// ///
/// The `DefId` belongs to the const param that we are supplying /// The `DefId` belongs to the const param that we are supplying
/// this (anon) const arg to. /// this (anon) const arg to.
Param(DefId), ///
/// The list of generic args is used to instantiate the parameters
/// used by the type of the const param specified by `DefId`.
Param(DefId, &'a [ty::GenericArg<'tcx>]),
/// Don't feed the type. /// Don't feed the type.
No, No,
} }
@ -298,6 +301,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
fn provided_kind( fn provided_kind(
&mut self, &mut self,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'tcx>, arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx>; ) -> ty::GenericArg<'tcx>;
@ -481,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn provided_kind( fn provided_kind(
&mut self, &mut self,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'tcx>, arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
@ -526,7 +531,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
.lowerer .lowerer
// Ambig portions of `ConstArg` are handled in the match arm below // Ambig portions of `ConstArg` are handled in the match arm below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) .lower_const_arg(
ct.as_unambig_ct(),
FeedConstTy::Param(param.def_id, preceding_args),
)
.into(), .into(),
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
self.lowerer.ct_infer(Some(param), inf.span).into() self.lowerer.ct_infer(Some(param), inf.span).into()
@ -582,8 +590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let ty = tcx let ty = tcx
.at(self.span) .at(self.span)
.type_of(param.def_id) .type_of(param.def_id)
.no_bound_vars() .instantiate(tcx, preceding_args);
.expect("const parameter types cannot be generic");
if let Err(guar) = ty.error_reported() { if let Err(guar) = ty.error_reported() {
return ty::Const::new_error(tcx, guar).into(); return ty::Const::new_error(tcx, guar).into();
} }
@ -2107,14 +2114,50 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub fn lower_const_arg( pub fn lower_const_arg(
&self, &self,
const_arg: &hir::ConstArg<'tcx>, const_arg: &hir::ConstArg<'tcx>,
feed: FeedConstTy, feed: FeedConstTy<'_, 'tcx>,
) -> Const<'tcx> { ) -> Const<'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
if let FeedConstTy::Param(param_def_id) = feed if let FeedConstTy::Param(param_def_id, args) = feed
&& let hir::ConstArgKind::Anon(anon) = &const_arg.kind && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
{ {
tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id)); let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
// We must error if the instantiated type has any inference variables as we will
// use this type to feed the `type_of` and query results must not contain inference
// variables otherwise we will ICE.
//
// We also error if the type contains any regions as effectively any region will wind
// up as a region variable in mir borrowck. It would also be somewhat concerning if
// hir typeck was using equality but mir borrowck wound up using subtyping as that could
// result in a non-infer in hir typeck but a region variable in borrowck.
//
// FIXME(generic_const_parameter_types): Ideally we remove these errors one day when
// we have the ability to intermix typeck of anon const const args with the parent
// bodies typeck.
if tcx.features().generic_const_parameter_types()
&& (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
{
let e = tcx.dcx().span_err(
const_arg.span(),
"anonymous constants with lifetimes in their type are not yet supported",
);
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
return ty::Const::new_error(tcx, e);
}
if anon_const_type.has_non_region_infer() {
let e = tcx.dcx().span_err(
const_arg.span(),
"anonymous constants with inferred types are not yet supported",
);
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
return ty::Const::new_error(tcx, e);
}
tcx.feed_anon_const_type(
anon.def_id,
ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
);
} }
let hir_id = const_arg.hir_id; let hir_id = const_arg.hir_id;
@ -2230,10 +2273,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let expr = &tcx.hir_body(anon.body).value; let expr = &tcx.hir_body(anon.body).value;
debug!(?expr); debug!(?expr);
let ty = tcx // FIXME(generic_const_parameter_types): We should use the proper generic args
.type_of(anon.def_id) // here. It's only used as a hint for literals so doesn't matter too much to use the right
.no_bound_vars() // generic arguments, just weaker type inference.
.expect("const parameter types cannot be generic"); let ty = tcx.type_of(anon.def_id).instantiate_identity();
match self.try_lower_anon_const_lit(ty, expr) { match self.try_lower_anon_const_lit(ty, expr) {
Some(v) => v, Some(v) => v,

View file

@ -260,7 +260,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
pub fn lower_const_arg_for_rustdoc<'tcx>( pub fn lower_const_arg_for_rustdoc<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
hir_ct: &hir::ConstArg<'tcx>, hir_ct: &hir::ConstArg<'tcx>,
feed: FeedConstTy, feed: FeedConstTy<'_, 'tcx>,
) -> Const<'tcx> { ) -> Const<'tcx> {
let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)

View file

@ -522,7 +522,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn lower_const_arg( pub(crate) fn lower_const_arg(
&self, &self,
const_arg: &'tcx hir::ConstArg<'tcx>, const_arg: &'tcx hir::ConstArg<'tcx>,
feed: FeedConstTy, feed: FeedConstTy<'_, 'tcx>,
) -> ty::Const<'tcx> { ) -> ty::Const<'tcx> {
let ct = self.lowerer().lower_const_arg(const_arg, feed); let ct = self.lowerer().lower_const_arg(const_arg, feed);
self.register_wf_obligation( self.register_wf_obligation(
@ -1138,7 +1138,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.last() .last()
.is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self); .is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self);
let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res { let (res, implicit_args) = if let Res::Def(DefKind::ConstParam, def) = res {
// types of const parameters are somewhat special as they are part of
// the same environment as the const parameter itself. this means that
// unlike most paths `type-of(N)` can return a type naming parameters
// introduced by the containing item, rather than provided through `N`.
//
// for example given `<T, const M: usize, const N: [T; M]>` and some
// `let a = N;` expression. The path to `N` would wind up with no args
// (as it has no args), but instantiating the early binder on `typeof(N)`
// requires providing generic arguments for `[T, M, N]`.
(res, Some(ty::GenericArgs::identity_for_item(tcx, tcx.parent(def))))
} else if let Res::SelfCtor(impl_def_id) = res {
let ty = LoweredTy::from_raw( let ty = LoweredTy::from_raw(
self, self,
span, span,
@ -1264,6 +1275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn provided_kind( fn provided_kind(
&mut self, &mut self,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'tcx>, arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
@ -1283,7 +1295,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
.fcx .fcx
// Ambiguous parts of `ConstArg` are handled in the match arms below // Ambiguous parts of `ConstArg` are handled in the match arms below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) .lower_const_arg(
ct.as_unambig_ct(),
FeedConstTy::Param(param.def_id, preceding_args),
)
.into(), .into(),
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
self.fcx.ct_infer(Some(param), inf.span).into() self.fcx.ct_infer(Some(param), inf.span).into()
@ -1323,7 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
let args_raw = self_ctor_args.unwrap_or_else(|| { let args_raw = implicit_args.unwrap_or_else(|| {
lower_generic_args( lower_generic_args(
self, self,
def_id, def_id,

View file

@ -426,6 +426,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
fn provided_kind( fn provided_kind(
&mut self, &mut self,
preceding_args: &[ty::GenericArg<'tcx>],
param: &ty::GenericParamDef, param: &ty::GenericParamDef,
arg: &GenericArg<'tcx>, arg: &GenericArg<'tcx>,
) -> ty::GenericArg<'tcx> { ) -> ty::GenericArg<'tcx> {
@ -446,7 +447,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
(GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
.cfcx .cfcx
// We handle the ambig portions of `ConstArg` in the match arms below // We handle the ambig portions of `ConstArg` in the match arms below
.lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id)) .lower_const_arg(
ct.as_unambig_ct(),
FeedConstTy::Param(param.def_id, preceding_args),
)
.into(), .into(),
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
self.cfcx.ct_infer(Some(param), inf.span).into() self.cfcx.ct_infer(Some(param), inf.span).into()

View file

@ -342,6 +342,7 @@ impl ParamConst {
ParamConst::new(def.index, def.name) ParamConst::new(def.index, def.name)
} }
#[instrument(level = "debug")]
pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> { pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
let mut candidates = env.caller_bounds().iter().filter_map(|clause| { let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
// `ConstArgHasType` are never desugared to be higher ranked. // `ConstArgHasType` are never desugared to be higher ranked.

View file

@ -125,9 +125,6 @@ resolve_const_param_in_enum_discriminant =
resolve_const_param_in_non_trivial_anon_const = resolve_const_param_in_non_trivial_anon_const =
const parameters may only be used as standalone arguments, i.e. `{$name}` const parameters may only be used as standalone arguments, i.e. `{$name}`
resolve_const_param_in_ty_of_const_param =
const parameters may not be used in the type of const parameters
resolve_constructor_private_if_any_field_private = resolve_constructor_private_if_any_field_private =
a constructor is private if any of the fields is private a constructor is private if any of the fields is private
@ -250,9 +247,6 @@ resolve_lifetime_param_in_enum_discriminant =
resolve_lifetime_param_in_non_trivial_anon_const = resolve_lifetime_param_in_non_trivial_anon_const =
lifetime parameters may not be used in const expressions lifetime parameters may not be used in const expressions
resolve_lifetime_param_in_ty_of_const_param =
lifetime parameters may not be used in the type of const parameters
resolve_lowercase_self = resolve_lowercase_self =
attempt to use a non-constant value in a constant attempt to use a non-constant value in a constant
.suggestion = try using `Self` .suggestion = try using `Self`
@ -437,9 +431,6 @@ resolve_type_param_in_enum_discriminant =
resolve_type_param_in_non_trivial_anon_const = resolve_type_param_in_non_trivial_anon_const =
type parameters may not be used in const expressions type parameters may not be used in const expressions
resolve_type_param_in_ty_of_const_param =
type parameters may not be used in the type of const parameters
resolve_undeclared_label = resolve_undeclared_label =
use of undeclared label `{$name}` use of undeclared label `{$name}`
.label = undeclared label `{$name}` .label = undeclared label `{$name}`

View file

@ -890,9 +890,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ResolutionError::ForwardDeclaredGenericParam => { ResolutionError::ForwardDeclaredGenericParam => {
self.dcx().create_err(errs::ForwardDeclaredGenericParam { span }) self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
} }
ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self ResolutionError::ParamInTyOfConstParam { name } => {
.dcx() self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
.create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }), }
ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => { ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
self.dcx().create_err(errs::ParamInNonTrivialAnonConst { self.dcx().create_err(errs::ParamInNonTrivialAnonConst {
span, span,

View file

@ -347,19 +347,6 @@ pub(crate) struct ParamInTyOfConstParam {
#[label] #[label]
pub(crate) span: Span, pub(crate) span: Span,
pub(crate) name: Symbol, pub(crate) name: Symbol,
#[subdiagnostic]
pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
}
#[derive(Debug)]
#[derive(Subdiagnostic)]
pub(crate) enum ParamKindInTyOfConstParam {
#[note(resolve_type_param_in_ty_of_const_param)]
Type,
#[note(resolve_const_param_in_ty_of_const_param)]
Const,
#[note(resolve_lifetime_param_in_ty_of_const_param)]
Lifetime,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View file

@ -1131,6 +1131,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return Res::Err; return Res::Err;
} }
if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
);
}
assert_eq!(res, Res::Err);
return Res::Err;
}
match res { match res {
Res::Local(_) => { Res::Local(_) => {
use ResolutionError::*; use ResolutionError::*;
@ -1209,10 +1220,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(span) = finalize { if let Some(span) = finalize {
self.report_error( self.report_error(
span, span,
ParamInTyOfConstParam { ParamInTyOfConstParam { name: rib_ident.name },
name: rib_ident.name,
param_kind: None,
},
); );
} }
return Res::Err; return Res::Err;
@ -1239,6 +1247,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| RibKind::MacroDefinition(..) | RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym | RibKind::InlineAsmSym
| RibKind::AssocItem | RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => { | RibKind::ForwardGenericParamBan => {
// Nothing to do. Continue. // Nothing to do. Continue.
continue; continue;
@ -1292,18 +1301,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
RibKind::Item(has_generic_params, def_kind) => { RibKind::Item(has_generic_params, def_kind) => {
(has_generic_params, def_kind) (has_generic_params, def_kind)
} }
RibKind::ConstParamTy => {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
},
);
}
return Res::Err;
}
}; };
if let Some(span) = finalize { if let Some(span) = finalize {
@ -1328,6 +1325,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| RibKind::MacroDefinition(..) | RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym | RibKind::InlineAsmSym
| RibKind::AssocItem | RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => continue, | RibKind::ForwardGenericParamBan => continue,
RibKind::ConstantItem(trivial, _) => { RibKind::ConstantItem(trivial, _) => {
@ -1361,18 +1359,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
RibKind::Item(has_generic_params, def_kind) => { RibKind::Item(has_generic_params, def_kind) => {
(has_generic_params, def_kind) (has_generic_params, def_kind)
} }
RibKind::ConstParamTy => {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
},
);
}
return Res::Err;
}
}; };
// This was an attempt to use a const parameter outside its scope. // This was an attempt to use a const parameter outside its scope.

View file

@ -227,9 +227,11 @@ impl RibKind<'_> {
| RibKind::ConstantItem(..) | RibKind::ConstantItem(..)
| RibKind::Module(_) | RibKind::Module(_)
| RibKind::MacroDefinition(_) | RibKind::MacroDefinition(_)
| RibKind::ConstParamTy
| RibKind::InlineAsmSym => false, | RibKind::InlineAsmSym => false,
RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true, RibKind::ConstParamTy
| RibKind::AssocItem
| RibKind::Item(..)
| RibKind::ForwardGenericParamBan => true,
} }
} }
@ -1570,6 +1572,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
} }
let mut forward_ty_ban_rib_const_param_ty = Rib {
bindings: forward_ty_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
};
let mut forward_const_ban_rib_const_param_ty = Rib {
bindings: forward_const_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
};
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
for param in params { for param in params {
match param.kind { match param.kind {
@ -1592,21 +1605,27 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
} }
// Allow all following defaults to refer to this type parameter. // Allow all following defaults to refer to this type parameter.
forward_ty_ban_rib let i = &Ident::with_dummy_span(param.ident.name);
.bindings forward_ty_ban_rib.bindings.remove(i);
.remove(&Ident::with_dummy_span(param.ident.name)); if this.r.tcx.features().generic_const_parameter_types() {
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
}
} }
GenericParamKind::Const { ref ty, kw_span: _, ref default } => { GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
// Const parameters can't have param bounds. // Const parameters can't have param bounds.
assert!(param.bounds.is_empty()); assert!(param.bounds.is_empty());
this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);
this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty);
this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { if this.r.tcx.features().generic_const_parameter_types() {
this.visit_ty(ty) this.visit_ty(ty)
}); } else {
this.ribs[TypeNS].pop().unwrap(); this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
this.ribs[ValueNS].pop().unwrap(); this.visit_ty(ty)
});
}
forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
if let Some(expr) = default { if let Some(expr) = default {
this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[TypeNS].push(forward_ty_ban_rib);
@ -1620,9 +1639,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
} }
// Allow all following defaults to refer to this const parameter. // Allow all following defaults to refer to this const parameter.
forward_const_ban_rib let i = &Ident::with_dummy_span(param.ident.name);
.bindings forward_const_ban_rib.bindings.remove(i);
.remove(&Ident::with_dummy_span(param.ident.name)); if this.r.tcx.features().generic_const_parameter_types() {
forward_const_ban_rib_const_param_ty.bindings.remove(i);
}
} }
} }
} }

View file

@ -3052,7 +3052,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
.create_err(errors::ParamInTyOfConstParam { .create_err(errors::ParamInTyOfConstParam {
span: lifetime_ref.ident.span, span: lifetime_ref.ident.span,
name: lifetime_ref.ident.name, name: lifetime_ref.ident.name,
param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
}) })
.emit(); .emit();
} }

View file

@ -30,9 +30,7 @@ use std::sync::Arc;
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use effective_visibilities::EffectiveVisibilitiesVisitor; use effective_visibilities::EffectiveVisibilitiesVisitor;
use errors::{ use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
};
use imports::{Import, ImportData, ImportKind, NameResolution}; use imports::{Import, ImportData, ImportKind, NameResolution};
use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification}; use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
@ -276,8 +274,10 @@ enum ResolutionError<'ra> {
}, },
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers. /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam, ForwardDeclaredGenericParam,
// FIXME(generic_const_parameter_types): This should give custom output specifying it's only
// problematic to use *forward declared* parameters when the feature is enabled.
/// ERROR E0770: the type of const parameters must not depend on other generic parameters. /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> }, ParamInTyOfConstParam { name: Symbol },
/// generic parameters must not be used inside const evaluations. /// generic parameters must not be used inside const evaluations.
/// ///
/// This error is only emitted when using `min_const_generics`. /// This error is only emitted when using `min_const_generics`.

View file

@ -1037,6 +1037,7 @@ symbols! {
generic_associated_types_extended, generic_associated_types_extended,
generic_const_exprs, generic_const_exprs,
generic_const_items, generic_const_items,
generic_const_parameter_types,
generic_param_attrs, generic_param_attrs,
generic_pattern_types, generic_pattern_types,
get_context, get_context,

View file

@ -1189,9 +1189,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let span = obligation.cause.span; let span = obligation.cause.span;
let mut diag = match ty.kind() { let mut diag = match ty.kind() {
_ if ty.has_param() => {
span_bug!(span, "const param tys cannot mention other generic parameters");
}
ty::Float(_) => { ty::Float(_) => {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),

View file

@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]); LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:15:40 --> $DIR/const-param-type-depends-on-const-param.rs:15:40
| |
LL | pub struct SelfDependent<const N: [u8; N]>; LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]); LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:15:40 --> $DIR/const-param-type-depends-on-const-param.rs:15:40
| |
LL | pub struct SelfDependent<const N: [u8; N]>; LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error: `[u8; N]` is forbidden as the type of a const generic parameter error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:11:47 --> $DIR/const-param-type-depends-on-const-param.rs:11:47

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct B<T, const N: T>(PhantomData<[T; N]>); LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub struct Dependent<T, const X: T>([(); X]); LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:11:22 --> $DIR/const-param-type-depends-on-type-param.rs:11:22

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub struct Dependent<T, const X: T>([(); X]); LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/const-param-type-depends-on-type-param.rs:11:22 --> $DIR/const-param-type-depends-on-type-param.rs:11:22

View file

@ -0,0 +1,23 @@
#![feature(
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
generic_arg_infer
)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy_;
fn foo<T: ConstParamTy_, const N: usize, const M: [T; N]>() -> [T; N] {
loop {}
}
fn main() {
// Requires inferring `T`/`N` from `12_u8` and `2` respectively.
let a = foo::<_, _, { [12_u8; 2] }>();
//~^ ERROR: anonymous constants with inferred types are not yet supported
// Requires inferring `T`/`N`/`12_?i`/`_` from `[u8; 2]`
let b: [u8; 2] = foo::<_, _, { [12; _] }>();
//~^ ERROR: anonymous constants with inferred types are not yet supported
}

View file

@ -0,0 +1,14 @@
error: anonymous constants with inferred types are not yet supported
--> $DIR/bad_inference.rs:17:25
|
LL | let a = foo::<_, _, { [12_u8; 2] }>();
| ^^^^^^^^^^^^^^
error: anonymous constants with inferred types are not yet supported
--> $DIR/bad_inference.rs:21:34
|
LL | let b: [u8; 2] = foo::<_, _, { [12; _] }>();
| ^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -0,0 +1,19 @@
//@ check-pass
#![feature(
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
generic_arg_infer
)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy_;
fn foo<T: ConstParamTy_, const N: usize, const M: [T; N]>() -> [T; N] {
M
}
fn main() {
let a: [u8; 2] = foo::<u8, 2, { [12; _] }>();
}

View file

@ -0,0 +1,11 @@
#![feature(adt_const_params, generic_const_parameter_types)]
#![expect(incomplete_features)]
use std::marker::PhantomData;
struct UsesConst<const N: [u8; M], const M: usize>;
//~^ ERROR: the type of const parameters must not depend on other generic parameters
struct UsesType<const N: [T; 2], T>(PhantomData<T>);
//~^ ERROR: the type of const parameters must not depend on other generic parameters
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/forward_declared_type.rs:6:32
|
LL | struct UsesConst<const N: [u8; M], const M: usize>;
| ^ the type must not depend on the parameter `M`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/forward_declared_type.rs:8:27
|
LL | struct UsesType<const N: [T; 2], T>(PhantomData<T>);
| ^ the type must not depend on the parameter `T`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0770`.

View file

@ -0,0 +1,13 @@
//@ check-pass
#![feature(adt_const_params, generic_arg_infer, generic_const_parameter_types)]
#![expect(incomplete_features)]
struct Bar<const N: usize, const M: [u8; N]>;
fn foo<const N: usize, const M: [u8; N]>(_: Bar<N, M>) {}
fn main() {
foo(Bar::<2, { [1; 2] }>);
foo::<_, _>(Bar::<2, { [1; 2] }>);
}

View file

@ -0,0 +1,20 @@
#![feature(generic_const_parameter_types, adt_const_params, unsized_const_params)]
#![expect(incomplete_features)]
fn foo<'a, const N: &'a u32>() {}
fn bar() {
foo::<'static, { &1_u32 }>();
//~^ ERROR: anonymous constants with lifetimes in their type are not yet supported
foo::<'_, { &1_u32 }>();
//~^ ERROR: anonymous constants with lifetimes in their type are not yet supported
}
fn borrowck<'a, const N: &'static u32, const M: &'a u32>() {
foo::<'a, M>();
foo::<'static, M>();
//~^ ERROR: lifetime may not live long enough
foo::<'static, N>();
}
fn main() {}

View file

@ -0,0 +1,23 @@
error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/lifetime_dependent_const_param.rs:7:20
|
LL | foo::<'static, { &1_u32 }>();
| ^^^^^^^^^^
error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/lifetime_dependent_const_param.rs:9:15
|
LL | foo::<'_, { &1_u32 }>();
| ^^^^^^^^^^
error: lifetime may not live long enough
--> $DIR/lifetime_dependent_const_param.rs:15:5
|
LL | fn borrowck<'a, const N: &'static u32, const M: &'a u32>() {
| -- lifetime `'a` defined here
LL | foo::<'a, M>();
LL | foo::<'static, M>();
| ^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: aborting due to 3 previous errors

View file

@ -0,0 +1,15 @@
#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy_;
fn foo<const N: usize, const M: [u8; N]>() {}
fn bar<T: ConstParamTy_, const M: [T; 2]>() {}
fn main() {
foo::<3, { [1; 2] }>();
//~^ ERROR: mismatched type
bar::<u8, { [2_u16; 2] }>();
//~^ ERROR: mismatched type
}

View file

@ -0,0 +1,21 @@
error[E0308]: mismatched types
--> $DIR/mismatched_args_with_value.rs:10:16
|
LL | foo::<3, { [1; 2] }>();
| ^^^^^^ expected an array with a size of 3, found one with a size of 2
error[E0308]: mismatched types
--> $DIR/mismatched_args_with_value.rs:13:18
|
LL | bar::<u8, { [2_u16; 2] }>();
| ^^^^^ expected `u8`, found `u16`
|
help: change the type of the numeric literal from `u16` to `u8`
|
LL - bar::<u8, { [2_u16; 2] }>();
LL + bar::<u8, { [2_u8; 2] }>();
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,9 @@
#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)]
#![expect(incomplete_features)]
use std::marker::{ConstParamTy_, PhantomData};
struct UsesType<T, const N: usize, const M: [T; N]>(PhantomData<T>);
//~^ ERROR: `[T; N]` can't be used as a const parameter type
fn main() {}

View file

@ -0,0 +1,11 @@
error[E0741]: `[T; N]` can't be used as a const parameter type
--> $DIR/no_const_param_ty_bound.rs:6:45
|
LL | struct UsesType<T, const N: usize, const M: [T; N]>(PhantomData<T>);
| ^^^^^^
|
= note: `T` must implement `UnsizedConstParamTy`, but it does not
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0741`.

View file

@ -0,0 +1,21 @@
//@ check-pass
#![feature(
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
generic_arg_infer
)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy_;
fn foo<U, T: ConstParamTy_, const N: usize, const M: [T; N]>(_: U) -> [T; N] {
loop {}
}
fn main() {
// Check that `_` doesnt cause a "Type of const argument is uninferred" error
// as it is not actually used by the type of `M`.
let a = foo::<_, u8, 2, { [12; _] }>(true);
}

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
| ^^ the type must not depend on the parameter `'a` | ^^ the type must not depend on the parameter `'a`
|
= note: lifetime parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
| ^^ the type must not depend on the parameter `'a` | ^^ the type must not depend on the parameter `'a`
|
= note: lifetime parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn foo<const N: usize, const A: [u8; N]>() {} LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn foo<const N: usize, const A: [u8; N]>() {} LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^ the type must not depend on the parameter `N` | ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters
error: `[u8; N]` is forbidden as the type of a const generic parameter error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/issue-62878.rs:5:33 --> $DIR/issue-62878.rs:5:33

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
| ^^^ the type must not depend on the parameter `LEN` | ^^^ the type must not depend on the parameter `LEN`
|
= note: const parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
| ^^^ the type must not depend on the parameter `LEN` | ^^^ the type must not depend on the parameter `LEN`
|
= note: const parameters may not be used in the type of const parameters
error: `[u8; LEN]` is forbidden as the type of a const generic parameter error: `[u8; LEN]` is forbidden as the type of a const generic parameter
--> $DIR/issue-71169.rs:5:38 --> $DIR/issue-71169.rs:5:38

View file

@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^ the type must not depend on the parameter `Args` | ^^^^ the type must not depend on the parameter `Args`
|
= note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:23:40 --> $DIR/issue-71381.rs:23:40
| |
LL | const FN: unsafe extern "C" fn(Args), LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args` | ^^^^ the type must not depend on the parameter `Args`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^ the type must not depend on the parameter `Args` | ^^^^ the type must not depend on the parameter `Args`
|
= note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:23:40 --> $DIR/issue-71381.rs:23:40
| |
LL | const FN: unsafe extern "C" fn(Args), LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args` | ^^^^ the type must not depend on the parameter `Args`
|
= note: type parameters may not be used in the type of const parameters
error: using function pointers as const generic parameters is forbidden error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:14:61 --> $DIR/issue-71381.rs:14:61

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn func<A, const F: fn(inner: A)>(outer: A) { LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^ the type must not depend on the parameter `A` | ^ the type must not depend on the parameter `A`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn func<A, const F: fn(inner: A)>(outer: A) { LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^ the type must not depend on the parameter `A` | ^ the type must not depend on the parameter `A`
|
= note: type parameters may not be used in the type of const parameters
error: using function pointers as const generic parameters is forbidden error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71611.rs:5:21 --> $DIR/issue-71611.rs:5:21

View file

@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T) LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-88997.rs:8:54 --> $DIR/issue-88997.rs:8:54
| |
LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T) LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | pub struct Foo<T, const H: T>(T) LL | pub struct Foo<T, const H: T>(T)
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | fn function_with_str<'a, const STRING: &'a str>() {} LL | fn function_with_str<'a, const STRING: &'a str>() {}
| ^^ the type must not depend on the parameter `'a` | ^^ the type must not depend on the parameter `'a`
|
= note: lifetime parameters may not be used in the type of const parameters
warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/E0771.rs:1:30 --> $DIR/E0771.rs:1:30

View file

@ -0,0 +1,21 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/feature-gate-generic-const-parameter-types.rs:7:50
|
LL | struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
| ^^^ the type must not depend on the parameter `LEN`
error: `[u8; LEN]` is forbidden as the type of a const generic parameter
--> $DIR/feature-gate-generic-const-parameter-types.rs:7:45
|
LL | struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
| ^^^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0770`.

View file

@ -0,0 +1,11 @@
//@ [feature] check-pass
//@ revisions: normal feature
#![cfg_attr(feature, feature(adt_const_params, generic_const_parameter_types))]
#![cfg_attr(feature, expect(incomplete_features))]
struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
//[normal]~^ ERROR: the type of const parameters must not depend on other generic parameters
//[normal]~| ERROR: `[u8; LEN]` is forbidden as the type of a const generic parameter
fn main() {}

View file

@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct G<T, const N: Vec<T>>(T); LL | struct G<T, const N: Vec<T>>(T);
| ^ the type must not depend on the parameter `T` | ^ the type must not depend on the parameter `T`
|
= note: type parameters may not be used in the type of const parameters
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -9,8 +9,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
| |
LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>; LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
| ^^ the type must not depend on the parameter `'a` | ^^ the type must not depend on the parameter `'a`
|
= note: lifetime parameters may not be used in the type of const parameters
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/unusual-rib-combinations.rs:11:15 --> $DIR/unusual-rib-combinations.rs:11:15

View file

@ -3,6 +3,7 @@ trait Foo<const N: Bar<2>> {
//~^ WARN trait objects without an explicit `dyn` are deprecated //~^ 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! //~| 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 cycle detected when computing type of `Foo::N`
//~| ERROR cycle detected when computing type of `Foo::N`
fn func() {} fn func() {}
} }

View file

@ -13,7 +13,7 @@ LL | trait Foo<const N: dyn Bar<2>> {
| +++ | +++
warning: trait objects without an explicit `dyn` are deprecated warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:20 --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20
| |
LL | trait Bar<const M: Foo<2>> {} LL | trait Bar<const M: Foo<2>> {}
| ^^^^^^ | ^^^^^^
@ -32,7 +32,7 @@ LL | trait Foo<const N: Bar<2>> {
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
note: ...which requires computing type of `Bar::M`... note: ...which requires computing type of `Bar::M`...
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:11 --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11
| |
LL | trait Bar<const M: Foo<2>> {} LL | trait Bar<const M: Foo<2>> {}
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
@ -44,6 +44,26 @@ LL | trait Foo<const N: Bar<2>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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 = 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[E0391]: cycle detected when computing type of `Foo::N`
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11
|
LL | trait Foo<const N: Bar<2>> {
| ^^^^^^^^^^^^^^^
|
note: ...which requires computing type of `Bar::M`...
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11
|
LL | trait Bar<const M: Foo<2>> {}
| ^^^^^^^^^^^^^^^
= note: ...which again requires computing type of `Foo::N`, completing the cycle
note: cycle used when computing explicit predicates of trait `Foo`
--> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1
|
LL | trait Foo<const N: Bar<2>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors; 2 warnings emitted
For more information about this error, try `rustc --explain E0391`. For more information about this error, try `rustc --explain E0391`.