Skip to content

Commit e8df0ee

Browse files
Rollup merge of rust-lang#157949 - bb1yd:allow-self-in-const-generics, r=BoxyUwU
Allow self in const generics Fixes rust-lang#149203
2 parents 16d9d4b + a8d9636 commit e8df0ee

10 files changed

Lines changed: 139 additions & 14 deletions

File tree

‎compiler/rustc_hir_analysis/src/collect/type_of.rs‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tracing::instrument;
1313

1414
use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder};
1515
use crate::check::wfcheck::check_static_item;
16+
use crate::diagnostics::ParamInTyOfConstParam;
1617
use crate::hir_ty_lowering::HirTyLowerer;
1718

1819
mod opaque;
@@ -239,8 +240,19 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
239240
}
240241

241242
Node::GenericParam(param) => match &param.kind {
242-
GenericParamKind::Type { default: Some(ty), .. }
243-
| GenericParamKind::Const { ty, .. } => icx.lower_ty(ty),
243+
GenericParamKind::Type { default: Some(ty), .. } => icx.lower_ty(ty),
244+
GenericParamKind::Const { ty, .. } => {
245+
let lowered_ty = icx.lower_ty(ty);
246+
if !tcx.features().generic_const_parameter_types() && lowered_ty.has_param() {
247+
let guar = tcx
248+
.dcx()
249+
.create_err(ParamInTyOfConstParam { span: ty.span, ty: lowered_ty })
250+
.emit();
251+
Ty::new_error(tcx, guar)
252+
} else {
253+
lowered_ty
254+
}
255+
}
244256
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
245257
},
246258

‎compiler/rustc_hir_analysis/src/diagnostics.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,3 +2144,12 @@ pub(crate) struct OnlyStructsCanBeViewedAdt<'tcx> {
21442144
pub article: &'static str,
21452145
pub kind: &'static str,
21462146
}
2147+
2148+
#[derive(Diagnostic)]
2149+
#[diag("the type of const parameters must not depend on other generic parameters", code = E0770)]
2150+
pub(crate) struct ParamInTyOfConstParam<'tcx> {
2151+
#[primary_span]
2152+
#[label("the type `{$ty}` must not depend on other generic parameter")]
2153+
pub(crate) span: Span,
2154+
pub(crate) ty: Ty<'tcx>,
2155+
}

‎compiler/rustc_resolve/src/diagnostics/impls.rs‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12821282
ResolutionError::ParamInTyOfConstParam { name } => {
12831283
self.dcx().create_err(diagnostics::ParamInTyOfConstParam { span, name })
12841284
}
1285+
ResolutionError::SelfInConstParam => {
1286+
self.dcx().create_err(diagnostics::SelfInConstGenericTy {
1287+
span,
1288+
enable_feature: self.tcx().sess.is_nightly_build(),
1289+
})
1290+
}
12851291
ResolutionError::ParamInNonTrivialAnonConst { is_gca, name, param_kind: is_type } => {
12861292
self.dcx().create_err(diagnostics::ParamInNonTrivialAnonConst {
12871293
span,
@@ -1305,9 +1311,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
13051311
ForwardGenericParamBanReason::Default => {
13061312
self.dcx().create_err(diagnostics::SelfInGenericParamDefault { span })
13071313
}
1308-
ForwardGenericParamBanReason::ConstParamTy => {
1309-
self.dcx().create_err(diagnostics::SelfInConstGenericTy { span })
1310-
}
1314+
ForwardGenericParamBanReason::ConstParamTy => self
1315+
.dcx()
1316+
.create_err(diagnostics::SelfInConstGenericTy { span, enable_feature: false }),
13111317
},
13121318
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
13131319
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =

‎compiler/rustc_resolve/src/diagnostics/mod.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ pub(crate) struct SelfInGenericParamDefault {
386386
pub(crate) struct SelfInConstGenericTy {
387387
#[primary_span]
388388
pub(crate) span: Span,
389+
#[help(
390+
"add `#![feature(min_adt_const_params)]` to the crate attributes to enable `Self` as a const parameter type"
391+
)]
392+
pub(crate) enable_feature: bool,
389393
}
390394

391395
#[derive(Diagnostic)]

‎compiler/rustc_resolve/src/ident.rs‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,18 +1596,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15961596
}
15971597

