Skip to content

Commit b2dfdd2

Browse files
committed
Turn elided_lifetimes_in_associated_constant FCW into a hard error
1 parent 6eda741 commit b2dfdd2

12 files changed

Lines changed: 88 additions & 292 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,
@@ -4809,48 +4808,6 @@ declare_lint! {
48094808
"impl trait in impl method signature does not match trait method signature",
48104809
}
48114810

4812-
declare_lint! {
4813-
/// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes
4814-
/// in associated constants when there are other lifetimes in scope. This was
4815-
/// accidentally supported, and this lint was later relaxed to allow eliding
4816-
/// lifetimes to `'static` when there are no lifetimes in scope.
4817-
///
4818-
/// ### Example
4819-
///
4820-
/// ```rust,compile_fail
4821-
/// #![deny(elided_lifetimes_in_associated_constant)]
4822-
///
4823-
/// struct Foo<'a>(&'a ());
4824-
///
4825-
/// impl<'a> Foo<'a> {
4826-
/// const STR: &str = "hello, world";
4827-
/// }
4828-
/// ```
4829-
///
4830-
/// {{produces}}
4831-
///
4832-
/// ### Explanation
4833-
///
4834-
/// Previous version of Rust
4835-
///
4836-
/// Implicit static-in-const behavior was decided [against] for associated
4837-
/// constants because of ambiguity. This, however, regressed and the compiler
4838-
/// erroneously treats elided lifetimes in associated constants as lifetime
4839-
/// parameters on the impl.
4840-
///
4841-
/// This is a [future-incompatible] lint to transition this to a
4842-
/// hard error in the future.
4843-
///
4844-
/// [against]: https://github.com/rust-lang/rust/issues/38831
4845-
/// [future-incompatible]: ../index.md#future-incompatible-lints
4846-
pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4847-
Deny,
4848-
"elided lifetimes cannot be used in associated constants in impls",
4849-
@future_incompatible = FutureIncompatibleInfo {
4850-
reason: fcw!(FutureReleaseError #115010),
4851-
};
4852-
}
4853-
48544811
declare_lint! {
48554812
/// The `private_macro_use` lint detects private macros that are imported
48564813
/// 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: 41 additions & 81 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,
@@ -1883,7 +1883,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18831883
self.record_lifetime_use(lifetime.id, res, elision_candidate);
18841884
return;
18851885
}
1886-
LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
1886+
LifetimeRibKind::StaticIfNoLifetimeInScope { emit_lint } => {
18871887
let mut lifetimes_in_scope = vec![];
18881888
for rib in self.lifetime_ribs[..i].iter().rev() {
18891889
lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
@@ -1905,24 +1905,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19051905
);
19061906
return;
19071907
} else if emit_lint {
1908-
let lt_span = if elided {
1909-
lifetime.ident.span.shrink_to_hi()
1910-
} else {
1911-
lifetime.ident.span
1912-
};
1913-
let code = if elided { "'static " } else { "'static" };
1914-
1915-
self.r.lint_buffer.buffer_lint(
1916-
lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
1917-
node_id,
1918-
lifetime.ident.span,
1919-
crate::errors::AssociatedConstElidedLifetime {
1920-
elided,
1921-
code,
1922-
span: lt_span,
1923-
lifetimes_in_scope: lifetimes_in_scope.into(),
1924-
},
1925-
);
1908+
break;
19261909
}
19271910
}
19281911
LifetimeRibKind::AnonymousReportError => {
@@ -3348,10 +3331,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
33483331
generics.span,
33493332
|this| {
33503333
this.with_lifetime_rib(
3351-
LifetimeRibKind::StaticIfNoLifetimeInScope {
3352-
lint_id: item.id,
3353-
emit_lint: false,
3354-
},
3334+
LifetimeRibKind::StaticIfNoLifetimeInScope { emit_lint: false },
33553335
|this| {
33563336
this.visit_generics(generics);
33573337
if rhs_kind.is_type_const()
@@ -3567,67 +3547,47 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
35673547
generics.span,
35683548
|this| {
35693549
this.with_lifetime_rib(
3570-
// Until these are a hard error, we need to create them within the
3571-
// correct binder, Otherwise the lifetimes of this assoc const think
3572-
// they are lifetimes of the trait.
3573-
LifetimeRibKind::AnonymousCreateParameter {
3574-
binder: item.id,
3575-
report_in_path: true,
3550+
LifetimeRibKind::StaticIfNoLifetimeInScope {
3551+
// In impls, it's not a hard error yet due to backcompat.
3552+
emit_lint: true,
35763553
},
35773554
|this| {
3578-
this.with_lifetime_rib(
3579-
LifetimeRibKind::StaticIfNoLifetimeInScope {
3580-
lint_id: item.id,
3581-
// In impls, it's not a hard error yet due to backcompat.
3582-
emit_lint: true,
3583-
},
3584-
|this| {
3585-
// If this is a trait impl, ensure the const
3586-
// exists in trait
3587-
this.check_trait_item(
3588-
item.id,
3589-
*ident,
3590-
*ident,
3591-
&item.kind,
3592-
ValueNS,
3593-
item.span,
3594-
seen_trait_items,
3595-
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3596-
);
3555+
// If this is a trait impl, ensure the const
3556+
// exists in trait
3557+
this.check_trait_item(
3558+
item.id,
3559+
*ident,
3560+
*ident,
3561+
&item.kind,
3562+
ValueNS,
3563+
item.span,
3564+
seen_trait_items,
3565+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
3566+
);
35973567

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