1
- use crate :: utils:: { is_entrypoint_fn, match_type, paths, return_ty, span_lint} ;
1
+ use crate :: utils:: { get_trait_def_id, implements_trait, is_entrypoint_fn, match_type, paths, return_ty, span_lint} ;
2
+ use if_chain:: if_chain;
2
3
use itertools:: Itertools ;
3
4
use rustc:: lint:: in_external_macro;
5
+ use rustc:: ty;
4
6
use rustc_data_structures:: fx:: FxHashSet ;
5
7
use rustc_hir as hir;
6
8
use rustc_lint:: { LateContext , LateLintPass } ;
@@ -152,11 +154,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
152
154
fn check_item ( & mut self , cx : & LateContext < ' a , ' tcx > , item : & ' tcx hir:: Item < ' _ > ) {
153
155
let headers = check_attrs ( cx, & self . valid_idents , & item. attrs ) ;
154
156
match item. kind {
155
- hir:: ItemKind :: Fn ( ref sig, .. ) => {
157
+ hir:: ItemKind :: Fn ( ref sig, _ , body_id ) => {
156
158
if !( is_entrypoint_fn ( cx, cx. tcx . hir ( ) . local_def_id ( item. hir_id ) )
157
159
|| in_external_macro ( cx. tcx . sess , item. span ) )
158
160
{
159
- lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers) ;
161
+ lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers, Some ( body_id ) ) ;
160
162
}
161
163
} ,
162
164
hir:: ItemKind :: Impl {
@@ -179,7 +181,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
179
181
let headers = check_attrs ( cx, & self . valid_idents , & item. attrs ) ;
180
182
if let hir:: TraitItemKind :: Method ( ref sig, ..) = item. kind {
181
183
if !in_external_macro ( cx. tcx . sess , item. span ) {
182
- lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers) ;
184
+ lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers, None ) ;
183
185
}
184
186
}
185
187
}
@@ -189,8 +191,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
189
191
if self . in_trait_impl || in_external_macro ( cx. tcx . sess , item. span ) {
190
192
return ;
191
193
}
192
- if let hir:: ImplItemKind :: Method ( ref sig, .. ) = item. kind {
193
- lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers) ;
194
+ if let hir:: ImplItemKind :: Method ( ref sig, body_id ) = item. kind {
195
+ lint_for_missing_headers ( cx, item. hir_id , item. span , sig, headers, Some ( body_id ) ) ;
194
196
}
195
197
}
196
198
}
@@ -201,6 +203,7 @@ fn lint_for_missing_headers<'a, 'tcx>(
201
203
span : impl Into < MultiSpan > + Copy ,
202
204
sig : & hir:: FnSig < ' _ > ,
203
205
headers : DocHeaders ,
206
+ body_id : Option < hir:: BodyId > ,
204
207
) {
205
208
if !cx. access_levels . is_exported ( hir_id) {
206
209
return ; // Private functions do not require doc comments
@@ -213,13 +216,36 @@ fn lint_for_missing_headers<'a, 'tcx>(
213
216
"unsafe function's docs miss `# Safety` section" ,
214
217
) ;
215
218
}
216
- if !headers. errors && match_type ( cx, return_ty ( cx, hir_id) , & paths:: RESULT ) {
217
- span_lint (
218
- cx,
219
- MISSING_ERRORS_DOC ,
220
- span,
221
- "docs for function returning `Result` missing `# Errors` section" ,
222
- ) ;
219
+ if !headers. errors {
220
+ if match_type ( cx, return_ty ( cx, hir_id) , & paths:: RESULT ) {
221
+ span_lint (
222
+ cx,
223
+ MISSING_ERRORS_DOC ,
224
+ span,
225
+ "docs for function returning `Result` missing `# Errors` section" ,
226
+ ) ;
227
+ } else {
228
+ if_chain ! {
229
+ if let Some ( body_id) = body_id;
230
+ if let Some ( future) = get_trait_def_id( cx, & paths:: FUTURE ) ;
231
+ let def_id = cx. tcx. hir( ) . body_owner_def_id( body_id) ;
232
+ let mir = cx. tcx. optimized_mir( def_id) ;
233
+ let ret_ty = mir. return_ty( ) ;
234
+ if implements_trait( cx, ret_ty, future, & [ ] ) ;
235
+ if let ty:: Opaque ( _, subs) = ret_ty. kind;
236
+ if let Some ( gen ) = subs. types( ) . next( ) ;
237
+ if let ty:: Generator ( _, subs, _) = gen . kind;
238
+ if match_type( cx, subs. as_generator( ) . return_ty( def_id, cx. tcx) , & paths:: RESULT ) ;
239
+ then {
240
+ span_lint(
241
+ cx,
242
+ MISSING_ERRORS_DOC ,
243
+ span,
244
+ "docs for function returning `Result` missing `# Errors` section" ,
245
+ ) ;
246
+ }
247
+ }
248
+ }
223
249
}
224
250
}
225
251
0 commit comments