15981598
RibKind::ConstParamTy => {
1599-
if !self.features.generic_const_parameter_types() {
1599+
let adt_enabled = self.features.min_adt_const_params()
1600+
|| self.features.adt_const_params();
1601+
let is_self = matches!(res, Res::SelfTyAlias { .. });
1602+
// We check whether Self depends on generics parameters in `fn type_of`
1603+
if self.features.generic_const_parameter_types()
1604+
|| (adt_enabled && is_self)
1605+
{
1606+
continue;
1607+
} else {
16001608
if let Some(span) = finalize {
1601-
self.report_error(
1602-
span,
1603-
ResolutionError::ParamInTyOfConstParam {
1604-
name: rib_ident.name,
1605-
},
1606-
);
1609+
if matches!(res, Res::SelfTyAlias { .. }) {
1610+
self.report_error(span, ResolutionError::SelfInConstParam);
1611+
} else {
1612+
self.report_error(
1613+
span,
1614+
ResolutionError::ParamInTyOfConstParam {
1615+
name: rib_ident.name,
1616+
},
1617+
);
1618+
}
16071619
}
16081620
return Res::Err;
1609-
} else {
1610-
continue;
16111621
}
16121622
}
16131623

‎compiler/rustc_resolve/src/lib.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ enum ResolutionError<'ra> {
299299
// problematic to use *forward declared* parameters when the feature is enabled.
300300
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
301301
ParamInTyOfConstParam { name: Symbol },
302+
/// cannot use self in const param
303+
SelfInConstParam,
302304
/// generic parameters must not be used inside const evaluations.
303305
///
304306
/// This error is only emitted when using `min_const_generics`.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Allow Self in const generics when Self doesn't depends on generics(#149203)
2+
#![feature(min_adt_const_params)]
3+
4+
//1
5+
trait MyTrait {
6+
fn foo<const N: i32>();
7+
}
8+
9+
impl MyTrait for i32 {
10+
fn foo<const N: Self>() {}
11+
}
12+
13+
//2
14+
impl<T> Wrap<T> {
15+
fn f<const N: Self>() {}
16+
//~^ ERROR the type of const parameters must not depend on other generic parameters
17+
18+
}
19+
struct Wrap<T>(T);
20+
21+
//3
22+
type Foo<const N: usize> = Bar;
23+
24+
#[derive(Eq, PartialEq, core::marker::ConstParamTy)]
25+
struct Bar;
26+
27+
trait Trait<const N: usize> {
28+
fn bar<const C: Bar>();
29+
}
30+
31+
impl<const N: usize> Trait<N> for Foo<N> {
32+
fn bar<const C: Self>() {}
33+
// FIXME: currently the compiler let this pass
34+
// https://github.com/rust-lang/rust/pull/157949#discussion_r3544858218
35+
}
36+
fn main(){}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0770]: the type of const parameters must not depend on other generic parameters
2+
--> $DIR/allow-self-in-const-generics.rs:15:19
3+
|
4+
LL | fn f<const N: Self>() {}
5+
| ^^^^ the type `Wrap<T>` must not depend on other generic parameter
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0770`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Ban Self in const generics when min_adt_const_params and adt_const_params are not enabled
2+
// #149203
3+
trait MyTrait {
4+
fn foo<const N: i32>();
5+
}
6+
7+
impl MyTrait for i32 {
8+
fn foo<const N: Self>() {}
9+
//~^ ERROR cannot use `Self` in const parameter type
10+
//~| ERROR associated function `foo` has an incompatible generic parameter for trait `MyTrait`
11+
}
12+
13+
fn main(){}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: cannot use `Self` in const parameter type
2+
--> $DIR/ban-self-when-feature-not-enabled.rs:8:21
3+
|
4+
LL | fn foo<const N: Self>() {}
5+
| ^^^^
6+
|
7+
= help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable `Self` as a const parameter type
8+
9+
error[E0053]: associated function `foo` has an incompatible generic parameter for trait `MyTrait`
10+
--> $DIR/ban-self-when-feature-not-enabled.rs:8:12
11+
|
12+
LL | trait MyTrait {
13+
| -------
14+
LL | fn foo<const N: i32>();
15+
| ------------ expected const parameter of type `i32`
16+
...
17+
LL | impl MyTrait for i32 {
18+
| --------------------
19+
LL | fn foo<const N: Self>() {}
20+
| ^^^^^^^^^^^^^ found const parameter of type `{type error}`
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0053`.

0 commit comments

Comments
 (0)