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: 3 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ declare_features! (
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
/// Enable mgca `type const` syntax before expansion.
(incomplete, mgca_type_const_syntax, "1.95.0", Some(132980)),
/// Allows additional const parameter types, such as [u8; 10] or user defined types.
/// User defined types must not have fields more private than the type itself.
(unstable, min_adt_const_params, "CURRENT_RUSTC_VERSION", Some(154042)),
/// Enables the generic const args MVP (only bare paths, not arbitrary computation).
(incomplete, min_generic_const_args, "1.84.0", Some(132980)),
/// A minimal, sound subset of specialization intended to be used by the
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
let span = tcx.def_span(param.def_id);
let def_id = param.def_id.expect_local();

if tcx.features().adt_const_params() {
if tcx.features().adt_const_params() || tcx.features().min_adt_const_params() {
enter_wf_checking_ctxt(tcx, tcx.local_parent(def_id), |wfcx| {
wfcx.register_bound(
ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(ty)),
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
return Ok(());
}

if !tcx.features().adt_const_params() {
match *self_type.kind() {
ty::Adt(adt, _) if adt.is_struct() => {
let struct_vis = tcx.visibility(adt.did());
for variant in adt.variants() {
for field in &variant.fields {
if !field.vis.is_at_least(struct_vis, tcx) {
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
return Err(tcx
.dcx()
.emit_err(errors::ConstParamTyFieldVisMismatch { span }));
}
}
}
}

_ => {}
}
}

let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) {
Ok(()) => Ok(()),
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,14 @@ pub(crate) struct ConstParamTyImplOnNonAdt {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("the trait `ConstParamTy` may not be implemented for this struct")]
pub(crate) struct ConstParamTyFieldVisMismatch {
#[primary_span]
#[label("struct fields are less visible than the struct")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("at least one trait is required for an object type", code = E0224)]
pub(crate) struct TraitObjectDeclaredWithNoTraits {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// const generics. Of course, `Struct` and `Enum` may contain ty params, too, but the
// benefits of including them here outweighs the small number of false positives.
Some(Res::Def(DefKind::Struct | DefKind::Enum, _))
if self.r.tcx.features().adt_const_params() =>
if self.r.tcx.features().adt_const_params()
|| self.r.tcx.features().min_adt_const_params() =>
{
Applicability::MaybeIncorrect
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,7 @@ symbols! {
meta_sized,
metadata_type,
mgca_type_const_syntax,
min_adt_const_params,
min_const_fn,
min_const_generics,
min_const_unsafe_fn,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ pub trait ConstParamTy_: StructuralPartialEq + Eq {}
/// Derive macro generating an impl of the trait `ConstParamTy`.
#[rustc_builtin_macro]
#[allow_internal_unstable(const_param_ty_trait)]
#[unstable(feature = "adt_const_params", issue = "95174")]
#[unstable(feature = "min_adt_const_params", issue = "154042", implied_by = "adt_const_params")]
pub macro ConstParamTy($item:item) {
/* compiler built-in */
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Ensure we enforce `min_adt_const_params` rules on any adt `ConstParamTy_`
//! implementation unless `adt_const_params` feature is used.
#![allow(incomplete_features)]
#![feature(const_param_ty_trait)]

use std::marker::ConstParamTy_;

#[derive(PartialEq, Eq)]
pub struct Fumo {
cirno: i32,
pub(crate) reimu: i32
}

impl ConstParamTy_ for Fumo {}
//~^ ERROR: the trait `ConstParamTy` may not be implemented for this struct

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: the trait `ConstParamTy` may not be implemented for this struct
--> $DIR/const_param_ty-on-adt-without-adt-gate.rs:14:24
|
LL | impl ConstParamTy_ for Fumo {}
| ^^^^ struct fields are less visible than the struct

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Ensure min_adt_const_params enforce
//! struct's visibility on its fields
#![allow(incomplete_features)]
#![feature(min_adt_const_params)]
#![feature(const_param_ty_trait)]

use std::marker::ConstParamTy_;

#[derive(PartialEq, Eq)]
pub struct Meowl {
pub public: i32,
private: i32
}

#[derive(PartialEq, Eq)]
pub struct Meowl2 {
pub a: i32,
pub b: i32
}

#[derive(PartialEq, Eq)]
pub(crate) struct Meowl3 {
pub(crate) a: i32,
pub b: i32
}

impl ConstParamTy_ for Meowl {}
//~^ ERROR the trait `ConstParamTy` may not be implemented for this struct
impl ConstParamTy_ for Meowl2 {}
impl ConstParamTy_ for Meowl3 {}

fn something<const N: Meowl2>() {}
fn something2<const N: Meowl3>() {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: the trait `ConstParamTy` may not be implemented for this struct
--> $DIR/min_adt_const_params-gate-fail.rs:27:24
|
LL | impl ConstParamTy_ for Meowl {}
| ^^^^^ struct fields are less visible than the struct

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// gate-test-min_adt_const_params
//@run-pass
#![feature(min_adt_const_params, const_param_ty_trait)]
#![allow(incomplete_features, dead_code)]

use std::marker::ConstParamTy_;

#[derive(PartialEq, Eq)]
pub struct Meowl {
pub public: i32,
pub also_public: i32
}

impl ConstParamTy_ for Meowl {}

fn meoow<const N: Meowl>() {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@run-pass
#![feature(min_adt_const_params)]

use std::marker::ConstParamTy;

#[derive(ConstParamTy, Eq, PartialEq)]
#[allow(dead_code)]
struct Foo {
pub field: u32,
}

fn main() {}
Loading