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
16 changes: 14 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use tracing::instrument;

use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder};
use crate::check::wfcheck::check_static_item;
use crate::diagnostics::ParamInTyOfConstParam;
use crate::hir_ty_lowering::HirTyLowerer;

mod opaque;
Expand Down Expand Up @@ -235,8 +236,19 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}

Node::GenericParam(param) => match &param.kind {
GenericParamKind::Type { default: Some(ty), .. }
| GenericParamKind::Const { ty, .. } => icx.lower_ty(ty),
GenericParamKind::Type { default: Some(ty), .. } => icx.lower_ty(ty),
GenericParamKind::Const { ty, .. } => {
let lowered_ty = icx.lower_ty(ty);
if !tcx.features().generic_const_parameter_types() && lowered_ty.has_param() {
Comment thread
BoxyUwU marked this conversation as resolved.
let guar = tcx
.dcx()
.create_err(ParamInTyOfConstParam { span: ty.span, ty: lowered_ty })
.emit();
Ty::new_error(tcx, guar)
} else {
lowered_ty
}
}
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
},

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 @@ -2030,3 +2030,12 @@ pub(crate) struct OnlyStructsCanBeViewedAdt<'tcx> {
pub article: &'static str,
pub kind: &'static str,
}

#[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>,
}
12 changes: 9 additions & 3 deletions compiler/rustc_resolve/src/diagnostics/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ResolutionError::ParamInTyOfConstParam { name } => {
self.dcx().create_err(diagnostics::ParamInTyOfConstParam { span, name })
}
ResolutionError::SelfInConstParam => {
self.dcx().create_err(diagnostics::SelfInConstGenericTy {
span,
enable_feature: self.tcx().sess.is_nightly_build(),
})
}
ResolutionError::ParamInNonTrivialAnonConst { is_gca, name, param_kind: is_type } => {
self.dcx().create_err(diagnostics::ParamInNonTrivialAnonConst {
span,
Expand All @@ -1306,9 +1312,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ForwardGenericParamBanReason::Default => {
self.dcx().create_err(diagnostics::SelfInGenericParamDefault { span })
}
ForwardGenericParamBanReason::ConstParamTy => {
self.dcx().create_err(diagnostics::SelfInConstGenericTy { span })
}
ForwardGenericParamBanReason::ConstParamTy => self
.dcx()
.create_err(diagnostics::SelfInConstGenericTy { span, enable_feature: false }),
},
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_resolve/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ pub(crate) struct SelfInGenericParamDefault {
pub(crate) struct SelfInConstGenericTy {
#[primary_span]
pub(crate) span: Span,
#[help(
"add `#![feature(min_adt_const_params)]` to the crate attributes to enable `Self` as a const parameter type"
)]
pub(crate) enable_feature: bool,
}

#[derive(Diagnostic)]
Expand Down
28 changes: 19 additions & 9 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1593,18 +1593,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}

RibKind::ConstParamTy => {
Comment thread
BoxyUwU marked this conversation as resolved.
if !self.features.generic_const_parameter_types() {
let adt_enabled = self.features.min_adt_const_params()
|| self.features.adt_const_params();
let is_self = matches!(res, Res::SelfTyAlias { .. });
// We check whether Self depends on generics parameters in `fn type_of`
if self.features.generic_const_parameter_types()
Comment thread
bb1yd marked this conversation as resolved.
|| (adt_enabled && is_self)
{
continue;
} else {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
if matches!(res, Res::SelfTyAlias { .. }) {
self.report_error(span, ResolutionError::SelfInConstParam);
} else {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
}
}
return Res::Err;
} else {
continue;
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ enum ResolutionError<'ra> {
// 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.
ParamInTyOfConstParam { name: Symbol },
/// cannot use self in const param
SelfInConstParam,
/// generic parameters must not be used inside const evaluations.
///
/// This error is only emitted when using `min_const_generics`.
Expand Down
36 changes: 36 additions & 0 deletions tests/ui/const-generics/allow-self-in-const-generics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Allow Self in const generics when Self doesn't depends on generics(#149203)
#![feature(min_adt_const_params)]

//1
trait MyTrait {
fn foo<const N: i32>();
}

impl MyTrait for i32 {
fn foo<const N: Self>() {}
}

//2
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);

//3
type Foo<const N: usize> = Bar;

#[derive(Eq, PartialEq, core::marker::ConstParamTy)]
struct Bar;

trait Trait<const N: usize> {
fn bar<const C: Bar>();
}

impl<const N: usize> Trait<N> for Foo<N> {
fn bar<const C: Self>() {}
// FIXME: currently the compiler let this pass
// https://github.com/rust-lang/rust/pull/157949#discussion_r3544858218
}
fn main(){}
9 changes: 9 additions & 0 deletions tests/ui/const-generics/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:15: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`.
13 changes: 13 additions & 0 deletions tests/ui/const-generics/ban-self-when-feature-not-enabled.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Ban Self in const generics when min_adt_const_params and adt_const_params are not enabled
// #149203
trait MyTrait {
fn foo<const N: i32>();
}

impl MyTrait for i32 {
fn foo<const N: Self>() {}
//~^ ERROR cannot use `Self` in const parameter type
//~| ERROR associated function `foo` has an incompatible generic parameter for trait `MyTrait`
}

fn main(){}
24 changes: 24 additions & 0 deletions tests/ui/const-generics/ban-self-when-feature-not-enabled.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: cannot use `Self` in const parameter type
--> $DIR/ban-self-when-feature-not-enabled.rs:8:21
|
LL | fn foo<const N: Self>() {}
| ^^^^
|
= help: add `#![feature(min_adt_const_params)]` to the crate attributes to enable `Self` as a const parameter type

error[E0053]: associated function `foo` has an incompatible generic parameter for trait `MyTrait`
--> $DIR/ban-self-when-feature-not-enabled.rs:8:12
|
LL | trait MyTrait {
| -------
LL | fn foo<const N: i32>();
| ------------ expected const parameter of type `i32`
...
LL | impl MyTrait for i32 {
| --------------------
LL | fn foo<const N: Self>() {}
| ^^^^^^^^^^^^^ found const parameter of type `{type error}`

error: aborting due to 2 previous errors

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