allow complex expressions in assoc consts

This commit is contained in:
Bastian Kauschke 2020-08-05 18:59:53 +02:00
parent 0d54f571c1
commit 37c29adabc
4 changed files with 36 additions and 34 deletions

View File

@ -948,10 +948,14 @@ fn resolve_item(&mut self, item: &'ast Item) {
// Only impose the restrictions of `ConstRibKind` for an
// actual constant expression in a provided default.
if let Some(expr) = default {
this.with_constant_rib(
expr.is_potential_trivial_const_param(),
|this| this.visit_expr(expr),
);
// We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable.
//
// Type parameters can already be used and as associated consts are
// not used as part of the type system, this is far less surprising.
this.with_constant_rib(true, |this| {
this.visit_expr(expr)
});
}
}
AssocItemKind::Fn(_, _, generics, _) => {
@ -1225,7 +1229,7 @@ fn resolve_implementation(
for item in impl_items {
use crate::ResolutionError::*;
match &item.kind {
AssocItemKind::Const(_default, _ty, expr) => {
AssocItemKind::Const(_default, _ty, _expr) => {
debug!("resolve_implementation AssocItemKind::Const",);
// If this is a trait impl, ensure the const
// exists in trait
@ -1236,18 +1240,14 @@ fn resolve_implementation(
|n, s| ConstNotMemberOfTrait(n, s),
);
this.with_constant_rib(
expr.as_ref().map_or(false, |e| {
e.is_potential_trivial_const_param()
}),
|this| {
visit::walk_assoc_item(
this,
item,
AssocCtxt::Impl,
)
},
);
// We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable.
//
// Type parameters can already be used and as associated consts are
// not used as part of the type system, this is far less surprising.
this.with_constant_rib(true, |this| {
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
});
}
AssocItemKind::Fn(_, _, generics, _) => {
// We also need a new scope for the impl item type parameters.

View File

@ -0,0 +1,18 @@
// check-pass
#![feature(min_const_generics)]
struct Foo<const N: usize>;
impl<const N: usize> Foo<N> {
const VALUE: usize = N * 2;
}
trait Bar {
const ASSOC: usize;
}
impl<const N: usize> Bar for Foo<N> {
const ASSOC: usize = N * 3;
}
fn main() {}

View File

@ -26,12 +26,4 @@ trait Foo {
const ASSOC: usize;
}
impl<const N: usize> Foo for [u8; N] {
const ASSOC: usize = N + 1;
//~^ ERROR generic parameters must not be used inside of non trivial constant values
// FIXME(min_const_generics): We probably have to allow this as we can
// already allow referencing type parameters here on stable.
}
fn main() {}

View File

@ -30,13 +30,5 @@ LL | let _ = [0; N + 1];
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: generic parameters must not be used inside of non trivial constant values
--> $DIR/complex-expression.rs:30:26
|
LL | const ASSOC: usize = N + 1;
| ^ non-trivial anonymous constants must not depend on the parameter `N`
|
= help: it is currently only allowed to use either `N` or `{ N }` as generic constants
error: aborting due to 5 previous errors
error: aborting due to 4 previous errors