Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
tcx.require_lang_item(LangItem::Sized, ty_span),
);
check_where_clauses(wfcx, def_id);
wfcheck::check_const_item(wfcx, def_id, ty);
Ok(())
wfcheck::check_const_item(wfcx, def_id, ty)
}));

// Only `Node::Item` and `Node::ForeignItem` still have HIR based
Expand Down
37 changes: 24 additions & 13 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ use tracing::{debug, instrument};
use super::compare_eii::{compare_eii_function_types, compare_eii_statics};
use crate::autoderef::Autoderef;
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
use crate::diagnostics;
use crate::diagnostics::InvalidReceiverTyHint;
use crate::diagnostics::{self, InvalidReceiverTyHint, ParamInTyOfConstParam};

pub(super) struct WfCheckingCtxt<'a, 'tcx> {
pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>,
Expand Down Expand Up @@ -927,7 +926,6 @@ pub(crate) fn check_associated_item(
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_const_item(wfcx, def_id, ty);

if item.defaultness(tcx).has_value() {
let code = ObligationCauseCode::SizedConstOrStatic;
Expand All @@ -939,7 +937,7 @@ pub(crate) fn check_associated_item(
);
}

Ok(())
check_const_item(wfcx, def_id, ty)
}
ty::AssocKind::Fn { .. } => {
let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
Expand Down Expand Up @@ -1259,22 +1257,33 @@ pub(crate) fn check_static_item<'tcx>(
}

/// Runs checks common to both free consts and associated consts
#[instrument(level = "debug", skip(wfcx))]
#[instrument(level = "debug", skip(wfcx), ret)]
pub(super) fn check_const_item<'tcx>(
wfcx: &WfCheckingCtxt<'_, 'tcx>,
def_id: LocalDefId,
item_ty: Ty<'tcx>,
) {
) -> Result<(), ErrorGuaranteed> {
let tcx = wfcx.tcx();
let span = tcx.def_span(def_id);

if tcx.is_direct_const(def_id.into()) && !tcx.features().const_param_ty_unchecked() {
wfcx.register_bound(
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
wfcx.param_env,
item_ty,
tcx.require_lang_item(LangItem::ConstParamTy, span),
);
let mut res = Ok(());

if tcx.is_direct_const(def_id.into()) {
if !tcx.features().const_param_ty_unchecked() {
wfcx.register_bound(
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)),
wfcx.param_env,
item_ty,
tcx.require_lang_item(LangItem::ConstParamTy, span),
);
}
// FIXME(min_generic_const_args): We *might* want to move this check to `type_of`, so we can
// return `ty::Error` if it references invalid params. However, doing so is hard, because
// `type_of` doesn't know if it's a direct const - `const_of_item` determines that, and
// `const_of_item` calls `type_of`.
if !tcx.features().generic_const_parameter_types() && item_ty.has_param() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a FIXME about how we might want to move this to type_of so we can return Error from type_of if it references invalid params

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// FIXME(min_generic_const_args): We *might* want to move this check to `type_of`, so we can
// return `ty::Error` if it references invalid params. However, doing so is hard, because
// `type_of` doesn't know if it's a direct const - `const_of_item` determines that, and
// `const_of_item` calls `type_of`.

res = Err(tcx.dcx().emit_err(ParamInTyOfConstParam { span, ty: item_ty }));
}
}

if let Some(direct_rhs) = tcx.const_of_item(def_id) {
Expand All @@ -1289,6 +1298,8 @@ pub(super) fn check_const_item<'tcx>(
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)),
));
}

res
}

#[instrument(level = "debug", skip(tcx, impl_))]
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2396,16 +2396,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// we have the ability to intermix typeck of anon const const args with the parent
// bodies typeck.

// FIXME(min_generic_const_args): This check should be removed for mGCA, it is due to
// the lack of ConstParamTy rib-checking in nameres for directly represented const
// items.

