Add some commenting · rust-lang/rust@554becc (original) (raw)
`@@ -24,8 +24,8 @@ declare_lint! {
`
24
24
`}
`
25
25
``
26
26
`declare_lint_pass!(
`
27
``
`` -
/// Lint for use of async fn
in the definition of a publicly-reachable
``
28
``
`-
/// trait.
`
``
27
`+
/// Lint for opaque types that will begin capturing in-scope but unmentioned lifetimes
`
``
28
`+
/// in edition 2024.
`
29
29
`ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES]
`
30
30
`);
`
31
31
``
`@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
`
50
50
`}
`
51
51
`}
`
52
52
`DefKind::Fn => {
`
53
``
`-
// All freee functions need to check for overcaptures.
`
``
53
`+
// All free functions need to check for overcaptures.
`
54
54
`}
`
55
55
`DefKind::Closure => return,
`
56
56
` kind => {
`
`@@ -64,6 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
`
64
64
`let sig = cx.tcx.fn_sig(parent_def_id).instantiate_identity();
`
65
65
``
66
66
`let mut in_scope_parameters = FxIndexSet::default();
`
``
67
`+
// Populate the in_scope_parameters list first with all of the generics in scope
`
67
68
`let mut current_def_id = Some(parent_def_id.to_def_id());
`
68
69
`while let Some(def_id) = current_def_id {
`
69
70
`let generics = cx.tcx.generics_of(def_id);
`
`@@ -73,6 +74,8 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
`
73
74
` current_def_id = generics.parent;
`
74
75
`}
`
75
76
``
``
77
`+
// Then visit the signature to walk through all the binders (incl. the late-bound
`
``
78
`+
// vars on the function itself, which we need to count too).
`
76
79
` sig.visit_with(&mut VisitOpaqueTypes {
`
77
80
`tcx: cx.tcx,
`
78
81
` parent_def_id,
`
`@@ -94,6 +97,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
`
94
97
`&mut self,
`
95
98
`t: &ty::Binder<'tcx, T>,
`
96
99
`) -> Self::Result {
`
``
100
`+
// When we get into a binder, we need to add its own bound vars to the scope.
`
97
101
`let mut added = vec![];
`
98
102
`for arg in t.bound_vars() {
`
99
103
`let arg: ty::BoundVariableKind = arg;
`
`@@ -117,6 +121,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
`
117
121
``
118
122
` t.super_visit_with(self);
`
119
123
``
``
124
`` +
// And remove them. The shift_remove
should be O(1)
since we're popping
``
``
125
`+
// them off from the end.
`
120
126
`for arg in added.into_iter().rev() {
`
121
127
`self.in_scope_parameters.shift_remove(&arg);
`
122
128
`}
`
`@@ -129,22 +135,29 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
`
129
135
``
130
136
`if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind()
`
131
137
` && let Some(opaque_def_id) = opaque_ty.def_id.as_local()
`
``
138
`+
// Don't recurse infinitely on an opaque
`
132
139
` && self.seen.insert(opaque_def_id)
`
``
140
`+
// If it's owned by this function
`
133
141
` && let opaque =
`
134
142
`self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
`
135
143
` && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin
`
136
144
` && parent_def_id == self.parent_def_id
`
``
145
`` +
// And if the opaque doesn't already have use<>
syntax on it...
``
137
146
` && opaque.precise_capturing_args.is_none()
`
138
147
`{
`
``
148
`+
// Compute the set of args that are captured by the opaque...
`
139
149
`let mut captured = UnordSet::default();
`
140
150
`let variances = self.tcx.variances_of(opaque_def_id);
`
141
151
`let mut current_def_id = Some(opaque_def_id.to_def_id());
`
142
152
`while let Some(def_id) = current_def_id {
`
143
153
`let generics = self.tcx.generics_of(def_id);
`
144
``
`-
for param in &generics.params {
`
``
154
`+
for param in &generics.own_params {
`
``
155
`+
// A param is captured if it's invariant.
`
145
156
`if variances[param.index as usize] != ty::Invariant {
`
146
157
`continue;
`
147
158
`}
`
``
159
`` +
// We need to turn all ty::Param
/ConstKind::Param
and
``
``
160
`` +
// ReEarlyParam
/ReBound
into def ids.
``
148
161
` captured.insert(extract_def_id_from_arg(
`
149
162
`self.tcx,
`
150
163
` generics,
`
`@@ -154,6 +167,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
`
154
167
` current_def_id = generics.parent;
`
155
168
`}
`
156
169
``
``
170
`+
// Compute the set of in scope params that are not captured. Get their spans,
`
``
171
`+
// since that's all we really care about them for emitting the diagnostic.
`
157
172
`let uncaptured_spans: Vec<_> = self
`
158
173
`.in_scope_parameters
`
159
174
`.iter()
`
`@@ -174,6 +189,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
`
174
189
`);
`
175
190
`}
`
176
191
``
``
192
`+
// Walk into the bounds of the opaque, too, since we want to get nested opaques
`
``
193
`+
// in this lint as well. Interestingly, one place that I expect this lint to fire
`
``
194
`` +
// is for impl for<'a> Bound<Out = impl Other>
, since impl Other
will begin
``
``
195
`` +
// to capture 'a
in e2024 (even though late-bound vars in opaques are not allowed).
``
177
196
`for clause in
`
178
197
`self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args)
`
179
198
`{
`