Skip to content
Open
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
12 changes: 10 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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::{InvalidReceiverTyHint, ParamInTyOfConstParam};

pub(super) struct WfCheckingCtxt<'a, 'tcx> {
pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>,
Expand Down Expand Up @@ -855,7 +855,15 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
let ty = tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip();
let span = tcx.def_span(param.def_id);
let def_id = param.def_id.expect_local();

if !tcx.features().generic_const_parameter_types() && ty.has_param() {
let hir::GenericParamKind::Const { ty: &hir::Ty { span, .. }, .. } =
tcx.hir_node_by_def_id(def_id).expect_generic_param().kind
else {
bug!()
};
let err = tcx.dcx().create_err(ParamInTyOfConstParam { span, ty }).emit();
return Err(err);
}
if tcx.features().const_param_ty_unchecked() {
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
wfcx.register_wf_obligation(span, None, ty.into());
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_hir_analysis/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2000,3 +2000,12 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for UncoveredTyParam<'_> {
diag
}
}

#[derive(Diagnostic)]
#[diag("the type of const parameters must not depend on other generic parameters", code = E0770)]
pub(crate) struct ParamInTyOfConstParam<'tcx> {
#[primary_span]
#[label("the type `{$ty}` must not depend on other generic parameter")]
pub(crate) span: Span,
pub(crate) ty: Ty<'tcx>,
}
5 changes: 4 additions & 1 deletion compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1584,7 +1584,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}

RibKind::ConstParamTy => {

@fmease fmease Jun 16, 2026

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.

IINM you're now accepting this code despite N depending on T which shouldn't be allowed w/o enabling GCPT.

impl<T> Wrap<T> {
    fn f<const N: Self>() {}
}

struct Wrap<T>(T);

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to check if Self depends on generics?

@fmease fmease Jun 18, 2026

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.

I'm not super well-versed in name resolution, so I don't know if there's a good way to do this in rustc_resolve that still nicely leverages the existing rib structure. Boxy probably has an idea.

Calling type_of here on the LocalDefId found in the SelfTyAlias is probably too prone to cycles or hangs; looking at hir_node corresp. to the LocalDefId might be an option but that might not integrate with the visitor.

Naively speaking, I would do it in HIR ty lowering by inspecting the type as returned by type_of and by reusing+generalizing check_assoc_const_binding_type but that's probably also not super ideal. I haven't read a lot of the new mGCA code in HIR ty lowering, maybe there's already a function for that (that's similar to check_assoc_const_binding_type?)?

if !self.features.generic_const_parameter_types() {
// We check whether Self depends on generics parameters during HIR analysis
if !self.features.generic_const_parameter_types()
&& !matches!(res, Res::SelfTyAlias { .. })
{
if let Some(span) = finalize {
self.report_error(
span,
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/resolve/allow-self-in-const-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Allow Self in const generics when Self doesn't depends on generics
trait MyTrait {
fn foo<const N: i32>();
}

impl MyTrait for i32 {
fn foo<const N: Self>() {}
}
impl<T> Wrap<T> {
fn f<const N: Self>() {}
//~^ ERROR the type of const parameters must not depend on other generic parameters

}

struct Wrap<T>(T);
fn main(){}
9 changes: 9 additions & 0 deletions tests/ui/resolve/allow-self-in-const-generics.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/allow-self-in-const-generics.rs:10:19
|
LL | fn f<const N: Self>() {}
| ^^^^ the type `Wrap<T>` must not depend on other generic parameter

error: aborting due to 1 previous error

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