Skip to content

Commit f575aa5

Browse files
Explicitly deny elided lifetimes in associated consts
1 parent 180dffb commit f575aa5

8 files changed

+83
-73
lines changed

compiler/rustc_resolve/src/late.rs

+38-35
Original file line numberDiff line numberDiff line change
@@ -2727,19 +2727,21 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
27272727
kind: LifetimeBinderKind::ConstItem,
27282728
},
27292729
|this| {
2730-
this.visit_generics(generics);
2731-
this.visit_ty(ty);
2732-
2733-
// Only impose the restrictions of `ConstRibKind` for an
2734-
// actual constant expression in a provided default.
2735-
if let Some(expr) = expr {
2736-
// We allow arbitrary const expressions inside of associated consts,
2737-
// even if they are potentially not const evaluatable.
2738-
//
2739-
// Type parameters can already be used and as associated consts are
2740-
// not used as part of the type system, this is far less surprising.
2741-
this.resolve_const_body(expr, None);
2742-
}
2730+
this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
2731+
this.visit_generics(generics);
2732+
this.visit_ty(ty);
2733+
2734+
// Only impose the restrictions of `ConstRibKind` for an
2735+
// actual constant expression in a provided default.
2736+
if let Some(expr) = expr {
2737+
// We allow arbitrary const expressions inside of associated consts,
2738+
// even if they are potentially not const evaluatable.
2739+
//
2740+
// Type parameters can already be used and as associated consts are
2741+
// not used as part of the type system, this is far less surprising.
2742+
this.resolve_const_body(expr, None);
2743+
}
2744+
});
27432745
},
27442746
);
27452747
}
@@ -2898,7 +2900,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
28982900
match &item.kind {
28992901
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
29002902
debug!("resolve_implementation AssocItemKind::Const");
2901-
29022903
self.with_generic_param_rib(
29032904
&generics.params,
29042905
RibKind::AssocItem,
@@ -2908,28 +2909,30 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
29082909
kind: LifetimeBinderKind::ConstItem,
29092910
},
29102911
|this| {
2911-
// If this is a trait impl, ensure the const
2912-
// exists in trait
2913-
this.check_trait_item(
2914-
item.id,
2915-
item.ident,
2916-
&item.kind,
2917-
ValueNS,
2918-
item.span,
2919-
seen_trait_items,
2920-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
2921-
);
2912+
this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
2913+
// If this is a trait impl, ensure the const
2914+
// exists in trait
2915+
this.check_trait_item(
2916+
item.id,
2917+
item.ident,
2918+
&item.kind,
2919+
ValueNS,
2920+
item.span,
2921+
seen_trait_items,
2922+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
2923+
);
29222924

2923-
this.visit_generics(generics);
2924-
this.visit_ty(ty);
2925-
if let Some(expr) = expr {
2926-
// We allow arbitrary const expressions inside of associated consts,
2927-
// even if they are potentially not const evaluatable.
2928-
//
2929-
// Type parameters can already be used and as associated consts are
2930-
// not used as part of the type system, this is far less surprising.
2931-
this.resolve_const_body(expr, None);
2932-
}
2925+
this.visit_generics(generics);
2926+
this.visit_ty(ty);
2927+
if let Some(expr) = expr {
2928+
// We allow arbitrary const expressions inside of associated consts,
2929+
// even if they are potentially not const evaluatable.
2930+
//
2931+
// Type parameters can already be used and as associated consts are
2932+
// not used as part of the type system, this is far less surprising.
2933+
this.resolve_const_body(expr, None);
2934+
}
2935+
});
29332936
},
29342937
);
29352938
}

tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ trait Trait {
55
impl Trait for () {
66
const ASSOC: &dyn Fn(_) = 1i32;
77
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
8+
//~| ERROR `&` without an explicit lifetime name cannot be used here
89
}
910

1011
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
error[E0637]: `&` without an explicit lifetime name cannot be used here
2+
--> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:18
3+
|
4+
LL | const ASSOC: &dyn Fn(_) = 1i32;
5+
| ^ explicit lifetime name needed here
6+
17
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
28
--> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26
39
|
410
LL | const ASSOC: &dyn Fn(_) = 1i32;
511
| ^ not allowed in type signatures
612

7-
error: aborting due to previous error
13+
error: aborting due to 2 previous errors
814

9-
For more information about this error, try `rustc --explain E0121`.
15+
Some errors have detailed explanations: E0121, E0637.
16+
For more information about an error, try `rustc --explain E0121`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::marker::PhantomData;
2+
3+
struct Foo<'a> {
4+
x: PhantomData<&'a ()>,
5+
}
6+
7+
impl<'a> Foo<'a> {
8+
const FOO: Foo<'_> = Foo { x: PhantomData::<&'a ()> };
9+
//~^ ERROR `'_` cannot be used here
10+
}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0637]: `'_` cannot be used here
2+
--> $DIR/assoc-const-elided-lifetime.rs:8:20
3+
|
4+
LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&'a ()> };
5+
| ^^ `'_` is a reserved lifetime name
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0637`.
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
error[E0106]: missing lifetime specifier
1+
error[E0637]: `&` without an explicit lifetime name cannot be used here
22
--> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14
33
|
44
LL | const A: &str = "";
5-
| ^ expected named lifetime parameter
6-
|
7-
help: consider introducing a named lifetime parameter
8-
|
9-
LL ~ trait ZstAssert<'a>: Sized {
10-
LL ~ const A: &'a str = "";
11-
|
5+
| ^ explicit lifetime name needed here
126

137
error[E0106]: missing lifetime specifier
148
--> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
@@ -23,19 +17,11 @@ LL | const A: &str = "";
2317
LL ~ const B: S<'a> = S { s: &() };
2418
|
2519

26-
error[E0106]: missing lifetime specifier
20+
error[E0637]: `'_` cannot be used here
2721
--> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15
2822
|
2923
LL | const C: &'_ str = "";
30-
| ^^ expected named lifetime parameter
31-
|
32-
help: consider introducing a named lifetime parameter
33-
|
34-
LL ~ trait ZstAssert<'a>: Sized {
35-
LL | const A: &str = "";
36-
LL | const B: S = S { s: &() };
37-
LL ~ const C: &'a str = "";
38-
|
24+
| ^^ `'_` is a reserved lifetime name
3925

4026
error[E0106]: missing lifetime specifiers
4127
--> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
@@ -54,4 +40,5 @@ LL ~ const D: T<'a, 'a> = T { a: &(), b: &() };
5440

5541
error: aborting due to 4 previous errors
5642

57-
For more information about this error, try `rustc --explain E0106`.
43+
Some errors have detailed explanations: E0106, E0637.
44+
For more information about an error, try `rustc --explain E0106`.
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
error[E0106]: missing lifetime specifier
1+
error[E0637]: `&` without an explicit lifetime name cannot be used here
22
--> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14
33
|
44
LL | const A: &str = "";
5-
| ^ expected named lifetime parameter
6-
|
7-
help: consider introducing a named lifetime parameter
8-
|
9-
LL | const A<'a>: &'a str = "";
10-
| ++++ ++
5+
| ^ explicit lifetime name needed here
116

127
error[E0106]: missing lifetime specifier
138
--> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
@@ -20,16 +15,11 @@ help: consider introducing a named lifetime parameter
2015
LL | const B<'a>: S<'a> = S { s: &() };
2116
| ++++ ++++
2217

23-
error[E0106]: missing lifetime specifier
18+
error[E0637]: `'_` cannot be used here
2419
--> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15
2520
|
2621
LL | const C: &'_ str = "";
27-
| ^^ expected named lifetime parameter
28-
|
29-
help: consider introducing a named lifetime parameter
30-
|
31-
LL | const C<'a>: &'a str = "";
32-
| ++++ ~~
22+
| ^^ `'_` is a reserved lifetime name
3323

3424
error[E0106]: missing lifetime specifiers
3525
--> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
@@ -44,4 +34,5 @@ LL | const D<'a>: T<'a, 'a> = T { a: &(), b: &() };
4434

4535
error: aborting due to 4 previous errors
4636

47-
For more information about this error, try `rustc --explain E0106`.
37+
Some errors have detailed explanations: E0106, E0637.
38+
For more information about an error, try `rustc --explain E0106`.

tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
#![cfg_attr(generic_const_items, feature(generic_const_items), allow(incomplete_features))]
44

55
trait ZstAssert: Sized {
6-
const A: &str = ""; //~ ERROR missing lifetime specifier
6+
const A: &str = ""; //~ ERROR `&` without an explicit lifetime name cannot be used here
77
const B: S = S { s: &() }; //~ ERROR missing lifetime specifier
8-
const C: &'_ str = ""; //~ ERROR missing lifetime specifier
8+
const C: &'_ str = ""; //~ ERROR `'_` cannot be used here
99
const D: T = T { a: &(), b: &() }; //~ ERROR missing lifetime specifier
1010
}
1111

0 commit comments

Comments
 (0)