From 37c29adabc638f9c601daf5b78d0f6de63e35f99 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 5 Aug 2020 18:59:53 +0200 Subject: [PATCH] allow complex expressions in assoc consts --- src/librustc_resolve/late.rs | 34 +++++++++---------- .../min_const_generics/assoc_const.rs | 18 ++++++++++ .../min_const_generics/complex-expression.rs | 8 ----- .../complex-expression.stderr | 10 +----- 4 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/const-generics/min_const_generics/assoc_const.rs diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 853085fbc00..b5fc69f9f31 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -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. diff --git a/src/test/ui/const-generics/min_const_generics/assoc_const.rs b/src/test/ui/const-generics/min_const_generics/assoc_const.rs new file mode 100644 index 00000000000..fa75613d9dd --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/assoc_const.rs @@ -0,0 +1,18 @@ +// check-pass +#![feature(min_const_generics)] + +struct Foo; + +impl Foo { + const VALUE: usize = N * 2; +} + +trait Bar { + const ASSOC: usize; +} + +impl Bar for Foo { + const ASSOC: usize = N * 3; +} + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs index 201af9fcef3..f9cb0d2829d 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-expression.rs +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs @@ -26,12 +26,4 @@ trait Foo { const ASSOC: usize; } -impl 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() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr index 03857aee076..baed8d13f00 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr @@ -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