move const param structural match checks to wfcheck
This commit is contained in:
parent
b287b56f97
commit
70dfe3fa74
@ -729,8 +729,8 @@ impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_wf_new(tcx: TyCtxt<'_>) {
|
pub fn check_wf_new(tcx: TyCtxt<'_>) {
|
||||||
let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
|
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
|
||||||
tcx.hir().krate().par_visit_all_item_likes(&visit);
|
tcx.hir().krate().visit_all_item_likes(&mut visit.as_deep_visitor());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
||||||
|
@ -6,9 +6,11 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
|
use rustc_hir::intravisit as hir_visit;
|
||||||
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items;
|
use rustc_hir::lang_items;
|
||||||
use rustc_hir::ItemKind;
|
use rustc_hir::ItemKind;
|
||||||
|
use rustc_middle::hir::map as hir_map;
|
||||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
|
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
|
||||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
@ -275,6 +277,95 @@ pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
check_associated_item(tcx, impl_item.hir_id, impl_item.span, method_sig);
|
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 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_associated_item(
|
fn check_associated_item(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
item_id: hir::HirId,
|
item_id: hir::HirId,
|
||||||
@ -1292,23 +1383,38 @@ impl CheckTypeWellFormedVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParItemLikeVisitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
|
impl Visitor<'tcx> for CheckTypeWellFormedVisitor<'tcx> {
|
||||||
fn visit_item(&self, i: &'tcx hir::Item<'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);
|
debug!("visit_item: {:?}", i);
|
||||||
let def_id = self.tcx.hir().local_def_id(i.hir_id);
|
let def_id = self.tcx.hir().local_def_id(i.hir_id);
|
||||||
self.tcx.ensure().check_item_well_formed(def_id);
|
self.tcx.ensure().check_item_well_formed(def_id);
|
||||||
|
hir_visit::walk_item(self, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
||||||
debug!("visit_trait_item: {:?}", trait_item);
|
debug!("visit_trait_item: {:?}", trait_item);
|
||||||
let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
|
let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
|
||||||
self.tcx.ensure().check_trait_item_well_formed(def_id);
|
self.tcx.ensure().check_trait_item_well_formed(def_id);
|
||||||
|
hir_visit::walk_trait_item(self, trait_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||||
debug!("visit_impl_item: {:?}", impl_item);
|
debug!("visit_impl_item: {:?}", impl_item);
|
||||||
let def_id = self.tcx.hir().local_def_id(impl_item.hir_id);
|
let def_id = self.tcx.hir().local_def_id(impl_item.hir_id);
|
||||||
self.tcx.ensure().check_impl_item_well_formed(def_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);
|
||||||
|
// No need to walk further here, there is nothing interesting
|
||||||
|
// inside of generic params we don't already check in `check_param_wf`.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ use rustc_middle::ty::util::IntTypeExt;
|
|||||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::traits;
|
|
||||||
|
|
||||||
use super::ItemCtxt;
|
use super::ItemCtxt;
|
||||||
use super::{bad_placeholder_type, is_suggestable_infer_ty};
|
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 {
|
Node::GenericParam(param) => match ¶m.kind {
|
||||||
GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),
|
GenericParamKind::Type { default: Some(ty), .. }
|
||||||
GenericParamKind::Const { ty: ref hir_ty, .. } => {
|
| GenericParamKind::Const { ty, .. } => icx.to_ty(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
|
|
||||||
}
|
|
||||||
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
|
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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,159 +1,16 @@
|
|||||||
error[E0391]: cycle detected when computing type of `Foo`
|
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/nested-type.rs:7:1
|
--> $DIR/nested-type.rs:17:5
|
||||||
|
|
|
|
||||||
LL | struct Foo<const N: [u8; {
|
LL | Foo::<17>::value()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
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() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo`
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/nested-type.rs:7:1
|
--> $DIR/nested-type.rs:17:5
|
||||||
|
|
|
|
||||||
LL | struct Foo<const N: [u8; {
|
LL | Foo::<17>::value()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value`
|
||||||
|
|
|
||||||
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() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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`.
|
||||||
|
@ -4,172 +4,29 @@ error: using `[u8; _]` as const generic parameters is forbidden
|
|||||||
LL | struct Foo<const N: [u8; {
|
LL | struct Foo<const N: [u8; {
|
||||||
| _____________________^
|
| _____________________^
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | | struct Foo<const N: usize>;
|
||||||
LL | |
|
LL | |
|
||||||
... |
|
... |
|
||||||
LL | | Foo::<17>::value()
|
LL | |
|
||||||
LL | | }]>;
|
LL | | }]>;
|
||||||
| |__^
|
| |__^
|
||||||
|
|
|
|
||||||
= note: the only supported types are integers, `bool` and `char`
|
= note: the only supported types are integers, `bool` and `char`
|
||||||
= note: more complex types are supported with `#[feature(const_generics)]`
|
= note: more complex types are supported with `#[feature(const_generics)]`
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo`
|
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/nested-type.rs:7:1
|
--> $DIR/nested-type.rs:17:5
|
||||||
|
|
|
|
||||||
LL | struct Foo<const N: [u8; {
|
LL | Foo::<17>::value()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
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() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo`
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/nested-type.rs:7:1
|
--> $DIR/nested-type.rs:17:5
|
||||||
|
|
|
|
||||||
LL | struct Foo<const N: [u8; {
|
LL | Foo::<17>::value()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^ calling non-const function `Foo::{{constant}}#0::Foo::<17_usize>::value`
|
||||||
|
|
|
||||||
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() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
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`.
|
||||||
|
@ -5,9 +5,7 @@
|
|||||||
#![cfg_attr(min, feature(min_const_generics))]
|
#![cfg_attr(min, feature(min_const_generics))]
|
||||||
|
|
||||||
struct Foo<const N: [u8; {
|
struct Foo<const N: [u8; {
|
||||||
//~^ ERROR cycle detected
|
//[min]~^ ERROR using `[u8; _]` as const generic
|
||||||
//~| ERROR cycle detected
|
|
||||||
//[min]~| ERROR using `[u8; _]` as const generic
|
|
||||||
struct Foo<const N: usize>;
|
struct Foo<const N: usize>;
|
||||||
|
|
||||||
impl<const N: usize> Foo<N> {
|
impl<const N: usize> Foo<N> {
|
||||||
@ -17,6 +15,8 @@ struct Foo<const N: [u8; {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Foo::<17>::value()
|
Foo::<17>::value()
|
||||||
|
//~^ ERROR calls in constants are limited to constant functions
|
||||||
|
//~| ERROR evaluation of constant value failed
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user