// 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.
if (tcx.features().generic_const_parameter_types()
|| tcx.features().min_generic_const_args())
if tcx.features().generic_const_parameter_types()
&& (ty.has_free_regions() || ty.has_erased_regions())
{
let e = self.dcx().span_err(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:8:77
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:12:1
|
LL | const FOO<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const FOO<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!([]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter

error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:11:62
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:15:1
|
LL | const BAR<const N: usize>: [(); N] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const BAR<const N: usize>: StructWithConstParam<N> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam<N>` must not depend on other generic parameter

error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:14:54
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:19:1
|
LL | const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!([]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter

error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:30:83
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:37:5
|
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!([]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter

error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:33:74
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:40:5
|
LL | const ASSOC_CONST<const N: usize>: [(); N] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const ASSOC_CONST<const N: usize>: StructWithConstParam<N> =
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam<N>` must not depend on other generic parameter

error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:36:63
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:44:5
|
LL | const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] });
| ^^^^^^^^^^^^
LL | const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!([]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter

error: aborting due to 6 previous errors
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:24:5
|
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter

error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:28:5
|
LL | const ASSOC_CONST<const N: usize>: StructWithConstParam<N>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam<N>` must not depend on other generic parameter

error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:32:5
|
LL | const ASSOC_LT<'a>: [&'a (); 0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter

error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0770`.
40 changes: 24 additions & 16 deletions tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,48 @@
//@ revisions: nogate gate
//@ [gate] check-fail
// FIXME(generic_const_parameter_types): this should pass
//@ [gate] check-pass
#![expect(incomplete_features)]
#![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)]
#![cfg_attr(gate, feature(generic_const_parameter_types))]

const FOO<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants referencing generics are not yet supported
use std::marker::ConstParamTy;

const BAR<const N: usize>: [(); N] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants referencing generics are not yet supported
#[derive(ConstParamTy, PartialEq, Eq, Debug)]
struct StructWithConstParam<const N: usize>;

const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants with lifetimes in their type are not yet supported
const FOO<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!([]);
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters

const BAR<const N: usize>: StructWithConstParam<N> =
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
core::direct_const_arg!(StructWithConstParam::<N>);

const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!([]);
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters

trait Tr {
// FIXME(min_generic_const_args): These should error under [nogate]
#[rustc_always_gca]
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters

#[rustc_always_gca]
const ASSOC_CONST<const N: usize>: [(); N];
const ASSOC_CONST<const N: usize>: StructWithConstParam<N>;
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters

#[rustc_always_gca]
const ASSOC_LT<'a>: [&'a (); 0];
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
}

impl Tr for () {
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants referencing generics are not yet supported
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = core::direct_const_arg!([]);
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters

const ASSOC_CONST<const N: usize>: [(); N] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants referencing generics are not yet supported
const ASSOC_CONST<const N: usize>: StructWithConstParam<N> =
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
core::direct_const_arg!(StructWithConstParam::<N>);

const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] });
//~^ ERROR anonymous constants with lifetimes in their type are not yet supported
const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!([]);
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ impl<TA> Pins<TA> for NoPin {}
pub trait PinA<PER> {
#[rustc_always_gca]
const A: &'static () = core::direct_const_arg!(const { &() });
//~^ ERROR anonymous constants with lifetimes in their type are not yet supported
}

pub trait Pins<USART> {}

impl<USART, T> Pins<USART> for T
//~^ ERROR conflicting implementations of trait `Pins<_>` for type `NoPin`
where
T: PinA<USART, A = { core::direct_const_arg!(const { &() }) }>,
//~^ ERROR anonymous constants with lifetimes in their type are not yet supported
T: PinA<USART, A = { core::direct_const_arg!(const { &() }) }>
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/assoc-const-no-infer-ice-115806.rs:22:50
|
LL | T: PinA<USART, A = { core::direct_const_arg!(const { &() }) }>,
| ^^^^^^^^^^^^^

error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin`
--> $DIR/assoc-const-no-infer-ice-115806.rs:19:1
--> $DIR/assoc-const-no-infer-ice-115806.rs:18:1
|
LL | impl<TA> Pins<TA> for NoPin {}
| --------------------------- first implementation here
...
LL | / impl<USART, T> Pins<USART> for T
LL | |
LL | | where
LL | | T: PinA<USART, A = { core::direct_const_arg!(const { &() }) }>,
| |___________________________________________________________________^ conflicting implementation for `NoPin`
LL | | T: PinA<USART, A = { core::direct_const_arg!(const { &() }) }>
| |__________________________________________________________________^ conflicting implementation for `NoPin`
|
= note: downstream crates may implement trait `PinA<_>` for type `NoPin`

error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/assoc-const-no-infer-ice-115806.rs:13:52
|
LL | const A: &'static () = core::direct_const_arg!(const { &() });
| ^^^^^^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 1 previous error

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