Skip to content

Commit 62c63fc

Browse files
committed
Hard error on hidden elided lifetimes in assoc consts
1 parent 01aac17 commit 62c63fc

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| {
@@ -2224,7 +2235,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22242235
//
22252236
// impl Foo for std::cell::Ref<u32> // note lack of '_
22262237
// async fn foo(_: std::cell::Ref<u32>) { ... }
2227-
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. } => {
2238+
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
2239+
| LifetimeRibKind::StaticUnlessHidden => {
22282240
let sess = self.r.tcx.sess;
22292241
let subdiag = elided_lifetime_in_path_suggestion(
22302242
sess.source_map(),
@@ -3298,36 +3310,33 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
32983310
LifetimeBinderKind::ConstItem,
32993311
generics.span,
33003312
|this| {
3301-
this.with_lifetime_rib(
3302-
LifetimeRibKind::Elided(LifetimeRes::Static),
3303-
|this| {
3304-
this.visit_generics(generics);
3305-
if rhs_kind.is_type_const()
3306-
&& !this.r.tcx.features().generic_const_parameter_types()
3307-
{
3308-
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3309-
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3310-
this.with_lifetime_rib(
3311-
LifetimeRibKind::ConstParamTy,
3312-
|this| this.visit_ty(ty),
3313-
)
3314-
})
3315-
});
3316-
} else {
3317-
this.visit_ty(ty);
3318-
}
3313+
this.with_lifetime_rib(LifetimeRibKind::StaticUnlessHidden, |this| {
3314+
this.visit_generics(generics);
3315+
if rhs_kind.is_type_const()
3316+
&& !this.r.tcx.features().generic_const_parameter_types()
3317+
{
3318+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3319+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3320+
this.with_lifetime_rib(
3321+
LifetimeRibKind::ConstParamTy,
3322+
|this| this.visit_ty(ty),
3323+
)
3324+
})
3325+
});
3326+
} else {
3327+
this.visit_ty(ty);
3328+
}
33193329

3320-
// Only impose the restrictions of `ConstRibKind` for an
3321-
// actual constant expression in a provided default.
3322-
//
3323-
// We allow arbitrary const expressions inside of associated consts,
3324-
// even if they are potentially not const evaluatable.
3325-
//
3326-
// Type parameters can already be used and as associated consts are
3327-
// not used as part of the type system, this is far less surprising.
3328-
this.resolve_const_item_rhs(rhs_kind, None);
3329-
},
3330-
)
3330+
// Only impose the restrictions of `ConstRibKind` for an
3331+
// actual constant expression in a provided default.
3332+
//
3333+
// We allow arbitrary const expressions inside of associated consts,
3334+
// even if they are potentially not const evaluatable.
3335+
//
3336+
// Type parameters can already be used and as associated consts are
3337+
// not used as part of the type system, this is far less surprising.
3338+
this.resolve_const_item_rhs(rhs_kind, None);
3339+
})
33313340
},
33323341
);
33333342

@@ -3514,45 +3523,42 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35143523
LifetimeBinderKind::ConstItem,
35153524
generics.span,
35163525
|this| {
3517-
this.with_lifetime_rib(
3518-
LifetimeRibKind::Elided(LifetimeRes::Static),
3519-
|this| {
3520-
// If this is a trait impl, ensure the const
3521-
// exists in trait
3522-
this.check_trait_item(
3523-
item.id,
3524-
*ident,
3525-
*ident,
3526-
&item.kind,
3527-
ValueNS,
3528-
item.span,
3529-
seen_trait_items,
3530-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3531-
);
3526+
this.with_lifetime_rib(LifetimeRibKind::StaticUnlessHidden, |this| {
3527+
// If this is a trait impl, ensure the const
3528+
// exists in trait
3529+
this.check_trait_item(
3530+
item.id,
3531+
*ident,
3532+
*ident,
3533+
&item.kind,
3534+
ValueNS,
3535+
item.span,
3536+
seen_trait_items,
3537+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3538+
);
35323539

3533-
this.visit_generics(generics);
3534-
if rhs_kind.is_type_const()
3535-
&& !this.r.tcx.features().generic_const_parameter_types()
3536-
{
3537-
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3538-
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3539-
this.with_lifetime_rib(
3540-
LifetimeRibKind::ConstParamTy,
3541-
|this| this.visit_ty(ty),
3542-
)
3543-
})
3544-
});
3545-
} else {
3546-
this.visit_ty(ty);
3547-
}
3548-
// We allow arbitrary const expressions inside of associated consts,
3549-
// even if they are potentially not const evaluatable.
3550-
//
3551-
// Type parameters can already be used and as associated consts are
3552-
// not used as part of the type system, this is far less surprising.
3553-
this.resolve_const_item_rhs(rhs_kind, None);
3554-
},
3555-
)
3540+
this.visit_generics(generics);
3541+
if rhs_kind.is_type_const()
3542+
&& !this.r.tcx.features().generic_const_parameter_types()
3543+
{
3544+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3545+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3546+
this.with_lifetime_rib(
3547+
LifetimeRibKind::ConstParamTy,
3548+
|this| this.visit_ty(ty),
3549+
)
3550+
})
3551+
});
3552+
} else {
3553+
this.visit_ty(ty);
3554+
}
3555+
// We allow arbitrary const expressions inside of associated consts,
3556+
// even if they are potentially not const evaluatable.
3557+
//
3558+
// Type parameters can already be used and as associated consts are
3559+
// not used as part of the type system, this is far less surprising.
3560+
this.resolve_const_item_rhs(rhs_kind, None);
3561+
})
35563562
},
35573563
);
35583564
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)