Rollup merge of #75069 - lcnr:type-of-lazy-norm, r=varkor
move const param structural match checks to wfcheck fixes #75047 fixes #74950 We currently check for structural match violations inside of `type_of`. As we need to check the array length when checking if `[NonEq; arr_len]` is structural match, we potentially require the variance of an expression. Computing the variance requires `type_of` for all types though, resulting in a cycle error. r? @varkor @eddyb
This commit is contained in:
commit
672d009b0c
@ -6,9 +6,12 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit as hir_visit;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
|
||||
use rustc_hir::lang_items;
|
||||
use rustc_hir::ItemKind;
|
||||
use rustc_middle::hir::map as hir_map;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{
|
||||
@ -275,6 +278,107 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig);
|
||||
}
|
||||
|
||||
fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
||||
match param.kind {
|
||||
// We currently only check wf of const params here.
|
||||
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (),
|
||||
|
||||
// Const parameters are well formed if their
|
||||
// type is structural match.
|
||||
hir::GenericParamKind::Const { ty: hir_ty } => {
|
||||
let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
|
||||
|
||||
let err_ty_str;
|
||||
let mut is_ptr = true;
|
||||
let err = if tcx.features().min_const_generics {
|
||||
match ty.kind {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => {
|
||||
is_ptr = false;
|
||||
err_ty_str = format!("`{}`", ty);
|
||||
Some(err_ty_str.as_str())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match ty.peel_refs().kind {
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
if let Some(unsupported_type) = err {
|
||||
if is_ptr {
|
||||
tcx.sess.span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
"using {} as const generic parameters is forbidden",
|
||||
unsupported_type
|
||||
),
|
||||
)
|
||||
} else {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
"{} is forbidden as the type of a const generic parameter",
|
||||
unsupported_type
|
||||
),
|
||||
)
|
||||
.note("the only supported types are integers, `bool` and `char`")
|
||||
.note("more complex types are supported with `#[feature(const_generics)]`")
|
||||
.emit()
|
||||
}
|
||||
};
|
||||
|
||||
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
|
||||
.is_some()
|
||||
{
|
||||
// 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.
|
||||
if let ty::Param(_) = ty.peel_refs().kind {
|
||||
// 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,
|
||||
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
|
||||
used as the type of a const parameter",
|
||||
ty,
|
||||
)
|
||||
.span_label(
|
||||
hir_ty.span,
|
||||
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
|
||||
)
|
||||
.note(
|
||||
"it is not currently possible to use a type parameter as the type of a \
|
||||
const parameter",
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
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",
|
||||
ty,
|
||||
)
|
||||
.span_label(
|
||||
hir_ty.span,
|
||||
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_associated_item(
|
||||
tcx: TyCtxt<'_>,
|
||||
item_id: hir::HirId,
|
||||
@ -1282,6 +1386,7 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
|
||||
fcx.select_all_obligations_or_error();
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct CheckTypeWellFormedVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
@ -1294,21 +1399,49 @@ impl CheckTypeWellFormedVisitor<'tcx> {
|
||||
|
||||
impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
|
||||
fn visit_item(&self, i: &'tcx hir::Item<'tcx>) {
|
||||
debug!("visit_item: {:?}", i);
|
||||
let def_id = self.tcx.hir().local_def_id(i.hir_id);
|
||||
self.tcx.ensure().check_item_well_formed(def_id);
|
||||
Visitor::visit_item(&mut self.clone(), i);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
||||
debug!("visit_trait_item: {:?}", trait_item);
|
||||
let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
|
||||
self.tcx.ensure().check_trait_item_well_formed(def_id);
|
||||
Visitor::visit_trait_item(&mut self.clone(), trait_item);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||
Visitor::visit_impl_item(&mut self.clone(), impl_item);
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
|
||||
type Map = hir_map::Map<'tcx>;
|
||||
|
||||
fn nested_visit_map(&mut self) -> hir_visit::NestedVisitorMap<Self::Map> {
|
||||
hir_visit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
|
||||
debug!("visit_item: {:?}", i);
|
||||
let def_id = self.tcx.hir().local_def_id(i.hir_id);
|
||||
self.tcx.ensure().check_item_well_formed(def_id);
|
||||
hir_visit::walk_item(self, i);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
||||
debug!("visit_trait_item: {:?}", trait_item);
|
||||
let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
|
||||
self.tcx.ensure().check_trait_item_well_formed(def_id);
|
||||
hir_visit::walk_trait_item(self, trait_item);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||
debug!("visit_impl_item: {:?}", impl_item);
|
||||
let def_id = self.tcx.hir().local_def_id(impl_item.hir_id);
|
||||
self.tcx.ensure().check_impl_item_well_formed(def_id);
|
||||
hir_visit::walk_impl_item(self, impl_item);
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
|
||||
check_param_wf(self.tcx, p);
|
||||
hir_visit::walk_generic_param(self, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
use super::ItemCtxt;
|
||||
use super::{bad_placeholder_type, is_suggestable_infer_ty};
|
||||
@ -323,88 +322,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
}
|
||||
|
||||
Node::GenericParam(param) => match ¶m.kind {
|
||||
GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),
|
||||
GenericParamKind::Const { ty: ref hir_ty, .. } => {
|
||||
let ty = icx.to_ty(hir_ty);
|
||||
let err_ty_str;
|
||||
let err = if tcx.features().min_const_generics {
|
||||
match ty.kind {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => {
|
||||
err_ty_str = format!("`{}`", ty);
|
||||
Some(err_ty_str.as_str())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match ty.peel_refs().kind {
|
||||
ty::FnPtr(_) => Some("function pointers"),
|
||||
ty::RawPtr(_) => Some("raw pointers"),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
if let Some(unsupported_type) = err {
|
||||
let mut err = tcx.sess.struct_span_err(
|
||||
hir_ty.span,
|
||||
&format!(
|
||||
"using {} as const generic parameters is forbidden",
|
||||
unsupported_type
|
||||
),
|
||||
);
|
||||
|
||||
if tcx.features().min_const_generics {
|
||||
err.note("the only supported types are integers, `bool` and `char`")
|
||||
.note("more complex types are supported with `#[feature(const_generics)]`").emit()
|
||||
} else {
|
||||
err.emit();
|
||||
}
|
||||
};
|
||||
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
|
||||
.is_some()
|
||||
{
|
||||
// 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.
|
||||
if let ty::Param(_) = ty.peel_refs().kind {
|
||||
// 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,
|
||||
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
|
||||
used as the type of a const parameter",
|
||||
ty,
|
||||
)
|
||||
.span_label(
|
||||
hir_ty.span,
|
||||
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
|
||||
)
|
||||
.note(
|
||||
"it is not currently possible to use a type parameter as the type of a \
|
||||
const parameter",
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
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",
|
||||
ty,
|
||||
)
|
||||
.span_label(
|
||||
hir_ty.span,
|
||||
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
ty
|
||||
}
|
||||
GenericParamKind::Type { default: Some(ty), .. }
|
||||
| GenericParamKind::Const { ty, .. } => icx.to_ty(ty),
|
||||
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
|
||||
},
|
||||
|
||||
|
@ -14,7 +14,7 @@ LL | arr: [u8; CFG.arr_size],
|
||||
|
|
||||
= help: it is currently only allowed to use either `CFG` or `{ CFG }` as generic constants
|
||||
|
||||
error: using `Config` as const generic parameters is forbidden
|
||||
error: `Config` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/array-size-in-generic-struct-param.rs:18:21
|
||||
|
|
||||
LL | struct B<const CFG: Config> {
|
||||
|
@ -16,7 +16,7 @@ struct Config {
|
||||
}
|
||||
|
||||
struct B<const CFG: Config> {
|
||||
//[min]~^ ERROR using `Config` as const generic parameters is forbidden
|
||||
//[min]~^ ERROR `Config` is forbidden
|
||||
arr: [u8; CFG.arr_size],
|
||||
//[full]~^ ERROR constant expression depends on a generic parameter
|
||||
//[min]~^^ ERROR generic parameters must not be used inside of non trivial
|
||||
|
@ -28,7 +28,7 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here
|
||||
LL | fn bar<const N: &u8>() {}
|
||||
| ^ explicit lifetime name needed here
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-elided-lifetime.rs:11:19
|
||||
|
|
||||
LL | struct A<const N: &u8>;
|
||||
@ -37,7 +37,7 @@ LL | struct A<const N: &u8>;
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-elided-lifetime.rs:16:15
|
||||
|
|
||||
LL | impl<const N: &u8> A<N> {
|
||||
@ -46,7 +46,7 @@ LL | impl<const N: &u8> A<N> {
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-elided-lifetime.rs:24:15
|
||||
|
|
||||
LL | impl<const N: &u8> B for A<N> {}
|
||||
@ -55,7 +55,7 @@ LL | impl<const N: &u8> B for A<N> {}
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-elided-lifetime.rs:28:17
|
||||
|
|
||||
LL | fn bar<const N: &u8>() {}
|
||||
@ -64,7 +64,7 @@ LL | fn bar<const N: &u8>() {}
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-elided-lifetime.rs:19:21
|
||||
|
|
||||
LL | fn foo<const M: &u8>(&self) {}
|
||||
|
@ -10,23 +10,23 @@
|
||||
|
||||
struct A<const N: &u8>;
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `&'static u8` is forbidden
|
||||
trait B {}
|
||||
|
||||
impl<const N: &u8> A<N> {
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `&'static u8` is forbidden
|
||||
fn foo<const M: &u8>(&self) {}
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `&'static u8` is forbidden
|
||||
}
|
||||
|
||||
impl<const N: &u8> B for A<N> {}
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `&'static u8` is forbidden
|
||||
|
||||
fn bar<const N: &u8>() {}
|
||||
//~^ ERROR `&` without an explicit lifetime name cannot be used here
|
||||
//[min]~^^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `&'static u8` is forbidden
|
||||
|
||||
fn main() {}
|
||||
|
@ -10,7 +10,7 @@ error[E0770]: the type of const parameters must not depend on other generic para
|
||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
||||
error: using `[u8; _]` as const generic parameters is forbidden
|
||||
error: `[u8; _]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:12:47
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
@ -19,7 +19,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `[u8; _]` as const generic parameters is forbidden
|
||||
error: `[u8; _]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:16:35
|
||||
|
|
||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~^^ ERROR using `[u8; _]` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `[u8; _]` is forbidden
|
||||
|
||||
pub struct SelfDependent<const N: [u8; N]>;
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//[min]~^^ ERROR using `[u8; _]` as const generic parameters is forbidden
|
||||
//[min]~^^ ERROR `[u8; _]` is forbidden
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `[usize; 1]` as const generic parameters is forbidden
|
||||
error: `[usize; 1]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/different_byref.rs:8:23
|
||||
|
|
||||
LL | struct Const<const V: [usize; 1]> {}
|
||||
|
@ -6,7 +6,7 @@
|
||||
#![cfg_attr(min, feature(min_const_generics))]
|
||||
|
||||
struct Const<const V: [usize; 1]> {}
|
||||
//[min]~^ using `[usize; 1]` as const generic parameters is forbidden
|
||||
//[min]~^ ERROR `[usize; 1]` is forbidden
|
||||
|
||||
fn main() {
|
||||
let mut x = Const::<{ [3] }> {};
|
||||
|
@ -3,18 +3,12 @@ error: using function pointers as const generic parameters is forbidden
|
||||
|
|
||||
LL | struct Wrapper<const F: fn() -> u32>;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/fn-const-param-call.rs:14:15
|
||||
|
|
||||
LL | impl<const F: fn() -> u32> Wrapper<F> {
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,9 +3,6 @@ error: using function pointers as const generic parameters is forbidden
|
||||
|
|
||||
LL | struct Checked<const F: fn(usize) -> bool>;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `A` as const generic parameters is forbidden
|
||||
error: `A` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/forbid-non-structural_match-types.rs:10:19
|
||||
|
|
||||
LL | struct B<const X: A>; // ok
|
||||
@ -7,7 +7,7 @@ LL | struct B<const X: A>; // ok
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `C` as const generic parameters is forbidden
|
||||
error: `C` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/forbid-non-structural_match-types.rs:15:19
|
||||
|
|
||||
LL | struct D<const X: C>;
|
||||
|
@ -8,11 +8,11 @@
|
||||
struct A;
|
||||
|
||||
struct B<const X: A>; // ok
|
||||
//[min]~^ ERROR using `A` as const generic parameters is forbidden
|
||||
//[min]~^ ERROR `A` is forbidden
|
||||
|
||||
struct C;
|
||||
|
||||
struct D<const X: C>; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
//[min]~^ ERROR using `C` as const generic parameters is forbidden
|
||||
//[min]~^ ERROR `C` is forbidden
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `&'static str` as const generic parameters is forbidden
|
||||
error: `&'static str` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-66596-impl-trait-for-str-const-arg.rs:9:25
|
||||
|
|
||||
LL | trait Trait<const NAME: &'static str> {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
trait Trait<const NAME: &'static str> {
|
||||
//[min]~^ ERROR using `&'static str` as const generic parameters is forbidden
|
||||
//[min]~^ ERROR `&'static str` is forbidden
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
|
@ -6,15 +6,6 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
|
|
||||
= note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052>
|
||||
|
||||
error: using `&'static str` as const generic parameters is forbidden
|
||||
--> $DIR/issue-56445.rs:9:25
|
||||
|
|
||||
LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0771`.
|
||||
|
@ -8,6 +8,5 @@ use std::marker::PhantomData;
|
||||
|
||||
struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
|
||||
//~^ ERROR: use of non-static lifetime `'a` in const generic
|
||||
//[min]~| ERROR: using `&'static str` as const
|
||||
|
||||
impl Bug<'_, ""> {}
|
||||
|
47
src/test/ui/const-generics/issues/issue-74950.min.stderr
Normal file
47
src/test/ui/const-generics/issues/issue-74950.min.stderr
Normal file
@ -0,0 +1,47 @@
|
||||
error: `Inner` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-74950.rs:18:23
|
||||
|
|
||||
LL | struct Outer<const I: Inner>;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: `Inner` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-74950.rs:18:23
|
||||
|
|
||||
LL | struct Outer<const I: Inner>;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: `Inner` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-74950.rs:18:23
|
||||
|
|
||||
LL | struct Outer<const I: Inner>;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: `Inner` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-74950.rs:18:23
|
||||
|
|
||||
LL | struct Outer<const I: Inner>;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: `Inner` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/issue-74950.rs:18:23
|
||||
|
|
||||
LL | struct Outer<const I: Inner>;
|
||||
| ^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
25
src/test/ui/const-generics/issues/issue-74950.rs
Normal file
25
src/test/ui/const-generics/issues/issue-74950.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// [full] build-pass
|
||||
// revisions: full min
|
||||
#![cfg_attr(full, feature(const_generics))]
|
||||
#![cfg_attr(full, allow(incomplete_features))]
|
||||
#![cfg_attr(min, feature(min_const_generics))]
|
||||
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Inner;
|
||||
|
||||
// Note: We emit the error 5 times if we don't deduplicate:
|
||||
// - struct definition
|
||||
// - impl PartialEq
|
||||
// - impl Eq
|
||||
// - impl StructuralPartialEq
|
||||
// - impl StructuralEq
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Outer<const I: Inner>;
|
||||
//[min]~^ `Inner` is forbidden
|
||||
//[min]~| `Inner` is forbidden
|
||||
//[min]~| `Inner` is forbidden
|
||||
//[min]~| `Inner` is forbidden
|
||||
//[min]~| `Inner` is forbidden
|
||||
|
||||
fn main() {}
|
15
src/test/ui/const-generics/issues/issue-75047.rs
Normal file
15
src/test/ui/const-generics/issues/issue-75047.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// check-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl<T> Bar<T> {
|
||||
const fn value() -> usize {
|
||||
42
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo<const N: [u8; Bar::<u32>::value()]>;
|
||||
|
||||
fn main() {}
|
@ -1,18 +1,17 @@
|
||||
#![feature(min_const_generics)]
|
||||
|
||||
struct Foo<const N: [u8; 0]>;
|
||||
//~^ ERROR using `[u8; 0]` as const generic parameters is forbidden
|
||||
//~^ ERROR `[u8; 0]` is forbidden
|
||||
|
||||
struct Bar<const N: ()>;
|
||||
//~^ ERROR using `()` as const generic parameters is forbidden
|
||||
|
||||
//~^ ERROR `()` is forbidden
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct No;
|
||||
|
||||
struct Fez<const N: No>;
|
||||
//~^ ERROR using `No` as const generic parameters is forbidden
|
||||
//~^ ERROR `No` is forbidden
|
||||
|
||||
struct Faz<const N: &'static u8>;
|
||||
//~^ ERROR using `&'static u8` as const generic parameters is forbidden
|
||||
//~^ ERROR `&'static u8` is forbidden
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `[u8; 0]` as const generic parameters is forbidden
|
||||
error: `[u8; 0]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/complex-types.rs:3:21
|
||||
|
|
||||
LL | struct Foo<const N: [u8; 0]>;
|
||||
@ -7,7 +7,7 @@ LL | struct Foo<const N: [u8; 0]>;
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `()` as const generic parameters is forbidden
|
||||
error: `()` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/complex-types.rs:6:21
|
||||
|
|
||||
LL | struct Bar<const N: ()>;
|
||||
@ -16,8 +16,8 @@ LL | struct Bar<const N: ()>;
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `No` as const generic parameters is forbidden
|
||||
--> $DIR/complex-types.rs:12:21
|
||||
error: `No` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/complex-types.rs:11:21
|
||||
|
|
||||
LL | struct Fez<const N: No>;
|
||||
| ^^
|
||||
@ -25,8 +25,8 @@ LL | struct Fez<const N: No>;
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static u8` as const generic parameters is forbidden
|
||||
--> $DIR/complex-types.rs:15:21
|
||||
error: `&'static u8` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/complex-types.rs:14:21
|
||||
|
|
||||
LL | struct Faz<const N: &'static u8>;
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -1,159 +1,16 @@
|
||||
error[E0391]: cycle detected when computing type of `Foo`
|
||||
--> $DIR/nested-type.rs:7:1
|
||||
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/nested-type.rs:16:5
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of `Foo::N`...
|
||||
--> $DIR/nested-type.rs:7:18
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires type-checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`...
|
||||
--> $DIR/nested-type.rs:11:5
|
||||
|
|
||||
LL | struct Foo<const N: usize>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires computing the variances for items in this crate...
|
||||
= note: ...which again requires computing type of `Foo`, completing the cycle
|
||||
note: cycle used when collecting item types in top-level module
|
||||
--> $DIR/nested-type.rs:3:1
|
||||
|
|
||||
LL | / #![cfg_attr(full, feature(const_generics))]
|
||||
LL | | #![cfg_attr(full, allow(incomplete_features))]
|
||||
LL | | #![cfg_attr(min, feature(min_const_generics))]
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
LL | Foo::<17>::value()
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0391]: cycle detected when computing type of `Foo`
|
||||
--> $DIR/nested-type.rs:7:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/nested-type.rs:16:5
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of `Foo::N`...
|
||||
--> $DIR/nested-type.rs:7:18
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires type-checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`...
|
||||
--> $DIR/nested-type.rs:11:5
|
||||
|
|
||||
LL | struct Foo<const N: usize>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires computing the variances for items in this crate...
|
||||
= note: ...which again requires computing type of `Foo`, completing the cycle
|
||||
note: cycle used when collecting item types in top-level module
|
||||
--> $DIR/nested-type.rs:3:1
|
||||
|
|
||||
LL | / #![cfg_attr(full, feature(const_generics))]
|
||||
LL | | #![cfg_attr(full, allow(incomplete_features))]
|
||||
LL | | #![cfg_attr(min, feature(min_const_generics))]
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
LL | Foo::<17>::value()
|
||||
| ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
Some errors have detailed explanations: E0015, E0080.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -1,175 +1,32 @@
|
||||
error: using `[u8; _]` as const generic parameters is forbidden
|
||||
error: `[u8; _]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/nested-type.rs:7:21
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| _____________________^
|
||||
LL | | struct Foo<const N: usize>;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | impl<const N: usize> Foo<N> {
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | |
|
||||
LL | | }]>;
|
||||
| |__^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error[E0391]: cycle detected when computing type of `Foo`
|
||||
--> $DIR/nested-type.rs:7:1
|
||||
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/nested-type.rs:16:5
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of `Foo::N`...
|
||||
--> $DIR/nested-type.rs:7:18
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires type-checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`...
|
||||
--> $DIR/nested-type.rs:11:5
|
||||
|
|
||||
LL | struct Foo<const N: usize>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires computing the variances for items in this crate...
|
||||
= note: ...which again requires computing type of `Foo`, completing the cycle
|
||||
note: cycle used when collecting item types in top-level module
|
||||
--> $DIR/nested-type.rs:3:1
|
||||
|
|
||||
LL | / #![cfg_attr(full, feature(const_generics))]
|
||||
LL | | #![cfg_attr(full, allow(incomplete_features))]
|
||||
LL | | #![cfg_attr(min, feature(min_const_generics))]
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
LL | Foo::<17>::value()
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0391]: cycle detected when computing type of `Foo`
|
||||
--> $DIR/nested-type.rs:7:1
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/nested-type.rs:16:5
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of `Foo::N`...
|
||||
--> $DIR/nested-type.rs:7:18
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| ^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires const-evaluating `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires type-checking `Foo::{{constant}}#0`...
|
||||
--> $DIR/nested-type.rs:7:26
|
||||
|
|
||||
LL | struct Foo<const N: [u8; {
|
||||
| __________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | Foo::<17>::value()
|
||||
LL | | }]>;
|
||||
| |_^
|
||||
note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`...
|
||||
--> $DIR/nested-type.rs:11:5
|
||||
|
|
||||
LL | struct Foo<const N: usize>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires computing the variances for items in this crate...
|
||||
= note: ...which again requires computing type of `Foo`, completing the cycle
|
||||
note: cycle used when collecting item types in top-level module
|
||||
--> $DIR/nested-type.rs:3:1
|
||||
|
|
||||
LL | / #![cfg_attr(full, feature(const_generics))]
|
||||
LL | | #![cfg_attr(full, allow(incomplete_features))]
|
||||
LL | | #![cfg_attr(min, feature(min_const_generics))]
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________^
|
||||
LL | Foo::<17>::value()
|
||||
| ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
Some errors have detailed explanations: E0015, E0080.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -4,10 +4,7 @@
|
||||
#![cfg_attr(full, allow(incomplete_features))]
|
||||
#![cfg_attr(min, feature(min_const_generics))]
|
||||
|
||||
struct Foo<const N: [u8; {
|
||||
//~^ ERROR cycle detected
|
||||
//~| ERROR cycle detected
|
||||
//[min]~| ERROR using `[u8; _]` as const generic
|
||||
struct Foo<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
impl<const N: usize> Foo<N> {
|
||||
@ -17,6 +14,8 @@ struct Foo<const N: [u8; {
|
||||
}
|
||||
|
||||
Foo::<17>::value()
|
||||
//~^ ERROR calls in constants are limited to constant functions
|
||||
//~| ERROR evaluation of constant value failed
|
||||
}]>;
|
||||
|
||||
fn main() {}
|
||||
|
@ -3,18 +3,12 @@ error: using raw pointers as const generic parameters is forbidden
|
||||
|
|
||||
LL | struct Const<const P: *const u32>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using raw pointers as const generic parameters is forbidden
|
||||
--> $DIR/raw-ptr-const-param-deref.rs:12:15
|
||||
|
|
||||
LL | impl<const P: *const u32> Const<P> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,9 +3,6 @@ error: using raw pointers as const generic parameters is forbidden
|
||||
|
|
||||
LL | struct Const<const P: *const u32>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `&'static str` as const generic parameters is forbidden
|
||||
error: `&'static str` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/slice-const-param-mismatch.rs:8:29
|
||||
|
|
||||
LL | struct ConstString<const T: &'static str>;
|
||||
@ -7,7 +7,7 @@ LL | struct ConstString<const T: &'static str>;
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static [u8]` as const generic parameters is forbidden
|
||||
error: `&'static [u8]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/slice-const-param-mismatch.rs:10:28
|
||||
|
|
||||
LL | struct ConstBytes<const T: &'static [u8]>;
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: using `&'static str` as const generic parameters is forbidden
|
||||
error: `&'static str` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/slice-const-param.rs:8:40
|
||||
|
|
||||
LL | pub fn function_with_str<const STRING: &'static str>() -> &'static str {
|
||||
@ -7,7 +7,7 @@ LL | pub fn function_with_str<const STRING: &'static str>() -> &'static str {
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||
|
||||
error: using `&'static [u8]` as const generic parameters is forbidden
|
||||
error: `&'static [u8]` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/slice-const-param.rs:13:41
|
||||
|
|
||||
LL | pub fn function_with_bytes<const BYTES: &'static [u8]>() -> &'static [u8] {
|
||||
|
@ -6,12 +6,12 @@
|
||||
#![cfg_attr(min, feature(min_const_generics))]
|
||||
|
||||
pub fn function_with_str<const STRING: &'static str>() -> &'static str {
|
||||
//[min]~^ ERROR using `&'static str` as const
|
||||
//[min]~^ ERROR `&'static str` is forbidden
|
||||
STRING
|
||||
}
|
||||
|
||||
pub fn function_with_bytes<const BYTES: &'static [u8]>() -> &'static [u8] {
|
||||
//[min]~^ ERROR using `&'static [u8]` as const
|
||||
//[min]~^ ERROR `&'static [u8]` is forbidden
|
||||
BYTES
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user