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

`{

`