forbid generic params in the type of const params
This commit is contained in:
parent
e2e29de5e8
commit
338a27174a
@ -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>() {}
|
||||
```
|
@ -442,6 +442,16 @@ impl<'a> Resolver<'a> {
|
||||
);
|
||||
err
|
||||
}
|
||||
ResolutionError::ParamInTyOfConstArg => {
|
||||
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, "const parameters must have a concrete type");
|
||||
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,
|
||||
}
|
||||
}
|
||||
@ -562,7 +567,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -798,7 +807,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,
|
||||
/// 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);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(res_err) = res_err {
|
||||
@ -2503,6 +2511,12 @@ 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);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
};
|
||||
|
||||
if record_used {
|
||||
@ -2527,9 +2541,21 @@ 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);
|
||||
}
|
||||
return Res::Err;
|
||||
}
|
||||
};
|
||||
|
||||
// This was an attempt to use a const parameter outside its scope.
|
||||
|
@ -0,0 +1,13 @@
|
||||
#![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
|
||||
//~| ERROR: cycle detected when computing type of `Dependent::X`
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,31 @@
|
||||
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]);
|
||||
| ^ const parameters must have a concrete type
|
||||
|
||||
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[E0391]: cycle detected when computing type of `Dependent::X`
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:9:44
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
| ^
|
||||
|
|
||||
= note: ...which again requires computing type of `Dependent::X`, completing the cycle
|
||||
note: cycle used when computing type of `Dependent`
|
||||
--> $DIR/const-param-type-depends-on-const-param.rs:9:1
|
||||
|
|
||||
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
@ -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]>);
|
||||
| ^ const parameters must have a concrete type
|
||||
|
||||
error[E0658]: const generics are unstable
|
||||
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19
|
||||
|
|
||||
@ -7,15 +13,6 @@ 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.
|
||||
For more information about an error, try `rustc --explain E0658`.
|
||||
For more information about this 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]);
|
||||
| ^ const parameters must have a concrete type
|
||||
|
||||
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,14 @@ 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`.
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
|
@ -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) {
|
||||
| ^^^^ const parameters must have a concrete type
|
||||
|
||||
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),
|
||||
| ^^^^ const parameters must have a concrete type
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71381.rs:13:61
|
||||
|
|
||||
@ -5,10 +17,10 @@ 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
|
||||
|
||||
|
@ -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,14 @@
|
||||
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) {
|
||||
| ^ const parameters must have a concrete type
|
||||
|
||||
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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user