@@ -9,31 +9,77 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
9
9
use rustc_middle:: ty:: {
10
10
self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor ,
11
11
} ;
12
- use rustc_session:: lint:: FutureIncompatibilityReason ;
13
- use rustc_span:: edition:: Edition ;
14
- use rustc_span:: { BytePos , Span } ;
12
+ use rustc_span:: { sym, BytePos , Span } ;
15
13
16
14
use crate :: fluent_generated as fluent;
17
15
use crate :: { LateContext , LateLintPass } ;
18
16
19
- // TODO: feature gate these too
20
-
21
17
declare_lint ! {
22
- /// UwU
18
+ /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope,
19
+ /// rather than just the lifetimes that are mentioned in the bounds of the type.
20
+ /// Often these sets are equal, but if not, it means that the `impl Trait` may
21
+ /// cause erroneous borrow-checker errors.
22
+ ///
23
+ /// ### Example
24
+ ///
25
+ /// ```rust,compile_fail
26
+ /// # #![feature(precise_capturing, lifetime_capture_rules_2024)]
27
+ /// # use std::fmt::Display;
28
+ /// let mut x = vec![];
29
+ /// x.push(1);
30
+ ///
31
+ /// fn test(x: &Vec<i32>) -> impl Display {
32
+ /// x[0]
33
+ /// }
34
+ ///
35
+ /// let element = test(&x);
36
+ /// x.push(2);
37
+ /// println!("{element}");
38
+ /// ```
39
+ ///
40
+ /// {{produces}}
41
+ ///
42
+ /// ### Explanation
43
+ ///
44
+ /// In edition < 2024, the returned `impl Display` doesn't capture the
45
+ /// lifetime from the `&Vec<i32>`, so the vector can be mutably borrowed
46
+ /// while the `impl Display` is live.
47
+ ///
48
+ /// To fix this, we can explicitly state that the `impl Display` doesn't
49
+ /// capture any lifetimes, using `impl use<> Display`.
23
50
pub IMPL_TRAIT_OVERCAPTURES ,
24
51
Allow ,
25
- "will capture more lifetimes than possibly intended in edition 2024" ,
26
- @future_incompatible = FutureIncompatibleInfo {
27
- reason: FutureIncompatibilityReason :: EditionSemanticsChange ( Edition :: Edition2024 ) ,
28
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>" ,
29
- } ;
52
+ "`impl Trait` will capture more lifetimes than possibly intended in edition 2024" ,
53
+ @feature_gate = sym:: precise_capturing;
54
+ //@future_incompatible = FutureIncompatibleInfo {
55
+ // reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
56
+ // reference: "<FIXME>",
57
+ //};
30
58
}
31
59
32
60
declare_lint ! {
33
- /// UwU
61
+ /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope.
62
+ /// If precise-capturing `use<...>` syntax is used, and the set of parameters
63
+ /// that are captures are *equal* to the set of parameters in scope, then
64
+ /// the syntax is redundant, and can be removed.
65
+ ///
66
+ /// ### Example
67
+ ///
68
+ /// ```rust,compile_fail
69
+ /// # #![feature(precise_capturing, lifetime_capture_rules_2024)]
70
+ /// fn test<'a>(x: &'a i32) -> impl use<'a> Sized { x }
71
+ /// ```
72
+ ///
73
+ /// {{produces}}
74
+ ///
75
+ /// ### Explanation
76
+ ///
77
+ /// To fix this, remove the `use<'a>`, since the lifetime is already captured
78
+ /// since it is in scope.
34
79
pub IMPL_TRAIT_REDUNDANT_CAPTURES ,
35
80
Warn ,
36
- "uwu 2"
81
+ "redundant precise-capturing `use<...>` syntax on an `impl Trait`" ,
82
+ @feature_gate = sym:: precise_capturing;
37
83
}
38
84
39
85
declare_lint_pass ! (
@@ -106,7 +152,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
106
152
for arg in t. bound_vars ( ) {
107
153
let arg: ty:: BoundVariableKind = arg;
108
154
match arg {
109
- ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: BrNamed ( def_id, ..) ) => {
155
+ ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: BrNamed ( def_id, ..) )
156
+ | ty:: BoundVariableKind :: Ty ( ty:: BoundTyKind :: Param ( def_id, _) ) => {
110
157
added. push ( def_id) ;
111
158
let unique = self . in_scope_parameters . insert ( def_id) ;
112
159
assert ! ( unique) ;
@@ -265,7 +312,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
265
312
}
266
313
_ => {
267
314
self . tcx . dcx ( ) . span_delayed_bug (
268
- self . tcx ( ) . hir ( ) . span ( arg. hir_id ( ) ) ,
315
+ self . tcx . hir ( ) . span ( arg. hir_id ( ) ) ,
269
316
"no valid for captured arg" ,
270
317
) ;
271
318
}
0 commit comments