From a87ab480999e21de80b12ad6de6a777c70bebaab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 5 Dec 2021 00:07:21 +0100 Subject: [PATCH 1/4] Ban non-static in const generics in AST. --- compiler/rustc_resolve/src/late.rs | 23 ++++++++++--- .../rustc_resolve/src/late/diagnostics.rs | 33 +++++++++---------- compiler/rustc_resolve/src/late/lifetimes.rs | 11 ------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9ea66c0b59d9f..f5e8eca8fcb2e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -199,6 +199,11 @@ enum LifetimeRibKind { /// This rib declares generic parameters. Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind }, + /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const + /// generics. We are disallowing this until we can decide on how we want to handle non-'static + /// lifetimes in const generics. See issue #74052 for discussion. + ConstGeneric, + /// For **Modern** cases, create a new anonymous region parameter /// and reference that. /// @@ -1102,14 +1107,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind)); this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind)); - this.visit_ty(ty); + this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { + this.visit_ty(ty) + }); this.ribs[TypeNS].pop().unwrap(); this.ribs[ValueNS].pop().unwrap(); if let Some(ref expr) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); - this.visit_anon_const(expr); + this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { + this.visit_anon_const(expr) + }); forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap(); } @@ -1158,8 +1167,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { return; } - if let LifetimeRibKind::Item = rib.kind { - break; + match rib.kind { + LifetimeRibKind::Item => break, + LifetimeRibKind::ConstGeneric => { + self.emit_non_static_lt_in_const_generic_error(lifetime); + self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); + return; + } + _ => {} } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a9edb713b0da7..b153c9f95267f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1886,6 +1886,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.emit(); } + + crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) { + struct_span_err!( + self.r.session, + lifetime_ref.ident.span, + E0771, + "use of non-static lifetime `{}` in const generic", + lifetime_ref.ident + ) + .note( + "for more information, see issue #74052 \ + ", + ) + .emit(); + } } impl<'tcx> LifetimeContext<'_, 'tcx> { @@ -1982,24 +1997,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { } } - // FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const - // generics. We are disallowing this until we can decide on how we want to handle non-'static - // lifetimes in const generics. See issue #74052 for discussion. - crate fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &hir::Lifetime) { - let mut err = struct_span_err!( - self.tcx.sess, - lifetime_ref.span, - E0771, - "use of non-static lifetime `{}` in const generic", - lifetime_ref - ); - err.note( - "for more information, see issue #74052 \ - ", - ); - err.emit(); - } - crate fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool { if let def::Res::Def(_, did) = trait_ref.trait_ref.path.res { if [ diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index ce3069265d020..6bb0c3b5e6b59 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -164,8 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> { map: &'a mut NamedRegionMap, scope: ScopeRef<'a>, - is_in_const_generic: bool, - /// Indicates that we only care about the definition of a trait. This should /// be false if the `Item` we are resolving lifetimes for is not a trait or /// we eventually need lifetimes resolve for trait items. @@ -452,7 +450,6 @@ fn do_resolve( tcx, map: &mut named_region_map, scope: ROOT_SCOPE, - is_in_const_generic: false, trait_definition_only, labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), @@ -1266,10 +1263,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, Region::Static); return; } - if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error { - self.emit_non_static_lt_in_const_generic_error(lifetime_ref); - return; - } self.resolve_lifetime_ref(lifetime_ref); } @@ -1341,14 +1334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } GenericParamKind::Const { ref ty, default } => { - let was_in_const_generic = this.is_in_const_generic; - this.is_in_const_generic = true; walk_list!(this, visit_param_bound, param.bounds); this.visit_ty(&ty); if let Some(default) = default { this.visit_body(this.tcx.hir().body(default.body)); } - this.is_in_const_generic = was_in_const_generic; } } } @@ -1798,7 +1788,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { tcx: *tcx, map, scope: &wrap_scope, - is_in_const_generic: self.is_in_const_generic, trait_definition_only: self.trait_definition_only, labels_in_fn, xcrate_object_lifetime_defaults, From b711723d415bdadb3b1a6cc2458f05480c06b49b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Dec 2021 22:51:39 +0100 Subject: [PATCH 2/4] Bless tests. --- .../issues/issue-56445-1.min.stderr | 11 ++++++++++- .../ui/const-generics/issues/issue-56445-1.rs | 1 + src/test/ui/error-codes/E0771.stderr | 16 ++++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr index 179643a755293..43a5df117fdc7 100644 --- a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr @@ -6,6 +6,15 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | = note: for more information, see issue #74052 -error: aborting due to previous error +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-56445-1.rs:9:25 + | +LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); + | ^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/const-generics/issues/issue-56445-1.rs b/src/test/ui/const-generics/issues/issue-56445-1.rs index aeef778991f06..13eb2ea9f69d5 100644 --- a/src/test/ui/const-generics/issues/issue-56445-1.rs +++ b/src/test/ui/const-generics/issues/issue-56445-1.rs @@ -8,5 +8,6 @@ use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); //~^ ERROR: use of non-static lifetime `'a` in const generic +//[min]~| ERROR: `&'static str` is forbidden as the type of a const generic parameter impl Bug<'_, ""> {} diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr index 5a16d5845a60e..3ab727f5f69da 100644 --- a/src/test/ui/error-codes/E0771.stderr +++ b/src/test/ui/error-codes/E0771.stderr @@ -1,3 +1,11 @@ +error[E0771]: use of non-static lifetime `'a` in const generic + --> $DIR/E0771.rs:4:41 + | +LL | fn function_with_str<'a, const STRING: &'a str>() {} + | ^^ + | + = note: for more information, see issue #74052 + warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/E0771.rs:1:12 | @@ -7,14 +15,6 @@ LL | #![feature(adt_const_params)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 for more information -error[E0771]: use of non-static lifetime `'a` in const generic - --> $DIR/E0771.rs:4:41 - | -LL | fn function_with_str<'a, const STRING: &'a str>() {} - | ^^ - | - = note: for more information, see issue #74052 - error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0771`. From 865d0fef2f49de54c89132672946cefb8b8a8f10 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 31 Mar 2022 20:10:37 +0200 Subject: [PATCH 3/4] Ban non-static lifetimes from AnonConst on AST. The extra diagnostics come from the compiler no longer aborting before typeck. --- compiler/rustc_resolve/src/late.rs | 27 +++++++++--- .../rustc_resolve/src/late/diagnostics.rs | 44 +++++++------------ compiler/rustc_resolve/src/late/lifetimes.rs | 4 -- 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f5e8eca8fcb2e..9622553319d95 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -204,6 +204,11 @@ enum LifetimeRibKind { /// lifetimes in const generics. See issue #74052 for discussion. ConstGeneric, + /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. + /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by + /// `body_id` is an anonymous constant and `lifetime_ref` is non-static. + AnonConst, + /// For **Modern** cases, create a new anonymous region parameter /// and reference that. /// @@ -532,7 +537,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } fn visit_anon_const(&mut self, constant: &'ast AnonConst) { // We deal with repeat expressions explicitly in `resolve_expr`. - self.resolve_anon_const(constant, IsRepeatExpr::No); + self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { + this.resolve_anon_const(constant, IsRepeatExpr::No); + }) } fn visit_expr(&mut self, expr: &'ast Expr) { self.resolve_expr(expr, None); @@ -1117,7 +1124,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { - this.visit_anon_const(expr) + this.resolve_anon_const(expr, IsRepeatExpr::No) }); forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap(); @@ -1174,6 +1181,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); return; } + LifetimeRibKind::AnonConst => { + self.maybe_emit_forbidden_non_static_lifetime_error(lifetime); + self.r.lifetimes_res_map.insert(lifetime.id, LifetimeRes::Error); + return; + } _ => {} } } @@ -3076,9 +3088,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { is_repeat, constant.value.is_potential_trivial_const_param(), None, - |this| { - visit::walk_anon_const(this, constant); - }, + |this| visit::walk_anon_const(this, constant), ); } @@ -3229,7 +3239,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } ExprKind::Repeat(ref elem, ref ct) => { self.visit_expr(elem); - self.resolve_anon_const(ct, IsRepeatExpr::Yes); + self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { + this.resolve_anon_const(ct, IsRepeatExpr::Yes) + }); + } + ExprKind::ConstBlock(ref ct) => { + self.resolve_anon_const(ct, IsRepeatExpr::No); } ExprKind::Index(ref elem, ref idx) => { self.resolve_expr(elem, Some(expr)); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b153c9f95267f..894ff0f17f8a1 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1901,6 +1901,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ) .emit(); } + + /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. + /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by + /// `body_id` is an anonymous constant and `lifetime_ref` is non-static. + crate fn maybe_emit_forbidden_non_static_lifetime_error(&self, lifetime_ref: &ast::Lifetime) { + let feature_active = self.r.session.features_untracked().generic_const_exprs; + if !feature_active { + feature_err( + &self.r.session.parse_sess, + sym::generic_const_exprs, + lifetime_ref.ident.span, + "a non-static lifetime is not allowed in a `const`", + ) + .emit(); + } + } } impl<'tcx> LifetimeContext<'_, 'tcx> { @@ -2398,32 +2414,4 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { _ => unreachable!(), } } - - /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. - /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by - /// `body_id` is an anonymous constant and `lifetime_ref` is non-static. - crate fn maybe_emit_forbidden_non_static_lifetime_error( - &self, - body_id: hir::BodyId, - lifetime_ref: &'tcx hir::Lifetime, - ) { - let is_anon_const = matches!( - self.tcx.def_kind(self.tcx.hir().body_owner_def_id(body_id)), - hir::def::DefKind::AnonConst - ); - let is_allowed_lifetime = matches!( - lifetime_ref.name, - hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore - ); - - if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime { - feature_err( - &self.tcx.sess.parse_sess, - sym::generic_const_exprs, - lifetime_ref.span, - "a non-static lifetime is not allowed in a `const`", - ) - .emit(); - } - } } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 6bb0c3b5e6b59..35a40a0a32131 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2243,10 +2243,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let result = loop { match *scope { Scope::Body { id, s } => { - // Non-static lifetimes are prohibited in anonymous constants without - // `generic_const_exprs`. - self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref); - outermost_body = Some(id); scope = s; } From 7d990a8c1838a18c54a4b8a9f5fe74ea507ecbb3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 31 Mar 2022 20:11:22 +0200 Subject: [PATCH 4/4] Bless tests. --- .../const-arg-in-const-arg.min.stderr | 275 ++++++++++++++---- .../const-generics/const-arg-in-const-arg.rs | 17 +- 2 files changed, 225 insertions(+), 67 deletions(-) diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr index ac693426fbd98..88d9ed46e1ad3 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -16,53 +16,8 @@ LL | let _: [u8; bar::()]; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:24:23 - | -LL | let _ = [0; bar::()]; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:29:24 - | -LL | let _: Foo<{ foo::() }>; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:24 - | -LL | let _: Foo<{ bar::() }>; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:27 - | -LL | let _ = Foo::<{ foo::() }>; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:36:27 - | -LL | let _ = Foo::<{ bar::() }>; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:15:23 + --> $DIR/const-arg-in-const-arg.rs:16:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -71,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:16:23 + --> $DIR/const-arg-in-const-arg.rs:18:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ @@ -80,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:17:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -89,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ @@ -97,8 +52,17 @@ LL | let _: [u8; baz::<'b>(&())]; = note: see issue #76560 for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:24:23 + | +LL | let _ = [0; bar::()]; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:25:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -107,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ @@ -116,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:29:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -125,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ @@ -133,8 +97,26 @@ LL | let _ = [0; baz::<'b>(&())]; = note: see issue #76560 for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:32:24 + | +LL | let _: Foo<{ foo::() }>; + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:33:24 + | +LL | let _: Foo<{ bar::() }>; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:31:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -143,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:32:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ @@ -152,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:33:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -161,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:34:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ @@ -169,8 +151,26 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = note: see issue #76560 for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:41:27 + | +LL | let _ = Foo::<{ foo::() }>; + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:42:27 + | +LL | let _ = Foo::<{ bar::() }>; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:37:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:38:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:39:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:40:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ @@ -205,6 +205,155 @@ LL | let _ = Foo::<{ baz::<'b>(&()) }>; = note: see issue #76560 for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable -error: aborting due to 23 previous errors +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:14:23 + | +LL | let _: [u8; bar::()]; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: [u8; bar::<{ N }>()]; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:16:23 + | +LL | let _: [u8; faz::<'a>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:19:23 + | +LL | let _: [u8; faz::<'b>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:24:23 + | +LL | let _ = [0; bar::()]; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _ = [0; bar::<{ N }>()]; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:26:23 + | +LL | let _ = [0; faz::<'a>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:29:23 + | +LL | let _ = [0; faz::<'b>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:33:24 + | +LL | let _: Foo<{ bar::() }>; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: Foo<{ bar::<{ N }>() }>; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:35:24 + | +LL | let _: Foo<{ faz::<'a>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:38:24 + | +LL | let _: Foo<{ faz::<'b>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: constant expression depends on a generic parameter + --> $DIR/const-arg-in-const-arg.rs:23:17 + | +LL | let _ = [0; foo::()]; + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:42:27 + | +LL | let _ = Foo::<{ bar::() }>; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _ = Foo::<{ bar::<{ N }>() }>; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:44:27 + | +LL | let _ = Foo::<{ faz::<'a>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:47:27 + | +LL | let _ = Foo::<{ faz::<'b>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: aborting due to 36 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0658, E0747. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.rs b/src/test/ui/const-generics/const-arg-in-const-arg.rs index 39f0b23733029..b9daadb547493 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.rs +++ b/src/test/ui/const-generics/const-arg-in-const-arg.rs @@ -12,31 +12,40 @@ struct Foo; fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::()]; //~ ERROR generic parameters may not let _: [u8; bar::()]; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _: [u8; faz::<'a>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //~ ERROR a non-static lifetime let _: [u8; faz::<'b>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'b>(&())]; //~ ERROR a non-static lifetime - // NOTE: This can be a future compat warning instead of an error, - // so we stop compilation before emitting this error in this test. - let _ = [0; foo::()]; - + let _ = [0; foo::()]; //~ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _ = [0; faz::<'a>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //~ ERROR a non-static lifetime let _ = [0; faz::<'b>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'b>(&())]; //~ ERROR a non-static lifetime let _: Foo<{ foo::() }>; //~ ERROR generic parameters may not let _: Foo<{ bar::() }>; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _: Foo<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime let _: Foo<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime let _ = Foo::<{ foo::() }>; //~ ERROR generic parameters may not let _ = Foo::<{ bar::() }>; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _ = Foo::<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime let _ = Foo::<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime }