Skip to content

Commit a92df8e

Browse files
committed
Turn elided_lifetimes_in_associated_constant FCW into a hard error
1 parent c8c4c83 commit a92df8e

12 files changed

Lines changed: 87 additions & 291 deletions

File tree

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ declare_lint_pass! {
4343
DEPRECATED_WHERE_CLAUSE_LOCATION,
4444
DUPLICATE_FEATURES,
4545
DUPLICATE_MACRO_ATTRIBUTES,
46-
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4746
ELIDED_LIFETIMES_IN_PATHS,
4847
EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
4948
EXPORTED_PRIVATE_DEPENDENCIES,
@@ -4909,48 +4908,6 @@ declare_lint! {
49094908
"impl trait in impl method signature does not match trait method signature",
49104909
}
49114910

4912-
declare_lint! {
4913-
/// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes
4914-
/// in associated constants when there are other lifetimes in scope. This was
4915-
/// accidentally supported, and this lint was later relaxed to allow eliding
4916-
/// lifetimes to `'static` when there are no lifetimes in scope.
4917-
///
4918-
/// ### Example
4919-
///
4920-
/// ```rust,compile_fail
4921-
/// #![deny(elided_lifetimes_in_associated_constant)]
4922-
///
4923-
/// struct Foo<'a>(&'a ());
4924-
///
4925-
/// impl<'a> Foo<'a> {
4926-
/// const STR: &str = "hello, world";
4927-
/// }
4928-
/// ```
4929-
///
4930-
/// {{produces}}
4931-
///
4932-
/// ### Explanation
4933-
///
4934-
/// Previous version of Rust
4935-
///
4936-
/// Implicit static-in-const behavior was decided [against] for associated
4937-
/// constants because of ambiguity. This, however, regressed and the compiler
4938-
/// erroneously treats elided lifetimes in associated constants as lifetime
4939-
/// parameters on the impl.
4940-
///
4941-
/// This is a [future-incompatible] lint to transition this to a
4942-
/// hard error in the future.
4943-
///
4944-
/// [against]: https://github.com/rust-lang/rust/issues/38831
4945-
/// [future-incompatible]: ../index.md#future-incompatible-lints
4946-
pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4947-
Deny,
4948-
"elided lifetimes cannot be used in associated constants in impls",
4949-
@future_incompatible = FutureIncompatibleInfo {
4950-
reason: fcw!(FutureReleaseError #115010),
4951-
};
4952-
}
4953-
49544911
declare_lint! {
49554912
/// The `private_macro_use` lint detects private macros that are imported
49564913
/// with `#[macro_use]`.

compiler/rustc_resolve/src/errors.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,28 +1661,6 @@ pub(crate) struct UnusedQualifications {
16611661
pub removal_span: Span,
16621662
}
16631663

1664-
#[derive(Diagnostic)]
1665-
#[diag(
1666-
"{$elided ->
1667-
[true] `&` without an explicit lifetime name cannot be used here
1668-
*[false] `'_` cannot be used here
1669-
}"
1670-
)]
1671-
pub(crate) struct AssociatedConstElidedLifetime {
1672-
#[suggestion(
1673-
"use the `'static` lifetime",
1674-
style = "verbose",
1675-
code = "{code}",
1676-
applicability = "machine-applicable"
1677-
)]
1678-
pub span: Span,
1679-
1680-
pub code: &'static str,
1681-
pub elided: bool,
1682-
#[note("cannot automatically infer `'static` because of other lifetimes in scope")]
1683-
pub lifetimes_in_scope: MultiSpan,
1684-
}
1685-
16861664
#[derive(Diagnostic)]
16871665
#[diag("lifetime parameter `{$ident}` only used once")]
16881666
pub(crate) struct SingleUseLifetime {

compiler/rustc_resolve/src/late.rs

Lines changed: 40 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ enum LifetimeRibKind {
345345
/// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
346346
/// otherwise give a warning that the previous behavior of introducing a new early-bound
347347
/// lifetime is a bug and will be removed (if `emit_lint` is enabled).
348-
StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool },
348+
StaticIfNoLifetimeInScope { emit_lint: bool },
349349

350350
/// Signal we cannot find which should be the anonymous lifetime.
351351
ElisionFailure,
@@ -1876,7 +1876,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18761876
self.record_lifetime_res(lifetime.id, res, elision_candidate);
18771877
return;
18781878
}
1879-
LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
1879+
LifetimeRibKind::StaticIfNoLifetimeInScope { emit_lint } => {
18801880
let mut lifetimes_in_scope = vec![];
18811881
for rib in self.lifetime_ribs[..i].iter().rev() {
18821882
lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
@@ -1898,24 +1898,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18981898
);
18991899
return;
19001900
} else if emit_lint {
1901-
let lt_span = if elided {
1902-
lifetime.ident.span.shrink_to_hi()
1903-
} else {
1904-
lifetime.ident.span
1905-
};
1906-
let code = if elided { "'static " } else { "'static" };
1907-
1908-
self.r.lint_buffer.buffer_lint(
1909-
lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
1910-
node_id,
1911-
lifetime.ident.span,
1912-
crate::errors::AssociatedConstElidedLifetime {
1913-
elided,
1914-
code,
1915-
span: lt_span,
1916-
lifetimes_in_scope: lifetimes_in_scope.into(),
1917-
},
1918-
);
1901+
break;
19191902
}
19201903
}
19211904
LifetimeRibKind::AnonymousReportError => {
@@ -3351,10 +3334,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33513334
generics.span,
33523335
|this| {
33533336
this.with_lifetime_rib(
3354-
LifetimeRibKind::StaticIfNoLifetimeInScope {
3355-
lint_id: item.id,
3356-
emit_lint: false,
3357-
},
3337+
LifetimeRibKind::StaticIfNoLifetimeInScope { emit_lint: false },
33583338
|this| {
33593339
this.visit_generics(generics);
33603340
if rhs_kind.is_type_const()
@@ -3571,66 +3551,46 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35713551
generics.span,
35723552
|this| {
35733553
this.with_lifetime_rib(
3574-
// Until these are a hard error, we need to create them within the
3575-
// correct binder, Otherwise the lifetimes of this assoc const think
3576-
// they are lifetimes of the trait.
3577-
LifetimeRibKind::AnonymousCreateParameter {
3578-
binder: item.id,
3579-
report_in_path: true,
3554+
LifetimeRibKind::StaticIfNoLifetimeInScope {
3555+
// In impls, it's not a hard error yet due to backcompat.
3556+
emit_lint: true,
35803557
},
35813558
|this| {
3582-
this.with_lifetime_rib(
3583-
LifetimeRibKind::StaticIfNoLifetimeInScope {
3584-
lint_id: item.id,
3585-
// In impls, it's not a hard error yet due to backcompat.
3586-
emit_lint: true,
3587-
},
3588-
|this| {
3589-
// If this is a trait impl, ensure the const
3590-
// exists in trait
3591-
this.check_trait_item(
3592-
item.id,
3593-
*ident,
3594-
&item.kind,
3595-
ValueNS,
3596-
item.span,
3597-
seen_trait_items,
3598-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3599-
);
3559+
// If this is a trait impl, ensure the const
3560+
// exists in trait
3561+
this.check_trait_item(
3562+
item.id,
3563+
*ident,
3564+
&item.kind,
3565+
ValueNS,
3566+
item.span,
3567+
seen_trait_items,
3568+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3569+
);
36003570

3601-
this.visit_generics(generics);
3602-
if rhs_kind.is_type_const()
3603-
&& !this
3604-
.r
3605-
.tcx
3606-
.features()
3607-
.generic_const_parameter_types()
3608-
{
3609-
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3610-
this.with_rib(
3611-
ValueNS,
3612-
RibKind::ConstParamTy,
3613-
|this| {
3614-
this.with_lifetime_rib(
3615-
LifetimeRibKind::ConstParamTy,
3616-
|this| this.visit_ty(ty),
3617-
)
3618-
},
3619-
)
3620-
});
3621-
} else {
3622-
this.visit_ty(ty);
3623-
}
3624-
// We allow arbitrary const expressions inside of associated consts,
3625-
// even if they are potentially not const evaluatable.
3626-
//
3627-
// Type parameters can already be used and as associated consts are
3628-
// not used as part of the type system, this is far less surprising.
3629-
this.resolve_const_item_rhs(rhs_kind, None);
3630-
},
3631-
)
3571+
this.visit_generics(generics);
3572+
if rhs_kind.is_type_const()
3573+
&& !this.r.tcx.features().generic_const_parameter_types()
3574+
{
3575+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3576+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3577+
this.with_lifetime_rib(
3578+
LifetimeRibKind::ConstParamTy,
3579+
|this| this.visit_ty(ty),
3580+
)
3581+
})
3582+
});
3583+
} else {
3584+
this.visit_ty(ty);
3585+
}
3586+
// We allow arbitrary const expressions inside of associated consts,
3587+
// even if they are potentially not const evaluatable.
3588+
//
3589+
// Type parameters can already be used and as associated consts are
3590+
// not used as part of the type system, this is far less surprising.
3591+
this.resolve_const_item_rhs(rhs_kind, None);
36323592
},
3633-
);
3593+
)
36343594
},
36353595
);
36363596
self.resolve_define_opaques(define_opaque);

