mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
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:
commit
24404e6409
@ -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!
|
||||
|
@ -115,36 +115,22 @@ pub trait EmissionGuarantee: Sized {
|
||||
) -> 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 @@ impl EmissionGuarantee for ErrorGuaranteed {
|
||||
handler: &Handler,
|
||||
msg: impl Into<DiagnosticMessage>,
|
||||
) -> DiagnosticBuilder<'_, Self> {
|
||||
DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
|
||||
handler, msg,
|
||||
)
|
||||
DiagnosticBuilder::new_guaranteeing_error(handler, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ impl Handler {
|
||||
&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.
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -149,6 +149,12 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||
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 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
span = obligation.cause.span;
|
||||
}
|
||||
}
|
||||
|
||||
if let ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
@ -657,6 +664,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
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 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
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> {
|
||||
|
@ -2655,7 +2655,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
| ObligationCauseCode::BinOp { .. }
|
||||
| ObligationCauseCode::AscribeUserTypeProvePredicate(..)
|
||||
| ObligationCauseCode::RustCall
|
||||
| ObligationCauseCode::DropImpl => {}
|
||||
| ObligationCauseCode::DropImpl
|
||||
| ObligationCauseCode::ConstParam(_) => {}
|
||||
ObligationCauseCode::SliceOrArrayElem => {
|
||||
err.note("slice and array elements must have `Sized` type");
|
||||
}
|
||||
|
@ -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),
|
||||
|
||||
|
@ -62,9 +62,7 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
|
||||
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};
|
||||
|
@ -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 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
||||
}
|
||||
|
||||
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(..) => {
|
||||
|
@ -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 @@ marker_impls! {
|
||||
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 macro ConstParamTy($item:item) {
|
||||
/* 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 @@ marker_impls! {
|
||||
{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",
|
||||
|
@ -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")]
|
||||
|
@ -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 @@ macro_rules! tuple_impls {
|
||||
{}
|
||||
}
|
||||
|
||||
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")]
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -49,5 +49,7 @@ fn main() {
|
||||
check::<D<u8>>();
|
||||
check::<D<[&[bool]; 8]>>();
|
||||
|
||||
// FIXME: test tuples
|
||||
check::<()>();
|
||||
check::<(i32,)>();
|
||||
check::<(D<u8>, D<i32>)>();
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ struct CantParam(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>() {}
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
| ^^^^^^
|
||||
|
@ -9,7 +9,11 @@ struct ArithArrayLen<const N: usize>([u32; 0 + N]);
|
||||
//[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,
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -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>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-66451.rs:27:10
|
||||
--> $DIR/issue-66451.rs:29:10
|
||||
|
|
||||
LL | let y: Test<{
|
||||
| ____________-
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -7,7 +7,7 @@ struct B;
|
||||
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!()
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -12,8 +12,8 @@ unsafe extern "C" fn pass(args: PassArg) {
|
||||
|
||||
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 @@ impl Test {
|
||||
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 @@ impl Test {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Test();
|
||||
let x = Test(std::ptr::null());
|
||||
x.call_me::<PassArg, 30, pass>()
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>() {}
|
||||
| ^^^^^^^
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>;
|
||||
| ^^^^^
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
39
tests/ui/const-generics/std/const-generics-range.full.stderr
Normal file
39
tests/ui/const-generics/std/const-generics-range.full.stderr
Normal 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`.
|
@ -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>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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))]
|
||||
|
@ -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(){
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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>() {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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 @@ pub struct TupleByteBool<const TBB: (u8, bool)>;
|
||||
//~| 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,
|
||||
|
@ -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]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user