Skip to content

Commit 554becc

Browse files
Add some commenting
1 parent d57e57c commit 554becc

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

compiler/rustc_lint/src/impl_trait_overcaptures.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ declare_lint! {
2424
}
2525

2626
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.
2929
ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES]
3030
);
3131

@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
5050
}
5151
}
5252
DefKind::Fn => {
53-
// All freee functions need to check for overcaptures.
53+
// All free functions need to check for overcaptures.
5454
}
5555
DefKind::Closure => return,
5656
kind => {
@@ -64,6 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
6464
let sig = cx.tcx.fn_sig(parent_def_id).instantiate_identity();
6565

6666
let mut in_scope_parameters = FxIndexSet::default();
67+
// Populate the in_scope_parameters list first with all of the generics in scope
6768
let mut current_def_id = Some(parent_def_id.to_def_id());
6869
while let Some(def_id) = current_def_id {
6970
let generics = cx.tcx.generics_of(def_id);
@@ -73,6 +74,8 @@ impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures {
7374
current_def_id = generics.parent;
7475
}
7576

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).
7679
sig.visit_with(&mut VisitOpaqueTypes {
7780
tcx: cx.tcx,
7881
parent_def_id,
@@ -94,6 +97,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
9497
&mut self,
9598
t: &ty::Binder<'tcx, T>,
9699
) -> Self::Result {
100+
// When we get into a binder, we need to add its own bound vars to the scope.
97101
let mut added = vec![];
98102
for arg in t.bound_vars() {
99103
let arg: ty::BoundVariableKind = arg;
@@ -117,6 +121,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
117121

118122
t.super_visit_with(self);
119123

124+
// And remove them. The `shift_remove` should be `O(1)` since we're popping
125+
// them off from the end.
120126
for arg in added.into_iter().rev() {
121127
self.in_scope_parameters.shift_remove(&arg);
122128
}
@@ -129,22 +135,29 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
129135

130136
if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind()
131137
&& let Some(opaque_def_id) = opaque_ty.def_id.as_local()
138+
// Don't recurse infinitely on an opaque
132139
&& self.seen.insert(opaque_def_id)
140+
// If it's owned by this function
133141
&& let opaque =
134142
self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
135143
&& let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin
136144
&& parent_def_id == self.parent_def_id
145+
// And if the opaque doesn't already have `use<>` syntax on it...
137146
&& opaque.precise_capturing_args.is_none()
138147
{
148+
// Compute the set of args that are captured by the opaque...
139149
let mut captured = UnordSet::default();
140150
let variances = self.tcx.variances_of(opaque_def_id);
141151
let mut current_def_id = Some(opaque_def_id.to_def_id());
142152
while let Some(def_id) = current_def_id {
143153
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.
145156
if variances[param.index as usize] != ty::Invariant {
146157
continue;
147158
}
159+
// We need to turn all `ty::Param`/`ConstKind::Param` and
160+
// `ReEarlyParam`/`ReBound` into def ids.
148161
captured.insert(extract_def_id_from_arg(
149162
self.tcx,
150163
generics,
@@ -154,6 +167,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
154167
current_def_id = generics.parent;
155168
}
156169

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.
157172
let uncaptured_spans: Vec<_> = self
158173
.in_scope_parameters
159174
.iter()
@@ -174,6 +189,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for VisitOpaqueTypes<'tcx> {
174189
);
175190
}
176191

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).
177196
for clause in
178197
self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args)
179198
{

0 commit comments

Comments
 (0)