src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[
383383
warn_since: None,
384384
deny_since: None,
385385
},
386-
Lint {
387-
label: "elided_lifetimes_in_associated_constant",
388-
description: r##"elided lifetimes cannot be used in associated constants in impls"##,
389-
default_severity: Severity::Error,
390-
warn_since: None,
391-
deny_since: None,
392-
},
393386
Lint {
394387
label: "elided_lifetimes_in_paths",
395388
description: r##"hidden lifetime parameters in types are deprecated"##,
@@ -1851,7 +1844,6 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
18511844
"coherence_leak_check",
18521845
"conflicting_repr_hints",
18531846
"const_evaluatable_unchecked",
1854-
"elided_lifetimes_in_associated_constant",
18551847
"float_literal_f32_fallback",
18561848
"forbidden_lint_groups",
18571849
"ill_formed_attribute_input",
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![deny(elided_lifetimes_in_associated_constant)]
2-
31
use std::marker::PhantomData;
42

53
struct Foo<'a> {
@@ -8,12 +6,10 @@ struct Foo<'a> {
86

97
impl<'a> Foo<'a> {
108
const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
11-
//~^ ERROR `'_` cannot be used here
12-
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9+
//~^ ERROR missing lifetime specifier
1310

1411
const BAR: &() = &();
15-
//~^ ERROR `&` without an explicit lifetime name cannot be used here
16-
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
12+
//~^ ERROR missing lifetime specifier
1713
}
1814

1915
fn main() {}
Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,26 @@
1-
error: `'_` cannot be used here
2-
--> $DIR/assoc-const-elided-lifetime.rs:10:20
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/assoc-const-elided-lifetime.rs:8:20
33
|
44
LL | const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
5-
| ^^
5+
| ^^ expected named lifetime parameter
66
|
7-
note: cannot automatically infer `'static` because of other lifetimes in scope
8-
--> $DIR/assoc-const-elided-lifetime.rs:9:6
9-
|
10-
LL | impl<'a> Foo<'a> {
11-
| ^^
12-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
13-
= note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
14-
note: the lint level is defined here
15-
--> $DIR/assoc-const-elided-lifetime.rs:1:9
16-
|
17-
LL | #![deny(elided_lifetimes_in_associated_constant)]
18-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19-
help: use the `'static` lifetime
7+
help: consider using the `'a` lifetime
208
|
219
LL - const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
22-
LL + const FOO: Foo<'static> = Foo { x: PhantomData::<&()> };
10+
LL + const FOO: Foo<'a> = Foo { x: PhantomData::<&()> };
2311
|
2412

25-
error: `&` without an explicit lifetime name cannot be used here
26-
--> $DIR/assoc-const-elided-lifetime.rs:14:16
13+
error[E0106]: missing lifetime specifier
14+
--> $DIR/assoc-const-elided-lifetime.rs:11:16
2715
|
2816
LL | const BAR: &() = &();
29-
| ^
30-
|
31-
note: cannot automatically infer `'static` because of other lifetimes in scope
32-
--> $DIR/assoc-const-elided-lifetime.rs:9:6
17+
| ^ expected named lifetime parameter
3318
|
34-
LL | impl<'a> Foo<'a> {
35-
| ^^
36-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
37-
= note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
38-
help: use the `'static` lifetime
19+
help: consider using the `'a` lifetime
3920
|
40-
LL | const BAR: &'static () = &();
41-
| +++++++
21+
LL | const BAR: &'a () = &();
22+
| ++
4223

4324
error: aborting due to 2 previous errors
4425

26+
For more information about this error, try `rustc --explain E0106`.
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
#![deny(elided_lifetimes_in_associated_constant)]
2-
31
struct Foo<'a>(&'a ());
42

53
impl Foo<'_> {
64
const STATIC: &str = "";
7-
//~^ ERROR `&` without an explicit lifetime name cannot be used here
8-
//~| WARN this was previously accepted by the compiler but is being phased out
5+
//~^ ERROR missing lifetime specifier
96
}
107

118
trait Bar {
@@ -14,9 +11,7 @@ trait Bar {
1411

1512
impl Bar for Foo<'_> {
1613
const STATIC: &str = "";
17-
//~^ ERROR `&` without an explicit lifetime name cannot be used here
18-
//~| WARN this was previously accepted by the compiler but is being phased out
19-
//~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration
14+
//~^ ERROR missing lifetime specifier
2015
}
2116

2217
fn main() {}

0 commit comments

Comments
 (0)