Skip to content

Commit bd04093

Browse files
committed
Hard error on hidden elided lifetimes in assoc consts
1 parent 6eeeb9d commit bd04093

4 files changed

Lines changed: 127 additions & 73 deletions

File tree

compiler/rustc_resolve/src/late.rs

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,10 @@ enum LifetimeRibKind {
342342
/// error on default object bounds (e.g., `Box<dyn Foo>`).
343343
AnonymousReportError,
344344

345+
/// Errors on hidden lifetimes like in `struct S<'a>(&'a()); fn foo(s: S) {}`
346+
/// `&` or `'_` lifetimes get elided to `'static`.
347+
StaticUnlessHidden,
348+
345349
/// Signal we cannot find which should be the anonymous lifetime.
346350
ElisionFailure,
347351

@@ -1368,6 +1372,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
13681372
}
13691373
LifetimeRibKind::AnonymousCreateParameter { .. }
13701374
| LifetimeRibKind::AnonymousReportError
1375+
| LifetimeRibKind::StaticUnlessHidden
13711376
| LifetimeRibKind::ImplTrait
13721377
| LifetimeRibKind::Elided(_)
13731378
| LifetimeRibKind::ElisionFailure
@@ -1773,6 +1778,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
17731778
// lifetime would be illegal.
17741779
LifetimeRibKind::Item
17751780
| LifetimeRibKind::AnonymousReportError
1781+
| LifetimeRibKind::StaticUnlessHidden
17761782
| LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
17771783
// An anonymous lifetime is legal here, and bound to the right
17781784
// place, go ahead.
@@ -1836,7 +1842,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18361842
| LifetimeRibKind::Generics { .. }
18371843
| LifetimeRibKind::ElisionFailure
18381844
| LifetimeRibKind::AnonymousReportError
1839-
| LifetimeRibKind::ImplTrait => {}
1845+
| LifetimeRibKind::ImplTrait
1846+
| LifetimeRibKind::StaticUnlessHidden => {}
18401847
}
18411848
}
18421849

@@ -1875,6 +1882,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18751882
self.record_lifetime_use(lifetime.id, res, elision_candidate);
18761883
return;
18771884
}
1885+
LifetimeRibKind::StaticUnlessHidden => {
1886+
self.record_lifetime_use(lifetime.id, LifetimeRes::Static, elision_candidate);
1887+
return;
1888+
}
18781889
LifetimeRibKind::AnonymousReportError => {
18791890
let guar = if elided {
18801891
let suggestion = self.lifetime_ribs[i..].iter().rev().find_map(|rib| {
@@ -2230,7 +2241,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22302241
//
22312242
// impl Foo for std::cell::Ref<u32> // note lack of '_
22322243
// async fn foo(_: std::cell::Ref<u32>) { ... }
2233-
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } => {
2244+
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
2245+
| LifetimeRibKind::StaticUnlessHidden => {
22342246
let sess = self.r.tcx.sess;
22352247
let subdiag = elided_lifetime_in_path_suggestion(
22362248
sess.source_map(),
@@ -3313,36 +3325,33 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33133325
LifetimeBinderKind::ConstItem,
33143326
generics.span,
33153327
|this| {
3316-
this.with_lifetime_rib(
3317-
LifetimeRibKind::Elided(LifetimeRes::Static),
3318-
|this| {
3319-
this.visit_generics(generics);
3320-
if rhs_kind.is_type_const()
3321-
&& !this.r.tcx.features().generic_const_parameter_types()
3322-
{
3323-
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3324-
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3325-
this.with_lifetime_rib(
3326-
LifetimeRibKind::ConstParamTy,
3327-
|this| this.visit_ty(ty),
3328-
)
3329-
})
3330-
});
3331-
} else {
3332-
this.visit_ty(ty);
3333-
}
3328+
this.with_lifetime_rib(LifetimeRibKind::StaticUnlessHidden, |this| {
3329+
this.visit_generics(generics);
3330+
if rhs_kind.is_type_const()
3331+
&& !this.r.tcx.features().generic_const_parameter_types()
3332+
{
3333+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3334+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3335+
this.with_lifetime_rib(
3336+
LifetimeRibKind::ConstParamTy,
3337+
|this| this.visit_ty(ty),
3338+
)
3339+
})
3340+
});
3341+
} else {
3342+
this.visit_ty(ty);
3343+
}
33343344

3335-
// Only impose the restrictions of `ConstRibKind` for an
3336-
// actual constant expression in a provided default.
3337-
//
3338-
// We allow arbitrary const expressions inside of associated consts,
3339-
// even if they are potentially not const evaluatable.
3340-
//
3341-
// Type parameters can already be used and as associated consts are
3342-
// not used as part of the type system, this is far less surprising.
3343-
this.resolve_const_item_rhs(rhs_kind, None);
3344-
},
3345-
)
3345+
// Only impose the restrictions of `ConstRibKind` for an
3346+
// actual constant expression in a provided default.
3347+
//
3348+
// We allow arbitrary const expressions inside of associated consts,
3349+
// even if they are potentially not const evaluatable.
3350+
//
3351+
// Type parameters can already be used and as associated consts are
3352+
// not used as part of the type system, this is far less surprising.
3353+
this.resolve_const_item_rhs(rhs_kind, None);
3354+
})
33463355
},
33473356
);
33483357

