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