Rollup merge of #111670 - compiler-errors:const-param-ty, r=BoxyUwU

Require that const param tys implement `ConstParamTy`

1. Require that const param tys implement `ConstParamTy` instead of using `search_for_adt_const_param_violation`
2. Add `StructuralPartialEq` as a supertrait for `ConstParamTy`, since we need to make sure that we derive *both* `PartialEq` and `Eq`
3. Implement `ConstParamTy` for tuples up to 12 (or whatever the default for tuples is)
4. Add some custom diagnostics to `ConstParamTy` errors, to avoid regressions from (1.). It's still not as great as it could be -- will point out inline in comments.

r? `@BoxyUwU`
This commit is contained in:
Michael Goulet 2023-06-01 23:07:36 -07:00 committed by GitHub
commit 24404e6409
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 569 additions and 316 deletions

View File

@ -10,15 +10,19 @@ struct A;
struct B<const X: A>; // error!
```
Only structural-match types (that is, types that derive `PartialEq` and `Eq`)
may be used as the types of const generic parameters.
Only structural-match types, which are types that derive `PartialEq` and `Eq`
and implement `ConstParamTy`, may be used as the types of const generic
parameters.
To fix the previous code example, we derive `PartialEq` and `Eq`:
To fix the previous code example, we derive `PartialEq`, `Eq`, and
`ConstParamTy`:
```
#![feature(adt_const_params)]
#[derive(PartialEq, Eq)] // We derive both traits here.
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)] // We derive both traits here.
struct A;
struct B<const X: A>; // ok!

View File

@ -115,36 +115,22 @@ fn make_diagnostic_builder(
) -> DiagnosticBuilder<'_, Self>;
}
/// Private module for sealing the `IsError` helper trait.
mod sealed_level_is_error {
use crate::Level;
/// Sealed helper trait for statically checking that a `Level` is an error.
pub(crate) trait IsError<const L: Level> {}
impl IsError<{ Level::Bug }> for () {}
impl IsError<{ Level::DelayedBug }> for () {}
impl IsError<{ Level::Fatal }> for () {}
// NOTE(eddyb) `Level::Error { lint: true }` is also an error, but lints
// don't need error guarantees, as their levels are always dynamic.
impl IsError<{ Level::Error { lint: false } }> for () {}
}
impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
/// Convenience function for internal use, clients should use one of the
/// `struct_*` methods on [`Handler`].
#[track_caller]
pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>>(
handler: &'a Handler,
message: M,
) -> Self
where
(): sealed_level_is_error::IsError<L>,
{
) -> Self {
Self {
inner: DiagnosticBuilderInner {
state: DiagnosticBuilderState::Emittable(handler),
diagnostic: Box::new(Diagnostic::new_with_code(L, None, message)),
diagnostic: Box::new(Diagnostic::new_with_code(
Level::Error { lint: false },
None,
message,
)),
},
_marker: PhantomData,
}
@ -203,9 +189,7 @@ fn make_diagnostic_builder(
handler: &Handler,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, Self> {
DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
handler, msg,
)
DiagnosticBuilder::new_guaranteeing_error(handler, msg)
}
}

View File

@ -6,7 +6,6 @@
#![feature(array_windows)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
#![feature(adt_const_params)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(result_option_inspect)]
@ -845,7 +844,7 @@ pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(self, msg)
DiagnosticBuilder::new_guaranteeing_error(self, msg)
}
/// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors.

View File

@ -829,83 +829,20 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
let ty = tcx.type_of(param.def_id).subst_identity();
if tcx.features().adt_const_params {
if let Some(non_structural_match_ty) =
traits::search_for_adt_const_param_violation(param.span, tcx, ty)
{
// We use the same error code in both branches, because this is really the same
// issue: we just special-case the message for type parameters to make it
// clearer.
match non_structural_match_ty.kind() {
ty::Param(_) => {
// Const parameters may not have type parameters as their types,
// because we cannot be sure that the type parameter derives `PartialEq`
// and `Eq` (just implementing them is not enough for `structural_match`).
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
used as the type of a const parameter",
)
.span_label(
hir_ty.span,
format!("`{ty}` may not derive both `PartialEq` and `Eq`"),
)
.note(
"it is not currently possible to use a type parameter as the type of a \
const parameter",
)
.emit();
}
ty::Float(_) => {
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"`{ty}` is forbidden as the type of a const generic parameter",
)
.note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
.emit();
}
ty::FnPtr(_) => {
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"using function pointers as const generic parameters is forbidden",
)
.emit();
}
ty::RawPtr(_) => {
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"using raw pointers as const generic parameters is forbidden",
)
.emit();
}
_ => {
let mut diag = struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
the type of a const parameter",
non_structural_match_ty,
);
if ty == non_structural_match_ty {
diag.span_label(
hir_ty.span,
format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
);
}
diag.emit();
}
}
}
enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
let trait_def_id =
tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span));
wfcx.register_bound(
ObligationCause::new(
hir_ty.span,
param.def_id,
ObligationCauseCode::ConstParam(ty),
),
wfcx.param_env,
ty,
trait_def_id,
);
});
} else {
let err_ty_str;
let mut is_ptr = true;

View File

@ -445,6 +445,9 @@ pub enum ObligationCauseCode<'tcx> {
/// Obligations to prove that a `std::ops::Drop` impl is not stronger than
/// the ADT it's being implemented for.
DropImpl,
/// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
ConstParam(Ty<'tcx>),
}
/// The 'location' at which we try to perform HIR-based wf checking.

View File

@ -149,6 +149,12 @@ fn report_selection_error(
root_obligation: &PredicateObligation<'tcx>,
error: &SelectionError<'tcx>,
);
fn report_const_param_not_wf(
&self,
ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
}
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
@ -641,6 +647,7 @@ fn report_selection_error(
span = obligation.cause.span;
}
}
if let ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id,
trait_item_def_id,
@ -657,6 +664,13 @@ fn report_selection_error(
return;
}
// Report a const-param specific error
if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives()
{
self.report_const_param_not_wf(ty, &obligation).emit();
return;
}
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
@ -1163,6 +1177,102 @@ fn report_selection_error(
self.point_at_returns_when_relevant(&mut err, &obligation);
err.emit();
}
fn report_const_param_not_wf(
&self,
ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let span = obligation.cause.span;
let mut diag = match ty.kind() {
_ if ty.has_param() => {
span_bug!(span, "const param tys cannot mention other generic parameters");
}
ty::Float(_) => {
struct_span_err!(
self.tcx.sess,
span,
E0741,
"`{ty}` is forbidden as the type of a const generic parameter",
)
}
ty::FnPtr(_) => {
struct_span_err!(
self.tcx.sess,
span,
E0741,
"using function pointers as const generic parameters is forbidden",
)
}
ty::RawPtr(_) => {
struct_span_err!(
self.tcx.sess,
span,
E0741,
"using raw pointers as const generic parameters is forbidden",
)
}
ty::Adt(def, _) => {
// We should probably see if we're *allowed* to derive `ConstParamTy` on the type...
let mut diag = struct_span_err!(
self.tcx.sess,
span,
E0741,
"`{ty}` must implement `ConstParamTy` to be used as the type of a const generic parameter",
);
// Only suggest derive if this isn't a derived obligation,
// and the struct is local.
if let Some(span) = self.tcx.hir().span_if_local(def.did())
&& obligation.cause.code().parent().is_none()
{
if ty.is_structural_eq_shallow(self.tcx) {
diag.span_suggestion(
span,
"add `#[derive(ConstParamTy)]` to the struct",
"#[derive(ConstParamTy)]\n",
Applicability::MachineApplicable,
);
} else {
// FIXME(adt_const_params): We should check there's not already an
// overlapping `Eq`/`PartialEq` impl.
diag.span_suggestion(
span,
"add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct",
"#[derive(ConstParamTy, PartialEq, Eq)]\n",
Applicability::MachineApplicable,
);
}
}
diag
}
_ => {
struct_span_err!(
self.tcx.sess,
span,
E0741,
"`{ty}` can't be used as a const parameter type",
)
}
};
let mut code = obligation.cause.code();
let mut pred = obligation.predicate.to_opt_poly_trait_pred();
while let Some((next_code, next_pred)) = code.parent() {
if let Some(pred) = pred {
let pred = self.instantiate_binder_with_placeholders(pred);
diag.note(format!(
"`{}` must implement `{}`, but it does not",
pred.self_ty(),
pred.print_modifiers_and_trait_path()
));
}
code = next_code;
pred = next_pred;
}
diag
}
}
trait InferCtxtPrivExt<'tcx> {

