Rollup merge of #74159 - lcnr:const-generic-ty-decl, r=varkor
forbid generic params in the type of const params implements and closes #74152 fixes #74101, closes #71169, fixes #73491, closes #62878 @eddyb and I talked [on zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/type.20of.20const.20parameters/near/203405696) about this and we probably want to also forbid generic consts in the default type of a parameter, e.g. `struct Foo<T, U = [u8; std::mem::size_of::<T>()]>`, this is currently still allowed and I will probably fix that in a followup PR. r? @varkor @eddyb
This commit is contained in:
commit
6ef0dfa42f
22 changed files with 271 additions and 36 deletions
|
@ -452,6 +452,7 @@ E0766: include_str!("./error_codes/E0766.md"),
|
|||
E0767: include_str!("./error_codes/E0767.md"),
|
||||
E0768: include_str!("./error_codes/E0768.md"),
|
||||
E0769: include_str!("./error_codes/E0769.md"),
|
||||
E0770: include_str!("./error_codes/E0770.md"),
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Const parameters cannot depend on type parameters.
|
||||
The following is therefore invalid:
|
||||
|
||||
```compile_fail,E0741
|
||||
```compile_fail,E0770
|
||||
#![feature(const_generics)]
|
||||
|
||||
fn const_id<T, const N: T>() -> T { // error
|
||||
|
|
15
src/librustc_error_codes/error_codes/E0770.md
Normal file
15
src/librustc_error_codes/error_codes/E0770.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
The type of a const parameter references other generic parameters.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0770
|
||||
#![feature(const_generics)]
|
||||
fn foo<T, const N: T>() {} // error!
|
||||
```
|
||||
|
||||
To fix this error, use a concrete type for the const parameter:
|
||||
|
||||
```
|
||||
#![feature(const_generics)]
|
||||
fn foo<T, const N: usize>() {}
|
||||
```
|
|
@ -2687,7 +2687,7 @@ pub enum Node<'hir> {
|
|||
Crate(&'hir CrateItem<'hir>),
|
||||
}
|
||||
|
||||
impl Node<'_> {
|
||||
impl<'hir> Node<'hir> {
|
||||
pub fn ident(&self) -> Option<Ident> {
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { ident, .. })
|
||||
|
@ -2698,7 +2698,7 @@ impl Node<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fn_decl(&self) -> Option<&FnDecl<'_>> {
|
||||
pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> {
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
|
||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
|
||||
|
@ -2722,7 +2722,7 @@ impl Node<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> Option<&Generics<'_>> {
|
||||
pub fn generics(&self) -> Option<&'hir Generics<'hir>> {
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { generics, .. })
|
||||
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
|
||||
|
|
|
@ -442,6 +442,19 @@ impl<'a> Resolver<'a> {
|
|||
);
|
||||
err
|
||||
}
|
||||
ResolutionError::ParamInTyOfConstArg(name) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0770,
|
||||
"the type of const parameters must not depend on other generic parameters"
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
format!("the type must not depend on the parameter `{}`", name),
|
||||
);
|
||||
err
|
||||
}
|
||||
ResolutionError::SelfInTyParamDefault => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
|
|
|
@ -123,6 +123,10 @@ crate enum RibKind<'a> {
|
|||
/// from the default of a type parameter because they're not declared
|
||||
/// before said type parameter. Also see the `visit_generics` override.
|
||||
ForwardTyParamBanRibKind,
|
||||
|
||||
/// We are inside of the type of a const parameter. Can't refer to any
|
||||
/// parameters.
|
||||
ConstParamTyRibKind,
|
||||
}
|
||||
|
||||
impl RibKind<'_> {
|
||||
|
@ -135,7 +139,8 @@ impl RibKind<'_> {
|
|||
| FnItemRibKind
|
||||
| ConstantItemRibKind
|
||||
| ModuleRibKind(_)
|
||||
| MacroDefinition(_) => false,
|
||||
| MacroDefinition(_)
|
||||
| ConstParamTyRibKind => false,
|
||||
AssocItemRibKind | ItemRibKind(_) | ForwardTyParamBanRibKind => true,
|
||||
}
|
||||
}
|
||||
|
@ -576,7 +581,11 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
for bound in ¶m.bounds {
|
||||
self.visit_param_bound(bound);
|
||||
}
|
||||
self.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
|
||||
self.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
|
||||
self.visit_ty(ty);
|
||||
self.ribs[TypeNS].pop().unwrap();
|
||||
self.ribs[ValueNS].pop().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -814,7 +823,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
| ItemRibKind(..)
|
||||
| ConstantItemRibKind
|
||||
| ModuleRibKind(..)
|
||||
| ForwardTyParamBanRibKind => {
|
||||
| ForwardTyParamBanRibKind
|
||||
| ConstParamTyRibKind => {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,6 +214,8 @@ enum ResolutionError<'a> {
|
|||
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
|
||||
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
|
||||
ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
|
||||
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
|
||||
ParamInTyOfConstArg(Symbol),
|
||||
/// Error E0735: type parameters with a default cannot use `Self`
|
||||
SelfInTyParamDefault,
|
||||
/// Error E0767: use of unreachable label
|
||||
|
@ -2480,6 +2482,12 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
return Res::Err;
|
||||
}
|
||||
ConstParamTyRibKind => {
|
||||
if record_used {
|
||||
self.report_error(span, ParamInTyOfConstArg(rib_ident.name));
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(res_err) = res_err {
|
||||
|
@ -2503,6 +2511,15 @@ impl<'a> Resolver<'a> {
|
|||
// This was an attempt to use a type parameter outside its scope.
|
||||
ItemRibKind(has_generic_params) => has_generic_params,
|
||||
FnItemRibKind => HasGenericParams::Yes,
|
||||
ConstParamTyRibKind => {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInTyOfConstArg(rib_ident.name),
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
};
|
||||
|
||||
if record_used {
|
||||
|
@ -2527,9 +2544,24 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
for rib in ribs {
|
||||
let has_generic_params = match rib.kind {
|
||||
NormalRibKind
|
||||
| ClosureOrAsyncRibKind
|
||||
| AssocItemRibKind
|
||||
| ModuleRibKind(..)
|
||||
| MacroDefinition(..)
|
||||
| ForwardTyParamBanRibKind
|
||||
| ConstantItemRibKind => continue,
|
||||
ItemRibKind(has_generic_params) => has_generic_params,
|
||||
FnItemRibKind => HasGenericParams::Yes,
|
||||
_ => continue,
|
||||
ConstParamTyRibKind => {
|
||||
if record_used {
|
||||
self.report_error(
|
||||
span,
|
||||
ResolutionError::ParamInTyOfConstArg(rib_ident.name),
|
||||
);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
};
|
||||
|
||||
// This was an attempt to use a const parameter outside its scope.
|
||||
|
|
|
@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
|||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::weak_lang_items;
|
||||
use rustc_hir::{GenericParamKind, Node};
|
||||
use rustc_hir::{GenericParamKind, HirId, Node};
|
||||
use rustc_middle::hir::map::blocks::FnLikeNode;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
|
@ -1155,6 +1155,35 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
|||
}
|
||||
}
|
||||
|
||||
struct AnonConstInParamListDetector {
|
||||
in_param_list: bool,
|
||||
found_anon_const_in_list: bool,
|
||||
ct: HirId,
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for AnonConstInParamListDetector {
|
||||
type Map = intravisit::ErasedMap<'v>;
|
||||
|
||||
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
|
||||
NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
|
||||
let prev = self.in_param_list;
|
||||
self.in_param_list = true;
|
||||
intravisit::walk_generic_param(self, p);
|
||||
self.in_param_list = prev;
|
||||
}
|
||||
|
||||
fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
|
||||
if self.in_param_list && self.ct == c.hir_id {
|
||||
self.found_anon_const_in_list = true;
|
||||
} else {
|
||||
intravisit::walk_anon_const(self, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||
use rustc_hir::*;
|
||||
|
||||
|
@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
|||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||
let parent_def_id = tcx.hir().local_def_id(parent_id);
|
||||
|
||||
// HACK(eddyb) this provides the correct generics when
|
||||
// `feature(const_generics)` is enabled, so that const expressions
|
||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||
if tcx.lazy_normalization() {
|
||||
let mut in_param_list = false;
|
||||
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
|
||||
if let Some(generics) = node.generics() {
|
||||
let mut visitor = AnonConstInParamListDetector {
|
||||
in_param_list: false,
|
||||
found_anon_const_in_list: false,
|
||||
ct: hir_id,
|
||||
};
|
||||
|
||||
visitor.visit_generics(generics);
|
||||
in_param_list = visitor.found_anon_const_in_list;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if in_param_list {
|
||||
// We do not allow generic parameters in anon consts if we are inside
|
||||
// of a param list.
|
||||
//
|
||||
// This affects both default type bindings, e.g. `struct<T, U = [u8; std::mem::size_of::<T>()]>(T, U)`,
|
||||
// and the types of const parameters, e.g. `struct V<const N: usize, const M: [u8; N]>();`.
|
||||
None
|
||||
} else if tcx.lazy_normalization() {
|
||||
// HACK(eddyb) this provides the correct generics when
|
||||
// `feature(const_generics)` is enabled, so that const expressions
|
||||
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
|
||||
Some(parent_def_id.to_def_id())
|
||||
} else {
|
||||
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
// Currently, const parameters cannot depend on other generic parameters,
|
||||
// as our current implementation can't really support this.
|
||||
//
|
||||
// We may want to lift this restriction in the future.
|
||||
|
||||
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
|
||||
pub struct SelfDependent<const N: [u8; N]>;
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,24 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:9:52
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:12:40
|
||||
|
|
||||
LL | pub struct SelfDependent<const N: [u8; N]>;
|
||||
| ^ the type must not depend on the parameter `N`
|
||||
|
||||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
|
@ -1,6 +1,6 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
|
||||
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
|
||||
//~^ ERROR the type of const parameters must not depend on other generic parameters
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
|
||||
|
|
||||
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
||||
error[E0658]: const generics are unstable
|
||||
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19
|
||||
|
|
||||
|
@ -7,15 +13,7 @@ LL | struct B<T, const N: T>(PhantomData<[T; N]>);
|
|||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
= help: add `#![feature(const_generics)]` to the crate attributes to enable
|
||||
|
||||
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
|
||||
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
|
||||
|
|
||||
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
|
||||
| ^ `T` 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
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0658, E0741.
|
||||
Some errors have detailed explanations: E0658, E0770.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
// Currently, const parameters cannot depend on type parameters, because there is no way to
|
||||
// enforce the structural-match property on an arbitrary type parameter. This restriction
|
||||
// may be relaxed in the future. See https://github.com/rust-lang/rfcs/pull/2000 for more
|
||||
// details.
|
||||
// Currently, const parameters cannot depend on other generic parameters,
|
||||
// as our current implementation can't really support this.
|
||||
//
|
||||
// We may want to lift this restriction in the future.
|
||||
|
||||
pub struct Dependent<T, const X: T>([(); X]);
|
||||
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
|
||||
//~^ ERROR: the type of const parameters must not depend on other generic parameters
|
||||
//~| ERROR: parameter `T` is never used
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:9:34
|
||||
|
|
||||
LL | pub struct Dependent<T, const X: T>([(); X]);
|
||||
| ^ the type must not depend on the parameter `T`
|
||||
|
||||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:1:12
|
||||
|
|
||||
|
@ -7,14 +13,15 @@ LL | #![feature(const_generics)]
|
|||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:9:34
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/const-param-type-depends-on-type-param.rs:9:22
|
||||
|
|
||||
LL | pub struct Dependent<T, const X: T>([(); X]);
|
||||
| ^ `T` may not derive both `PartialEq` and `Eq`
|
||||
| ^ unused parameter
|
||||
|
|
||||
= note: it is not currently possible to use a type parameter as the type of a const parameter
|
||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0741`.
|
||||
Some errors have detailed explanations: E0392, E0770.
|
||||
For more information about an error, try `rustc --explain E0392`.
|
||||
|
|
10
src/test/ui/const-generics/issues/issue-71169.rs
Normal file
10
src/test/ui/const-generics/issues/issue-71169.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
|
||||
//~^ ERROR the type of const parameters must not
|
||||
fn main() {
|
||||
const DATA: [u8; 4] = *b"ABCD";
|
||||
foo::<4, DATA>();
|
||||
//~^ ERROR constant expression depends on
|
||||
}
|
17
src/test/ui/const-generics/issues/issue-71169.stderr
Normal file
17
src/test/ui/const-generics/issues/issue-71169.stderr
Normal file
|
@ -0,0 +1,17 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71169.rs:4:43
|
||||
|
|
||||
LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
|
||||
| ^^^ the type must not depend on the parameter `LEN`
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/issue-71169.rs:8:14
|
||||
|
|
||||
LL | foo::<4, DATA>();
|
||||
| ^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
|
@ -12,6 +12,7 @@ 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
|
||||
self.0 = Self::trampiline::<Args, IDX, FN> as _
|
||||
}
|
||||
|
||||
|
@ -20,6 +21,7 @@ impl Test {
|
|||
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
|
||||
>(
|
||||
args: Args,
|
||||
) {
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:13:82
|
||||
|
|
||||
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
||||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71381.rs:22:40
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^ the type must not depend on the parameter `Args`
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:13:61
|
||||
|
|
||||
|
@ -5,10 +17,11 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:21:19
|
||||
--> $DIR/issue-71381.rs:22:19
|
||||
|
|
||||
LL | const FN: unsafe extern "C" fn(Args),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
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
|
||||
F(outer);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
error[E0770]: the type of const parameters must not depend on other generic parameters
|
||||
--> $DIR/issue-71611.rs:4:31
|
||||
|
|
||||
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
||||
| ^ the type must not depend on the parameter `A`
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71611.rs:4: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
|
||||
|
||||
For more information about this error, try `rustc --explain E0770`.
|
||||
|
|
9
src/test/ui/const-generics/issues/issue-73491.rs
Normal file
9
src/test/ui/const-generics/issues/issue-73491.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// check-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
const LEN: usize = 1024;
|
||||
|
||||
fn hoge<const IN: [u32; LEN]>() {}
|
||||
|
||||
fn main() {}
|
9
src/test/ui/const-generics/issues/issue-74101.rs
Normal file
9
src/test/ui/const-generics/issues/issue-74101.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// check-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn test<const N: [u8; 1 + 2]>() {}
|
||||
|
||||
struct Foo<const N: [u8; 1 + 2]>;
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue