@@ -310,9 +310,10 @@ enum LifetimeRibKind {
310
310
/// error on default object bounds (e.g., `Box<dyn Foo>`).
311
311
AnonymousReportError,
312
312
313
- /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior
314
- /// is a bug and will be reverted soon.
315
- AnonymousWarn(NodeId),
313
+ /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
314
+ /// otherwise give a warning that the previous behavior of introducing a new early-bound
315
+ /// lifetime is a bug and will be removed (if `emit_lint` is enabled).
316
+ StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool },
316
317
317
318
/// Signal we cannot find which should be the anonymous lifetime.
318
319
ElisionFailure,
@@ -1212,7 +1213,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
1212
1213
}
1213
1214
LifetimeRibKind::AnonymousCreateParameter { .. }
1214
1215
| LifetimeRibKind::AnonymousReportError
1215
- | LifetimeRibKind::AnonymousWarn(_)
1216
+ | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
1216
1217
| LifetimeRibKind::Elided(_)
1217
1218
| LifetimeRibKind::ElisionFailure
1218
1219
| LifetimeRibKind::ConcreteAnonConst(_)
@@ -1580,7 +1581,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1580
1581
// lifetime would be illegal.
1581
1582
LifetimeRibKind::Item
1582
1583
| LifetimeRibKind::AnonymousReportError
1583
- | LifetimeRibKind::AnonymousWarn(_)
1584
+ | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
1584
1585
| LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
1585
1586
// An anonymous lifetime is legal here, and bound to the right
1586
1587
// place, go ahead.
@@ -1643,7 +1644,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1643
1644
| LifetimeRibKind::Generics { .. }
1644
1645
| LifetimeRibKind::ElisionFailure
1645
1646
| LifetimeRibKind::AnonymousReportError
1646
- | LifetimeRibKind::AnonymousWarn(_) => {}
1647
+ | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {}
1647
1648
}
1648
1649
}
1649
1650
@@ -1677,16 +1678,36 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1677
1678
self.record_lifetime_res(lifetime.id, res, elision_candidate);
1678
1679
return;
1679
1680
}
1680
- LifetimeRibKind::AnonymousWarn(node_id) => {
1681
- self.r.lint_buffer.buffer_lint(
1682
- lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
1683
- node_id,
1684
- lifetime.ident.span,
1685
- lint::BuiltinLintDiag::AssociatedConstElidedLifetime {
1686
- elided,
1687
- span: lifetime.ident.span,
1688
- },
1689
- );
1681
+ LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
1682
+ let mut lifetimes_in_scope = vec![];
1683
+ for rib in &self.lifetime_ribs[..i] {
1684
+ lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
1685
+ // Consider any anonymous lifetimes, too
1686
+ if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind
1687
+ && let Some(extra) = self.r.extra_lifetime_params_map.get(&binder)
1688
+ {
1689
+ lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));
1690
+ }
1691
+ }
1692
+ if lifetimes_in_scope.is_empty() {
1693
+ self.record_lifetime_res(
1694
+ lifetime.id,
1695
+ LifetimeRes::Static,
1696
+ elision_candidate,
1697
+ );
1698
+ return;
1699
+ } else if emit_lint {
1700
+ self.r.lint_buffer.buffer_lint(
1701
+ lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
1702
+ node_id,
1703
+ lifetime.ident.span,
1704
+ lint::BuiltinLintDiag::AssociatedConstElidedLifetime {
1705
+ elided,
1706
+ span: lifetime.ident.span,
1707
+ lifetimes_in_scope: lifetimes_in_scope.into(),
1708
+ },
1709
+ );
1710
+ }
1690
1711
}
1691
1712
LifetimeRibKind::AnonymousReportError => {
1692
1713
if elided {
@@ -1904,7 +1925,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
1904
1925
// impl Foo for std::cell::Ref<u32> // note lack of '_
1905
1926
// async fn foo(_: std::cell::Ref<u32>) { ... }
1906
1927
LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
1907
- | LifetimeRibKind::AnonymousWarn(_) => {
1928
+ | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {
1908
1929
let sess = self.r.tcx.sess;
1909
1930
let subdiag = rustc_errors::elided_lifetime_in_path_suggestion(
1910
1931
sess.source_map(),
@@ -2838,19 +2859,27 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
2838
2859
kind: LifetimeBinderKind::ConstItem,
2839
2860
},
2840
2861
|this| {
2841
- this.visit_generics(generics);
2842
- this.visit_ty(ty);
2843
-
2844
- // Only impose the restrictions of `ConstRibKind` for an
2845
- // actual constant expression in a provided default.
2846
- if let Some(expr) = expr {
2847
- // We allow arbitrary const expressions inside of associated consts,
2848
- // even if they are potentially not const evaluatable.
2849
- //
2850
- // Type parameters can already be used and as associated consts are
2851
- // not used as part of the type system, this is far less surprising.
2852
- this.resolve_const_body(expr, None);
2853
- }
2862
+ this.with_lifetime_rib(
2863
+ LifetimeRibKind::StaticIfNoLifetimeInScope {
2864
+ lint_id: item.id,
2865
+ emit_lint: false,
2866
+ },
2867
+ |this| {
2868
+ this.visit_generics(generics);
2869
+ this.visit_ty(ty);
2870
+
2871
+ // Only impose the restrictions of `ConstRibKind` for an
2872
+ // actual constant expression in a provided default.
2873
+ if let Some(expr) = expr {
2874
+ // We allow arbitrary const expressions inside of associated consts,
2875
+ // even if they are potentially not const evaluatable.
2876
+ //
2877
+ // Type parameters can already be used and as associated consts are
2878
+ // not used as part of the type system, this is far less surprising.
2879
+ this.resolve_const_body(expr, None);
2880
+ }
2881
+ },
2882
+ )
2854
2883
},
2855
2884
);
2856
2885
}
@@ -3030,30 +3059,37 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3030
3059
kind: LifetimeBinderKind::ConstItem,
3031
3060
},
3032
3061
|this| {
3033
- this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| {
3034
- // If this is a trait impl, ensure the const
3035
- // exists in trait
3036
- this.check_trait_item(
3037
- item.id,
3038
- item.ident,
3039
- &item.kind,
3040
- ValueNS,
3041
- item.span,
3042
- seen_trait_items,
3043
- |i, s, c| ConstNotMemberOfTrait(i, s, c),
3044
- );
3062
+ this.with_lifetime_rib(
3063
+ LifetimeRibKind::StaticIfNoLifetimeInScope {
3064
+ lint_id: item.id,
3065
+ // In impls, it's not a hard error yet due to backcompat.
3066
+ emit_lint: true,
3067
+ },
3068
+ |this| {
3069
+ // If this is a trait impl, ensure the const
3070
+ // exists in trait
3071
+ this.check_trait_item(
3072
+ item.id,
3073
+ item.ident,
3074
+ &item.kind,
3075
+ ValueNS,
3076
+ item.span,
3077
+ seen_trait_items,
3078
+ |i, s, c| ConstNotMemberOfTrait(i, s, c),
3079
+ );
3045
3080
3046
- this.visit_generics(generics);
3047
- this.visit_ty(ty);
3048
- if let Some(expr) = expr {
3049
- // We allow arbitrary const expressions inside of associated consts,
3050
- // even if they are potentially not const evaluatable.
3051
- //
3052
- // Type parameters can already be used and as associated consts are
3053
- // not used as part of the type system, this is far less surprising.
3054
- this.resolve_const_body(expr, None);
3055
- }
3056
- });
3081
+ this.visit_generics(generics);
3082
+ this.visit_ty(ty);
3083
+ if let Some(expr) = expr {
3084
+ // We allow arbitrary const expressions inside of associated consts,
3085
+ // even if they are potentially not const evaluatable.
3086
+ //
3087
+ // Type parameters can already be used and as associated consts are
3088
+ // not used as part of the type system, this is far less surprising.
3089
+ this.resolve_const_body(expr, None);
3090
+ }
3091
+ },
3092
+ );
3057
3093
},
3058
3094
);
3059
3095
}
0 commit comments