View File

@ -2655,7 +2655,8 @@ fn note_obligation_cause_code<T>(
| ObligationCauseCode::BinOp { .. }
| ObligationCauseCode::AscribeUserTypeProvePredicate(..)
| ObligationCauseCode::RustCall
| ObligationCauseCode::DropImpl => {}
| ObligationCauseCode::DropImpl
| ObligationCauseCode::ConstParam(_) => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
}

View File

@ -100,7 +100,8 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
| ty::Str
| ty::Array(..)
| ty::Slice(_)
| ty::Ref(.., hir::Mutability::Not) => return Ok(()),
| ty::Ref(.., hir::Mutability::Not)
| ty::Tuple(_) => return Ok(()),
&ty::Adt(adt, substs) => (adt, substs),

View File

@ -62,9 +62,7 @@
pub use self::specialize::{
specialization_graph, translate_substs, translate_substs_with_cause, OverlapError,
};
pub use self::structural_match::{
search_for_adt_const_param_violation, search_for_structural_match_violation,
};
pub use self::structural_match::search_for_structural_match_violation;
pub use self::structural_normalize::StructurallyNormalizeExt;
pub use self::util::elaborate;
pub use self::util::{expand_trait_aliases, TraitAliasExpander};

View File

@ -34,24 +34,7 @@ pub fn search_for_structural_match_violation<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<Ty<'tcx>> {
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: false })
.break_value()
}
/// This method traverses the structure of `ty`, trying to find any
/// types that are not allowed to be used in a const generic.
///
/// This is either because the type does not implement `StructuralEq`
/// and `StructuralPartialEq`, or because the type is intentionally
/// not supported in const generics (such as floats and raw pointers,
/// which are allowed in match blocks).
pub fn search_for_adt_const_param_violation<'tcx>(
span: Span,
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<Ty<'tcx>> {
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: true })
.break_value()
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
}
/// This implements the traversal over the structure of a given type to try to
@ -65,11 +48,6 @@ struct Search<'tcx> {
/// Tracks ADTs previously encountered during search, so that
/// we will not recur on them again.
seen: FxHashSet<hir::def_id::DefId>,
// Additionally deny things that have been allowed in patterns,
// but are not allowed in adt const params, such as floats and
// fn ptrs.
adt_const_param: bool,
}
impl<'tcx> Search<'tcx> {
@ -124,41 +102,29 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
}
ty::FnPtr(..) => {
if !self.adt_const_param {
return ControlFlow::Continue(());
} else {
return ControlFlow::Break(ty);
}
return ControlFlow::Continue(());
}
ty::RawPtr(..) => {
if !self.adt_const_param {
// structural-match ignores substructure of
// `*const _`/`*mut _`, so skip `super_visit_with`.
//
// For example, if you have:
// ```
// struct NonStructural;
// #[derive(PartialEq, Eq)]
// struct T(*const NonStructural);
// const C: T = T(std::ptr::null());
// ```
//
// Even though `NonStructural` does not implement `PartialEq`,
// structural equality on `T` does not recur into the raw
// pointer. Therefore, one can still use `C` in a pattern.
return ControlFlow::Continue(());
} else {
return ControlFlow::Break(ty);
}
// structural-match ignores substructure of
// `*const _`/`*mut _`, so skip `super_visit_with`.
//
// For example, if you have:
// ```
// struct NonStructural;
// #[derive(PartialEq, Eq)]
// struct T(*const NonStructural);
// const C: T = T(std::ptr::null());
// ```
//
// Even though `NonStructural` does not implement `PartialEq`,
// structural equality on `T` does not recur into the raw
// pointer. Therefore, one can still use `C` in a pattern.
return ControlFlow::Continue(());
}
ty::Float(_) => {
if !self.adt_const_param {
return ControlFlow::Continue(());
} else {
return ControlFlow::Break(ty);
}
return ControlFlow::Continue(());
}
ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {

View File

@ -205,6 +205,20 @@ pub trait StructuralPartialEq {
// Empty.
}
marker_impls! {
#[unstable(feature = "structural_match", issue = "31434")]
StructuralPartialEq for
usize, u8, u16, u32, u64, u128,
isize, i8, i16, i32, i64, i128,
bool,
char,
str /* Technically requires `[u8]: StructuralEq` */,
(),
{T, const N: usize} [T; N],
{T} [T],
{T: ?Sized} &T,
}
/// Required trait for constants used in pattern matches.
///
/// Any type that derives `Eq` automatically implements this trait, *regardless*
@ -267,6 +281,7 @@ pub trait StructuralEq {
bool,
char,
str /* Technically requires `[u8]: StructuralEq` */,
(),
{T, const N: usize} [T; N],
{T} [T],
{T: ?Sized} &T,
@ -974,7 +989,8 @@ pub trait PointerLike {}
#[lang = "const_param_ty"]
#[unstable(feature = "adt_const_params", issue = "95174")]
#[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
pub trait ConstParamTy: StructuralEq {}
#[allow(multiple_supertrait_upcastable)]
pub trait ConstParamTy: StructuralEq + StructuralPartialEq {}
/// Derive macro generating an impl of the trait `ConstParamTy`.
#[rustc_builtin_macro]
@ -983,8 +999,7 @@ pub trait ConstParamTy: StructuralEq {}
/* compiler built-in */
}
// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure`
// FIXME(generic_const_parameter_types): handle `ty::Tuple`
// FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure`
marker_impls! {
#[unstable(feature = "adt_const_params", issue = "95174")]
ConstParamTy for
@ -998,6 +1013,11 @@ pub trait ConstParamTy: StructuralEq {}
{T: ?Sized + ConstParamTy} &T,
}
// FIXME(adt_const_params): Add to marker_impls call above once not in bootstrap
#[unstable(feature = "adt_const_params", issue = "95174")]
#[cfg(not(bootstrap))]
impl ConstParamTy for () {}
/// A common trait implemented by all function pointers.
#[unstable(
feature = "fn_ptr_trait",

View File

@ -1,3 +1,5 @@
use crate::marker::ConstParamTy;
/// Are values of a type transmutable into values of another type?
///
/// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of
@ -33,6 +35,9 @@ pub struct Assume {
pub validity: bool,
}
#[unstable(feature = "transmutability", issue = "99571")]
impl ConstParamTy for Assume {}
impl Assume {
/// Do not assume that *you* have ensured any safety properties are met.
#[unstable(feature = "transmutability", issue = "99571")]

View File

@ -1,6 +1,9 @@
// See src/libstd/primitive_docs.rs for documentation.
use crate::cmp::Ordering::{self, *};
#[cfg(not(bootstrap))]
use crate::marker::ConstParamTy;
use crate::marker::{StructuralEq, StructuralPartialEq};
// Recursive macro for implementing n-ary tuple functions and operations
//
@ -45,6 +48,28 @@ impl<$($T: Eq),+> Eq for ($($T,)+)
{}
}
maybe_tuple_doc! {
$($T)+ @
#[unstable(feature = "structural_match", issue = "31434")]
#[cfg(not(bootstrap))]
impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+)
{}
}
maybe_tuple_doc! {
$($T)+ @
#[unstable(feature = "structural_match", issue = "31434")]
impl<$($T),+> StructuralPartialEq for ($($T,)+)
{}
}
maybe_tuple_doc! {
$($T)+ @
#[unstable(feature = "structural_match", issue = "31434")]
impl<$($T),+> StructuralEq for ($($T,)+)
{}
}
maybe_tuple_doc! {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -10,6 +10,8 @@
clippy::uninlined_format_args
)]
use std::marker::ConstParamTy;
fn function() -> bool {
true
}
@ -96,7 +98,7 @@ fn main() {
};
println!("{}", os);
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, ConstParamTy)]
enum E {
A,
B,

View File

@ -1,11 +1,11 @@
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:37:15
--> $DIR/same_functions_in_if_condition.rs:39:15
|
LL | } else if function() {
| ^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:36:8
--> $DIR/same_functions_in_if_condition.rs:38:8
|
LL | if function() {
| ^^^^^^^^^^
@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:42:15
--> $DIR/same_functions_in_if_condition.rs:44:15
|
LL | } else if fn_arg(a) {
| ^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:41:8
--> $DIR/same_functions_in_if_condition.rs:43:8
|
LL | if fn_arg(a) {
| ^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:47:15
--> $DIR/same_functions_in_if_condition.rs:49:15
|
LL | } else if obj.method() {
| ^^^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:46:8
--> $DIR/same_functions_in_if_condition.rs:48:8
|
LL | if obj.method() {
| ^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:52:15
--> $DIR/same_functions_in_if_condition.rs:54:15
|
LL | } else if obj.method_arg(a) {
| ^^^^^^^^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:51:8
--> $DIR/same_functions_in_if_condition.rs:53:8
|
LL | if obj.method_arg(a) {
| ^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:59:15
--> $DIR/same_functions_in_if_condition.rs:61:15
|
LL | } else if v.pop().is_none() {
| ^^^^^^^^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:57:8
--> $DIR/same_functions_in_if_condition.rs:59:8
|
LL | if v.pop().is_none() {
| ^^^^^^^^^^^^^^^^^
error: this `if` has the same function call as a previous `if`
--> $DIR/same_functions_in_if_condition.rs:64:15
--> $DIR/same_functions_in_if_condition.rs:66:15
|
LL | } else if v.len() == 42 {
| ^^^^^^^^^^^^^
|
note: same as this
--> $DIR/same_functions_in_if_condition.rs:62:8
--> $DIR/same_functions_in_if_condition.rs:64:8
|
LL | if v.len() == 42 {
| ^^^^^^^^^^^^^

View File

@ -1,8 +1,20 @@
// revisions: cfail
#![feature(generic_const_exprs, adt_const_params)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
struct NonZeroUsize(usize);
impl NonZeroUsize {
const fn get(self) -> usize {
self.0
}
}
// regression test for #77650
fn c<T, const N: std::num::NonZeroUsize>()
fn c<T, const N: NonZeroUsize>()
where
[T; N.get()]: Sized,
{

View File

@ -1,11 +1,23 @@
// revisions: cfail
#![feature(generic_const_exprs, adt_const_params)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
struct NonZeroUsize(usize);
impl NonZeroUsize {
const fn get(self) -> usize {
self.0
}
}
// regression test for #77650
struct C<T, const N: core::num::NonZeroUsize>([T; N.get()])
struct C<T, const N: NonZeroUsize>([T; N.get()])
where
[T; N.get()]: Sized;
impl<'a, const N: core::num::NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N>
impl<'a, const N: NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N>
where
[B; N.get()]: Sized,
{

View File

@ -2,7 +2,18 @@
#![feature(generic_const_exprs, adt_const_params)]
#![allow(incomplete_features)]
use std::{convert::TryFrom, num::NonZeroUsize};
use std::{convert::TryFrom};
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
struct NonZeroUsize(usize);
impl NonZeroUsize {
const fn get(self) -> usize {
self.0
}
}
struct A<const N: NonZeroUsize>([u8; N.get()])
where

View File

@ -11,6 +11,10 @@ note: required by a bound in `check`
|
LL | fn check(_: impl std::marker::ConstParamTy) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
help: use parentheses to call this function
|
LL | check(main());
| ++
error[E0277]: `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` can't be used as a const parameter type
--> $DIR/const_param_ty_bad.rs:8:11
@ -25,6 +29,10 @@ note: required by a bound in `check`
|
LL | fn check(_: impl std::marker::ConstParamTy) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
help: use parentheses to call this closure
|
LL | check(|| {}());
| ++
error[E0277]: `fn()` can't be used as a const parameter type
--> $DIR/const_param_ty_bad.rs:9:11
@ -39,6 +47,10 @@ note: required by a bound in `check`
|
LL | fn check(_: impl std::marker::ConstParamTy) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
help: use parentheses to call this function pointer
|
LL | check(main as fn()());
| ++
error[E0277]: `&mut ()` can't be used as a const parameter type
--> $DIR/const_param_ty_bad.rs:10:11
@ -48,11 +60,17 @@ LL | check(&mut ());
| |
| required by a bound introduced by this call
|
= note: `ConstParamTy` is implemented for `&()`, but not for `&mut ()`
note: required by a bound in `check`
--> $DIR/const_param_ty_bad.rs:4:18
|
LL | fn check(_: impl std::marker::ConstParamTy) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
help: consider removing the leading `&`-reference
|
LL - check(&mut ());
LL + check(());
|
error[E0277]: `*mut ()` can't be used as a const parameter type
--> $DIR/const_param_ty_bad.rs:11:11
@ -62,6 +80,7 @@ LL | check(&mut () as *mut ());
| |
| required by a bound introduced by this call
|
= help: the trait `ConstParamTy` is implemented for `()`
note: required by a bound in `check`
--> $DIR/const_param_ty_bad.rs:4:18
|
@ -76,6 +95,7 @@ LL | check(&() as *const ());
| |
| required by a bound introduced by this call
|
= help: the trait `ConstParamTy` is implemented for `()`
note: required by a bound in `check`
--> $DIR/const_param_ty_bad.rs:4:18
|

View File

@ -49,5 +49,7 @@ fn main() {
check::<D<u8>>();
check::<D<[&[bool]; 8]>>();
// FIXME: test tuples
check::<()>();
check::<(i32,)>();
check::<(D<u8>, D<i32>)>();
}

View File

@ -9,9 +9,11 @@ impl std::marker::ConstParamTy for ImplementsConstParamTy {}
impl std::marker::ConstParamTy for CantParam {}
//~^ error: the type `CantParam` does not `#[derive(Eq)]`
//~| error: the type `CantParam` does not `#[derive(PartialEq)]`
#[derive(std::marker::ConstParamTy)]
//~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
//~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]`
struct CantParamDerive(ImplementsConstParamTy);
fn check<T: std::marker::ConstParamTy>() {}

View File

@ -1,3 +1,12 @@
error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
|
LL | impl std::marker::ConstParamTy for CantParam {}
| ^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParam`
|
note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error[E0277]: the type `CantParam` does not `#[derive(Eq)]`
--> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
|
@ -7,8 +16,18 @@ LL | impl std::marker::ConstParamTy for CantParam {}
note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
--> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
|
LL | #[derive(std::marker::ConstParamTy)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
|
note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
= note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
--> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10
--> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
|
LL | #[derive(std::marker::ConstParamTy)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
@ -17,6 +36,6 @@ note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
= note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -14,6 +14,7 @@ impl Eq for Union {}
impl std::marker::StructuralEq for Union {}
impl std::marker::ConstParamTy for Union {}
//~^ ERROR the type `Union` does not `#[derive(PartialEq)]`
#[derive(std::marker::ConstParamTy)]
//~^ ERROR this trait cannot be derived for unions

View File

@ -1,8 +1,18 @@
error: this trait cannot be derived for unions
--> $DIR/const_param_ty_impl_union.rs:18:10
--> $DIR/const_param_ty_impl_union.rs:19:10
|
LL | #[derive(std::marker::ConstParamTy)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0277]: the type `Union` does not `#[derive(PartialEq)]`
--> $DIR/const_param_ty_impl_union.rs:16:36
|
LL | impl std::marker::ConstParamTy for Union {}
| ^^^^^ the trait `StructuralPartialEq` is not implemented for `Union`
|
note: required by a bound in `ConstParamTy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,17 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy;
#[derive(Eq, PartialEq)]
struct Foo<T>(T);
trait Other {}
impl<T> ConstParamTy for Foo<T> where T: Other + ConstParamTy {}
fn foo<const N: Foo<u8>>() {}
//~^ ERROR `Foo<u8>` must implement `ConstParamTy` to be used as the type of a const generic parameter
//~| NOTE `u8` must implement `Other`, but it does not
fn main() {}

View File

@ -0,0 +1,11 @@
error[E0741]: `Foo<u8>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-param-with-additional-obligations.rs:13:17
|
LL | fn foo<const N: Foo<u8>>() {}
| ^^^^^^^
|
= note: `u8` must implement `Other`, but it does not
error: aborting due to previous error
For more information about this error, try `rustc --explain E0741`.

View File

@ -3,8 +3,6 @@ error[E0741]: `f32` is forbidden as the type of a const generic parameter
|
LL | fn foo<const F: f32>() {}
| ^^^
|
= note: floats do not derive `Eq` or `Ord`, which are required for const parameters
error: aborting due to previous error

View File

@ -1,13 +1,15 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#[derive(PartialEq, Eq)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
struct A;
struct B<const X: A>; // ok
struct C;
struct D<const X: C>; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]`
struct D<const X: C>; //~ ERROR `C` must implement `ConstParamTy` to be used as the type of a const generic parameter
fn main() {}

View File

@ -1,8 +1,14 @@
error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
--> $DIR/forbid-non-structural_match-types.rs:11:19
error[E0741]: `C` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/forbid-non-structural_match-types.rs:13:19
|
LL | struct D<const X: C>;
| ^ `C` doesn't derive both `PartialEq` and `Eq`
| ^
|
help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct
|
LL + #[derive(ConstParamTy, PartialEq, Eq)]
LL | struct C;
|
error: aborting due to previous error

View File

@ -7,7 +7,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
= help: try adding a `where` bound using this expression: `where [(); 0 + N]:`
error: overly complex generic constant
--> $DIR/array-size-in-generic-struct-param.rs:19:15
--> $DIR/array-size-in-generic-struct-param.rs:23:15
|
LL | arr: [u8; CFG.arr_size],
| ^^^^^^^^^^^^ field access is not supported in generic constants

View File

@ -8,7 +8,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations
--> $DIR/array-size-in-generic-struct-param.rs:19:15
--> $DIR/array-size-in-generic-struct-param.rs:23:15
|
LL | arr: [u8; CFG.arr_size],
| ^^^ cannot perform const operation using `CFG`
@ -17,7 +17,7 @@ LL | arr: [u8; CFG.arr_size],
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
error: `Config` is forbidden as the type of a const generic parameter
--> $DIR/array-size-in-generic-struct-param.rs:17:21
--> $DIR/array-size-in-generic-struct-param.rs:21:21
|
LL | struct B<const CFG: Config> {
| ^^^^^^

View File

@ -9,7 +9,11 @@
//[full]~^ ERROR unconstrained generic constant
//[min]~^^ ERROR generic parameters may not be used in const operations
#[cfg(full)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq)]
#[cfg_attr(full, derive(ConstParamTy))]
struct Config {
arr_size: usize,
}

View File

@ -1,7 +1,9 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#[derive(PartialEq, Eq)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
enum CompileFlag {
A,
B,

View File

@ -1,5 +1,5 @@
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:21:12
--> $DIR/invalid-enum.rs:23:12
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | test_1::<CompileFlag::A>();
| help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:25:15
--> $DIR/invalid-enum.rs:27:15
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | test_2::<_, CompileFlag::A>(0);
| help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:29:18
--> $DIR/invalid-enum.rs:31:18
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| help: try using the variant's enum: `CompileFlag`
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:29:18
--> $DIR/invalid-enum.rs:31:18
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
@ -37,7 +37,7 @@ LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
| + +
error[E0747]: type provided when a constant was expected
--> $DIR/invalid-enum.rs:33:18
--> $DIR/invalid-enum.rs:35:18
|
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^
@ -48,7 +48,7 @@ LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
| + +
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:21:12
--> $DIR/invalid-enum.rs:23:12
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
@ -59,7 +59,7 @@ LL | test_1::<{ CompileFlag::A }>();
| + +
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:25:15
--> $DIR/invalid-enum.rs:27:15
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^

View File

@ -1,13 +1,15 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#[derive(Debug, PartialEq, Eq)]
use std::marker::ConstParamTy;
#[derive(Debug, PartialEq, Eq, ConstParamTy)]
struct Foo {
value: i32,
nested: &'static Bar<i32>,
}
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, ConstParamTy)]
struct Bar<T>(T);
struct Test<const F: Foo>;

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/issue-66451.rs:27:10
--> $DIR/issue-66451.rs:29:10
|
LL | let y: Test<{
| ____________-

View File

@ -8,6 +8,6 @@ enum Nat {
}
fn foo<const N: Nat>() {}
//~^ ERROR `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
//~^ ERROR `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter
fn main() {}

View File

@ -7,11 +7,17 @@ LL | #![feature(adt_const_params)]
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0741]: `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
error[E0741]: `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/issue-80471.rs:10:17
|
LL | fn foo<const N: Nat>() {}
| ^^^
|
help: add `#[derive(ConstParamTy)]` to the struct
|
LL + #[derive(ConstParamTy)]
LL | enum Nat {
|
error: aborting due to previous error; 1 warning emitted

View File

@ -1,8 +1,10 @@
error[E0741]: `(dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
error[E0741]: `&'static (dyn A + 'static)` can't be used as a const parameter type
--> $DIR/issue-63322-forbid-dyn.rs:9:18
|
LL | fn test<const T: &'static dyn A>() {
| ^^^^^^^^^^^^^^
|
= note: `(dyn A + 'static)` must implement `ConstParamTy`, but it does not
error: aborting due to previous error

View File

@ -7,7 +7,7 @@ trait A {}
impl A for B {}
fn test<const T: &'static dyn A>() {
//[full]~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
//[full]~^ ERROR `&'static (dyn A + 'static)` can't be used as a const parameter type
//[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden
unimplemented!()
}

View File

@ -14,19 +14,6 @@ LL | const FN: unsafe extern "C" fn(Args),
|
= note: type parameters may not be used in the type of const parameters
error[E0741]: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:14:61
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0741]: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:23:19
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0741, E0770.
For more information about an error, try `rustc --explain E0741`.
For more information about this error, try `rustc --explain E0770`.

View File

@ -12,8 +12,8 @@
impl Test {
pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
//~^ ERROR: using function pointers as const generic parameters is forbidden
//~| ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^ ERROR: using function pointers as const generic parameters is forbidden
//~^^ ERROR: the type of const parameters must not depend on other generic parameters
self.0 = Self::trampiline::<Args, IDX, FN> as _
}
@ -21,8 +21,8 @@ pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Arg
Args: Sized,
const IDX: usize,
const FN: unsafe extern "C" fn(Args),
//~^ ERROR: using function pointers as const generic parameters is forbidden
//~| ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^ ERROR: using function pointers as const generic parameters is forbidden
//~^^ ERROR: the type of const parameters must not depend on other generic parameters
>(
args: Args,
) {
@ -31,6 +31,6 @@ pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Arg
}
fn main() {
let x = Test();
let x = Test(std::ptr::null());
x.call_me::<PassArg, 30, pass>()
}

View File

@ -6,13 +6,6 @@ LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
= note: type parameters may not be used in the type of const parameters
error[E0741]: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71611.rs:5:21
|
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^^^^^^^^^^^^
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0741, E0770.
For more information about an error, try `rustc --explain E0741`.
For more information about this error, try `rustc --explain E0770`.

View File

@ -3,8 +3,8 @@
#![cfg_attr(full, allow(incomplete_features))]
fn func<A, const F: fn(inner: A)>(outer: A) {
//~^ ERROR: using function pointers as const generic parameters is forbidden
//~| ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^ ERROR: using function pointers as const generic parameters is forbidden
//~^^ ERROR: the type of const parameters must not depend on other generic parameters
F(outer);
}

View File

@ -1,5 +1,5 @@
error: `IceEnum` is forbidden as the type of a const generic parameter
--> $DIR/issue-74255.rs:14:31
--> $DIR/issue-74255.rs:18:31
|
LL | fn ice_struct_fn<const I: IceEnum>() {}
| ^^^^^^^

View File

@ -3,7 +3,11 @@
#![cfg_attr(full, feature(adt_const_params))]
#![cfg_attr(full, allow(incomplete_features))]
#[cfg(full)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq)]
#[cfg_attr(full, derive(ConstParamTy))]
enum IceEnum {
Variant
}

View File

@ -1,5 +1,5 @@
error: `Inner` is forbidden as the type of a const generic parameter
--> $DIR/issue-74950.rs:17:23
--> $DIR/issue-74950.rs:20:23
|
LL | struct Outer<const I: Inner>;
| ^^^^^
@ -8,7 +8,7 @@ LL | struct Outer<const I: Inner>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `Inner` is forbidden as the type of a const generic parameter
--> $DIR/issue-74950.rs:17:23
--> $DIR/issue-74950.rs:20:23
|
LL | struct Outer<const I: Inner>;
| ^^^^^
@ -17,7 +17,7 @@ LL | struct Outer<const I: Inner>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `Inner` is forbidden as the type of a const generic parameter
--> $DIR/issue-74950.rs:17:23
--> $DIR/issue-74950.rs:20:23
|
LL | struct Outer<const I: Inner>;
| ^^^^^
@ -26,7 +26,7 @@ LL | struct Outer<const I: Inner>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `Inner` is forbidden as the type of a const generic parameter
--> $DIR/issue-74950.rs:17:23
--> $DIR/issue-74950.rs:20:23
|
LL | struct Outer<const I: Inner>;
| ^^^^^
@ -35,7 +35,7 @@ LL | struct Outer<const I: Inner>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `Inner` is forbidden as the type of a const generic parameter
--> $DIR/issue-74950.rs:17:23
--> $DIR/issue-74950.rs:20:23
|
LL | struct Outer<const I: Inner>;
| ^^^^^

View File

@ -3,8 +3,11 @@
#![cfg_attr(full, feature(adt_const_params))]
#![cfg_attr(full, allow(incomplete_features))]
#[cfg(full)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq)]
#[cfg_attr(full, derive(ConstParamTy))]
struct Inner;
// Note: We emit the error 5 times if we don't deduplicate:

View File

@ -3,7 +3,9 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#[derive(PartialEq, Eq)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
pub struct UnitDims {
pub time: u8,
pub length: u8,

View File

@ -9,6 +9,6 @@ enum Bar {
}
fn test<const BAR: Bar>() {}
//~^ ERROR `Arc<i32>` must be annotated with `#[derive(PartialEq, Eq)]`
//~^ ERROR `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter
fn main() {}

View File

@ -1,8 +1,14 @@
error[E0741]: `Arc<i32>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
error[E0741]: `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/issue-97278.rs:11:20
|
LL | fn test<const BAR: Bar>() {}
| ^^^
|
help: add `#[derive(ConstParamTy)]` to the struct
|
LL + #[derive(ConstParamTy)]
LL | enum Bar {
|
error: aborting due to previous error

View File

@ -3,10 +3,10 @@
fn main() {
pub struct Color<const WHITE: (fn(),)>;
//~^ ERROR using function pointers
//~^ ERROR `(fn(),)` can't be used as a const parameter type
impl<const WHITE: (fn(),)> Color<WHITE> {
//~^ ERROR using function pointers
//~^ ERROR `(fn(),)` can't be used as a const parameter type
pub fn new() -> Self {
Color::<WHITE>
}

View File

@ -1,14 +1,18 @@
error[E0741]: using function pointers as const generic parameters is forbidden
error[E0741]: `(fn(),)` can't be used as a const parameter type
--> $DIR/issue-99641.rs:5:35
|
LL | pub struct Color<const WHITE: (fn(),)>;
| ^^^^^^^
|
= note: `fn()` must implement `ConstParamTy`, but it does not
error[E0741]: using function pointers as const generic parameters is forbidden
error[E0741]: `(fn(),)` can't be used as a const parameter type
--> $DIR/issue-99641.rs:8:23
|
LL | impl<const WHITE: (fn(),)> Color<WHITE> {
| ^^^^^^^
|
= note: `fn()` must implement `ConstParamTy`, but it does not
error: aborting due to 2 previous errors

View File

@ -2,7 +2,8 @@
#![allow(incomplete_features)]
#![feature(adt_const_params)]
#![feature(generic_const_exprs)]
use std::marker::PhantomData;
use std::marker::{ConstParamTy, PhantomData};
struct Foo<const I: i32, const J: i32> {}
@ -22,7 +23,7 @@ pub struct Foo2<const P: Protocol, T> {
_marker: PhantomData<T>,
}
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, ConstParamTy)]
pub enum Protocol {
Variant1,
Variant2,

View File

@ -0,0 +1,39 @@
error[E0741]: `std::ops::Range<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:8:24
|
LL | struct _Range<const R: std::ops::Range<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0741]: `RangeFrom<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:13:28
|
LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0741]: `RangeFull` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:18:28
|
LL | struct _RangeFull<const R: std::ops::RangeFull>;
| ^^^^^^^^^^^^^^^^^^^
error[E0741]: `RangeInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:24:33
|
LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0741]: `RangeTo<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:29:26
|
LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0741]: `RangeToInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/const-generics-range.rs:34:35
|
LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0741`.

View File

@ -1,5 +1,5 @@
error: `std::ops::Range<usize>` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:7:24
--> $DIR/const-generics-range.rs:8:24
|
LL | struct _Range<const R: std::ops::Range<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | struct _Range<const R: std::ops::Range<usize>>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `RangeFrom<usize>` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:12:28
--> $DIR/const-generics-range.rs:13:28
|
LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `RangeFull` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:17:28
--> $DIR/const-generics-range.rs:18:28
|
LL | struct _RangeFull<const R: std::ops::RangeFull>;
| ^^^^^^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | struct _RangeFull<const R: std::ops::RangeFull>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `RangeInclusive<usize>` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:23:33
--> $DIR/const-generics-range.rs:24:33
|
LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -35,7 +35,7 @@ LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `RangeTo<usize>` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:28:26
--> $DIR/const-generics-range.rs:29:26
|
LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^
@ -44,7 +44,7 @@ LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
= help: more complex types are supported with `#![feature(adt_const_params)]`
error: `RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
--> $DIR/const-generics-range.rs:33:35
--> $DIR/const-generics-range.rs:34:35
|
LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,4 +1,5 @@
// [full] check-pass
// [full] known-bug: unknown
// revisions: full min
#![cfg_attr(full, feature(adt_const_params))]
#![cfg_attr(full, allow(incomplete_features))]

View File

@ -8,10 +8,10 @@ struct CompileTimeSettings{
}
struct Foo<const T: CompileTimeSettings>;
//~^ ERROR using function pointers as const generic parameters is forbidden
//~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
impl<const T: CompileTimeSettings> Foo<T> {
//~^ ERROR using function pointers as const generic parameters is forbidden
//~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
fn call_hooks(){
}
}

View File

@ -7,17 +7,29 @@ LL | #![feature(adt_const_params)]
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0741]: using function pointers as const generic parameters is forbidden
error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/refs_check_const_eq-issue-88384.rs:10:21
|
LL | struct Foo<const T: CompileTimeSettings>;
| ^^^^^^^^^^^^^^^^^^^
|
help: add `#[derive(ConstParamTy)]` to the struct
|
LL + #[derive(ConstParamTy)]
LL | struct CompileTimeSettings{
|
error[E0741]: using function pointers as const generic parameters is forbidden
error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/refs_check_const_eq-issue-88384.rs:13:15
|
LL | impl<const T: CompileTimeSettings> Foo<T> {
| ^^^^^^^^^^^^^^^^^^^
|
help: add `#[derive(ConstParamTy)]` to the struct
|
LL + #[derive(ConstParamTy)]
LL | struct CompileTimeSettings{
|
error: aborting due to 2 previous errors; 1 warning emitted

View File

@ -3,7 +3,9 @@
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#[derive(PartialEq, Eq)]
use std::marker::ConstParamTy;
#[derive(PartialEq, Eq, ConstParamTy)]
struct Yikes;
impl Yikes {

View File

@ -1,5 +1,5 @@
warning: taking a mutable reference to a `const` item
--> $DIR/thir-constparam-temp.rs:14:5
--> $DIR/thir-constparam-temp.rs:16:5
|
LL | YIKES.mut_self()
| ^^^^^^^^^^^^^^^^
@ -7,12 +7,12 @@ LL | YIKES.mut_self()
= note: each usage of a `const` item creates a new temporary
= note: the mutable reference will refer to this temporary, not the original `const` item
note: mutable reference created due to call to this method
--> $DIR/thir-constparam-temp.rs:10:5
--> $DIR/thir-constparam-temp.rs:12:5
|
LL | fn mut_self(&mut self) {}
| ^^^^^^^^^^^^^^^^^^^^^^
note: `const` item defined here
--> $DIR/thir-constparam-temp.rs:13:8
--> $DIR/thir-constparam-temp.rs:15:8
|
LL | fn foo<const YIKES: Yikes>() {
| ^^^^^^^^^^^^^^^^^^

View File

@ -1,14 +1,13 @@
// build-fail
// compile-flags: -C symbol-mangling-version=v0 --crate-name=c
// NOTE(eddyb) we need `core` for `core::option::Option`, normalize away its
// disambiguator hash, which can/should change (including between stage{1,2}).
// normalize-stderr-test: "core\[[0-9a-f]+\]" -> "core[HASH]"
// normalize-stderr-test: "c\[[0-9a-f]+\]" -> "c[HASH]"
#![feature(adt_const_params, decl_macro, rustc_attrs)]
#![allow(incomplete_features)]
use std::marker::ConstParamTy;
pub struct RefByte<const RB: &'static u8>;
#[rustc_symbol_name]
@ -43,25 +42,31 @@ impl Array3Bytes<{[1, 2, 3]}> {}
//~| ERROR demangling-alt(<c::TupleByteBool<{(1, false)}>>)
impl TupleByteBool<{(1, false)}> {}
pub struct OptionUsize<const OU: Option<usize>>;
#[derive(PartialEq, Eq, ConstParamTy)]
pub enum MyOption<T> {
Some(T),
None,
}
pub struct OptionUsize<const OU: MyOption<usize>>;
// HACK(eddyb) the full mangling is only in `.stderr` because we can normalize
// the `core` disambiguator hash away there, but not here.
#[rustc_symbol_name]
//~^ ERROR symbol-name
//~| ERROR demangling
//~| ERROR demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::None}>>)
impl OptionUsize<{None}> {}
//~| ERROR demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::None}>>)
impl OptionUsize<{MyOption::None}> {}
// HACK(eddyb) the full mangling is only in `.stderr` because we can normalize
// the `core` disambiguator hash away there, but not here.
#[rustc_symbol_name]
//~^ ERROR symbol-name
//~| ERROR demangling
//~| ERROR demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::Some(0)}>>)
impl OptionUsize<{Some(0)}> {}
//~| ERROR demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::Some(0)}>>)
impl OptionUsize<{MyOption::Some(0)}> {}
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, ConstParamTy)]
pub struct Foo {
s: &'static str,
ch: char,
@ -78,7 +83,7 @@ impl Foo_<{Foo { s: "abc", ch: 'x', slice: &[1, 2, 3] }}> {}
// NOTE(eddyb) this tests specifically the use of disambiguators in field names,
// using macros 2.0 hygiene to create a `struct` with conflicting field names.
macro duplicate_field_name_test($x:ident) {
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, ConstParamTy)]
pub struct Bar {
$x: u8,
x: u16,

View File

@ -1,131 +1,131 @@
error: symbol-name(_RMCsCRATE_HASH_1cINtB<REF>_7RefByteKRh7b_E)
--> $DIR/const-generics-structural-demangling.rs:14:1
--> $DIR/const-generics-structural-demangling.rs:13:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::RefByte<{&123u8}>>)
--> $DIR/const-generics-structural-demangling.rs:14:1
--> $DIR/const-generics-structural-demangling.rs:13:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::RefByte<{&123}>>)
--> $DIR/const-generics-structural-demangling.rs:14:1
--> $DIR/const-generics-structural-demangling.rs:13:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs_CsCRATE_HASH_1cINtB<REF>_6RefZstKRAEE)
--> $DIR/const-generics-structural-demangling.rs:24:1
--> $DIR/const-generics-structural-demangling.rs:23:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::RefZst<{&[]}>>)
--> $DIR/const-generics-structural-demangling.rs:24:1
--> $DIR/const-generics-structural-demangling.rs:23:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::RefZst<{&[]}>>)
--> $DIR/const-generics-structural-demangling.rs:24:1
--> $DIR/const-generics-structural-demangling.rs:23:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB<REF>_11Array3BytesKAh1_h2_h3_EE)
--> $DIR/const-generics-structural-demangling.rs:32:1
--> $DIR/const-generics-structural-demangling.rs:31:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::Array3Bytes<{[1u8, 2u8, 3u8]}>>)
--> $DIR/const-generics-structural-demangling.rs:32:1
--> $DIR/const-generics-structural-demangling.rs:31:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::Array3Bytes<{[1, 2, 3]}>>)
--> $DIR/const-generics-structural-demangling.rs:32:1
--> $DIR/const-generics-structural-demangling.rs:31:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB<REF>_13TupleByteBoolKTh1_b0_EE)
--> $DIR/const-generics-structural-demangling.rs:40:1
--> $DIR/const-generics-structural-demangling.rs:39:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::TupleByteBool<{(1u8, false)}>>)
--> $DIR/const-generics-structural-demangling.rs:40:1
--> $DIR/const-generics-structural-demangling.rs:39:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::TupleByteBool<{(1, false)}>>)
--> $DIR/const-generics-structural-demangling.rs:40:1
--> $DIR/const-generics-structural-demangling.rs:39:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4NoneUE)
--> $DIR/const-generics-structural-demangling.rs:50:1
error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtB<REF>_8MyOptionjE4NoneUE)
--> $DIR/const-generics-structural-demangling.rs:55:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::OptionUsize<{core[HASH]::option::Option::<usize>::None}>>)
--> $DIR/const-generics-structural-demangling.rs:50:1
error: demangling(<c[HASH]::OptionUsize<{c[HASH]::MyOption::<usize>::None}>>)
--> $DIR/const-generics-structural-demangling.rs:55:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::None}>>)
--> $DIR/const-generics-structural-demangling.rs:50:1
error: demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::None}>>)
--> $DIR/const-generics-structural-demangling.rs:55:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4SomeTj0_EE)
--> $DIR/const-generics-structural-demangling.rs:58:1
error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtB<REF>_8MyOptionjE4SomeTj0_EE)
--> $DIR/const-generics-structural-demangling.rs:63:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::OptionUsize<{core[HASH]::option::Option::<usize>::Some(0usize)}>>)
--> $DIR/const-generics-structural-demangling.rs:58:1
error: demangling(<c[HASH]::OptionUsize<{c[HASH]::MyOption::<usize>::Some(0usize)}>>)
--> $DIR/const-generics-structural-demangling.rs:63:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::Some(0)}>>)
--> $DIR/const-generics-structural-demangling.rs:58:1
error: demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::Some(0)}>>)
--> $DIR/const-generics-structural-demangling.rs:63:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs4_CsCRATE_HASH_1cINtB<REF>_4Foo_KVNtB<REF>_3FooS1sRe616263_2chc78_5sliceRAh1_h2_h3_EEE)
--> $DIR/const-generics-structural-demangling.rs:72:1
--> $DIR/const-generics-structural-demangling.rs:77:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling(<c[HASH]::Foo_<{c[HASH]::Foo { s: "abc", ch: 'x', slice: &[1u8, 2u8, 3u8] }}>>)
--> $DIR/const-generics-structural-demangling.rs:72:1
--> $DIR/const-generics-structural-demangling.rs:77:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<c::Foo_<{c::Foo { s: "abc", ch: 'x', slice: &[1, 2, 3] }}>>)
--> $DIR/const-generics-structural-demangling.rs:72:1
--> $DIR/const-generics-structural-demangling.rs:77:1
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
error: symbol-name(_RMs9_CsCRATE_HASH_1cINtB<REF>_4Bar_KVNtB<REF>_3BarS1xh7b_s_1xt1000_EE)
--> $DIR/const-generics-structural-demangling.rs:88:5
error: symbol-name(_RMsf_CsCRATE_HASH_1cINtB<REF>_4Bar_KVNtB<REF>_3BarS1xh7b_s_1xt1000_EE)
--> $DIR/const-generics-structural-demangling.rs:93:5
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
@ -136,7 +136,7 @@ LL | duplicate_field_name_test!(x);
= note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info)
error: demangling(<c[HASH]::Bar_<{c[HASH]::Bar { x: 123u8, x: 4096u16 }}>>)
--> $DIR/const-generics-structural-demangling.rs:88:5
--> $DIR/const-generics-structural-demangling.rs:93:5
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^
@ -147,7 +147,7 @@ LL | duplicate_field_name_test!(x);
= note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info)
error: demangling-alt(<c::Bar_<{c::Bar { x: 123, x: 4096 }}>>)
--> $DIR/const-generics-structural-demangling.rs:88:5
--> $DIR/const-generics-structural-demangling.rs:93:5
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^