@@ -3529,45 +3538,42 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35293538
LifetimeBinderKind::ConstItem,
35303539
generics.span,
35313540
|this| {
3532-
this.with_lifetime_rib(
3533-
LifetimeRibKind::Elided(LifetimeRes::Static),
3534-
|this| {
3535-
// If this is a trait impl, ensure the const
3536-
// exists in trait
3537-
this.check_trait_item(
3538-
item.id,
3539-
*ident,
3540-
*ident,
3541-
&item.kind,
3542-
ValueNS,
3543-
item.span,
3544-
seen_trait_items,
3545-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3546-
);
3541+
this.with_lifetime_rib(LifetimeRibKind::StaticUnlessHidden, |this| {
3542+
// If this is a trait impl, ensure the const
3543+
// exists in trait
3544+
this.check_trait_item(
3545+
item.id,
3546+
*ident,
3547+
*ident,
3548+
&item.kind,
3549+
ValueNS,
3550+
item.span,
3551+
seen_trait_items,
3552+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3553+
);
35473554

3548-
this.visit_generics(generics);
3549-
if rhs_kind.is_type_const()
3550-
&& !this.r.tcx.features().generic_const_parameter_types()
3551-
{
3552-
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3553-
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3554-
this.with_lifetime_rib(
3555-
LifetimeRibKind::ConstParamTy,
3556-
|this| this.visit_ty(ty),
3557-
)
3558-
})
3559-
});
3560-
} else {
3561-
this.visit_ty(ty);
3562-
}
3563-
// We allow arbitrary const expressions inside of associated consts,
3564-
// even if they are potentially not const evaluatable.
3565-
//
3566-
// Type parameters can already be used and as associated consts are
3567-
// not used as part of the type system, this is far less surprising.
3568-
this.resolve_const_item_rhs(rhs_kind, None);
3569-
},
3570-
)
3555+
this.visit_generics(generics);
3556+
if rhs_kind.is_type_const()
3557+
&& !this.r.tcx.features().generic_const_parameter_types()
3558+
{
3559+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3560+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3561+
this.with_lifetime_rib(
3562+
LifetimeRibKind::ConstParamTy,
3563+
|this| this.visit_ty(ty),
3564+
)
3565+
})
3566+
});
3567+
} else {
3568+
this.visit_ty(ty);
3569+
}
3570+
// We allow arbitrary const expressions inside of associated consts,
3571+
// even if they are potentially not const evaluatable.
3572+
//
3573+
// Type parameters can already be used and as associated consts are
3574+
// not used as part of the type system, this is far less surprising.
3575+
this.resolve_const_item_rhs(rhs_kind, None);
3576+
})
35713577
},
35723578
);
35733579
self.resolve_define_opaques(define_opaque);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0726]: implicit elided lifetime not allowed here
2+
--> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
3+
|
4+
LL | const B: S = S { s: &() };
5+
| ^ expected lifetime parameter
6+
|
7+
help: indicate the anonymous lifetime
8+
|
9+
LL | const B: S<'_> = S { s: &() };
10+
| ++++
11+
12+
error[E0726]: implicit elided lifetime not allowed here
13+
--> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
14+
|
15+
LL | const D: T = T { a: &(), b: &() };
16+
| ^ expected lifetime parameters
17+
|
18+
help: indicate the anonymous lifetimes
19+
|
20+
LL | const D: T<'_, '_> = T { a: &(), b: &() };
21+
| ++++++++
22+
23+
error: aborting due to 2 previous errors
24+
25+
For more information about this error, try `rustc --explain E0726`.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0726]: implicit elided lifetime not allowed here
2+
--> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
3+
|
4+
LL | const B: S = S { s: &() };
5+
| ^ expected lifetime parameter
6+
|
7+
help: indicate the anonymous lifetime
8+
|
9+
LL | const B: S<'_> = S { s: &() };
10+
| ++++
11+
12+
error[E0726]: implicit elided lifetime not allowed here
13+
--> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
14+
|
15+
LL | const D: T = T { a: &(), b: &() };
16+
| ^ expected lifetime parameters
17+
|
18+
help: indicate the anonymous lifetimes
19+
|
20+
LL | const D: T<'_, '_> = T { a: &(), b: &() };
21+
| ++++++++
22+
23+
error: aborting due to 2 previous errors
24+
25+
For more information about this error, try `rustc --explain E0726`.

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
//@ check-pass
2-
31
//@ revisions: default generic_const_items
42

53
#![cfg_attr(generic_const_items, feature(generic_const_items), allow(incomplete_features))]
64

75
trait ZstAssert: Sized {
86
const A: &str = "";
9-
const B: S = S { s: &() };
7+
const B: S = S { s: &() }; //~ ERROR implicit elided lifetime not allowed here
108
const C: &'_ str = "";
11-
const D: T = T { a: &(), b: &() };
9+
const D: T = T { a: &(), b: &() }; //~ ERROR implicit elided lifetime not allowed here
1210
}
1311

1412
const A: &str = "";

0 commit comments

Comments
 (0)