@@ -37,8 +37,8 @@ use std::path::Path;
37
37
38
38
use crate :: utils:: internal_lints:: is_lint_ref_type;
39
39
use crate :: utils:: {
40
- get_enclosing_body, get_parent_expr_for_hir, last_path_segment, match_function_call, match_qpath, match_type ,
41
- path_to_local_id, paths, span_lint, walk_ptrs_ty_depth, get_parent_expr
40
+ get_enclosing_body, get_parent_expr , get_parent_expr_for_hir, last_path_segment, match_function_call, match_qpath,
41
+ match_type , path_to_local_id, paths, span_lint, walk_ptrs_ty_depth,
42
42
} ;
43
43
44
44
/// This is the output file of the lint collector.
@@ -202,39 +202,19 @@ impl<'tcx> LateLintPass<'tcx> for MetadataCollector {
202
202
/// ```
203
203
fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' _ > ) {
204
204
if_chain ! {
205
+ // item validation
205
206
if let ItemKind :: Static ( ref ty, Mutability :: Not , body_id) = item. kind;
206
207
if is_lint_ref_type( cx, ty) ;
207
208
let expr = & cx. tcx. hir( ) . body( body_id) . value;
208
209
if let ExprKind :: AddrOf ( _, _, ref inner_exp) = expr. kind;
209
210
if let ExprKind :: Struct ( _, _, _) = inner_exp. kind;
211
+ // blacklist check
212
+ let lint_name = sym_to_string( item. ident. name) . to_ascii_lowercase( ) ;
213
+ if !BLACK_LISTED_LINTS . contains( & lint_name. as_str( ) ) ;
214
+ // metadata extraction
215
+ if let Some ( group) = get_lint_group_or_lint( cx, & lint_name, item) ;
216
+ if let Some ( docs) = extract_attr_docs_or_lint( cx, item) ;
210
217
then {
211
- let lint_name = sym_to_string( item. ident. name) . to_ascii_lowercase( ) ;
212
- if BLACK_LISTED_LINTS . contains( & lint_name. as_str( ) ) {
213
- return ;
214
- }
215
-
216
- let group: String ;
217
- let result = cx. lint_store. check_lint_name( lint_name. as_str( ) , Some ( sym:: clippy) ) ;
218
- if let CheckLintNameResult :: Tool ( Ok ( lint_lst) ) = result {
219
- if let Some ( group_some) = get_lint_group( cx, lint_lst[ 0 ] ) {
220
- group = group_some;
221
- } else {
222
- lint_collection_error_item( cx, item, "Unable to determine lint group" ) ;
223
- return ;
224
- }
225
- } else {
226
- lint_collection_error_item( cx, item, "Unable to find lint in lint_store" ) ;
227
- return ;
228
- }
229
-
230
- let docs: String ;
231
- if let Some ( docs_some) = extract_attr_docs( item) {
232
- docs = docs_some;
233
- } else {
234
- lint_collection_error_item( cx, item, "could not collect the lint documentation" ) ;
235
- return ;
236
- } ;
237
-
238
218
self . lints. push( LintMetadata :: new(
239
219
lint_name,
240
220
SerializableSpan :: from_item( cx, item) ,
@@ -301,7 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for MetadataCollector {
301
281
let span = SerializableSpan :: from_span( cx, local. span) ;
302
282
let local_str = crate :: utils:: snippet( cx, local. span, "_" ) ;
303
283
log_to_file( & format!( "{} -- {}\n " , local_str, span) ) ;
304
-
284
+
305
285
let value_hir_id = local. pat. hir_id;
306
286
let mut tracker = ValueTracker :: new( cx, value_hir_id) ;
307
287
if let Some ( init_expr) = local. init {
@@ -342,10 +322,21 @@ fn get_local_type<'a>(cx: &'a LateContext<'_>, local: &'a hir::Local<'_>) -> Opt
342
322
None
343
323
}
344
324
325
+ // ==================================================================
326
+ // Lint definition extraction
327
+ // ==================================================================
328
+
345
329
fn sym_to_string ( sym : Symbol ) -> String {
346
330
sym. as_str ( ) . to_string ( )
347
331
}
348
332
333
+ fn extract_attr_docs_or_lint ( cx : & LateContext < ' _ > , item : & Item < ' _ > ) -> Option < String > {
334
+ extract_attr_docs ( item) . or_else ( || {
335
+ lint_collection_error_item ( cx, item, "could not collect the lint documentation" ) ;
336
+ None
337
+ } )
338
+ }
339
+
349
340
/// This function collects all documentation that has been added to an item using
350
341
/// `#[doc = r""]` attributes. Several attributes are aggravated using line breaks
351
342
///
@@ -367,6 +358,19 @@ fn extract_attr_docs(item: &Item<'_>) -> Option<String> {
367
358
} )
368
359
}
369
360
361
+ fn get_lint_group_or_lint ( cx : & LateContext < ' _ > , lint_name : & str , item : & ' tcx Item < ' _ > ) -> Option < String > {
362
+ let result = cx. lint_store . check_lint_name ( lint_name, Some ( sym:: clippy) ) ;
363
+ if let CheckLintNameResult :: Tool ( Ok ( lint_lst) ) = result {
364
+ get_lint_group ( cx, lint_lst[ 0 ] ) . or_else ( || {
365
+ lint_collection_error_item ( cx, item, "Unable to determine lint group" ) ;
366
+ None
367
+ } )
368
+ } else {
369
+ lint_collection_error_item ( cx, item, "Unable to find lint in lint_store" ) ;
370
+ None
371
+ }
372
+ }
373
+
370
374
fn get_lint_group ( cx : & LateContext < ' _ > , lint_id : LintId ) -> Option < String > {
371
375
for ( group_name, lints, _) in & cx. lint_store . get_lint_groups ( ) {
372
376
if lints. iter ( ) . any ( |x| * x == lint_id) {
@@ -526,19 +530,8 @@ impl<'a, 'hir> ValueTracker<'a, 'hir> {
526
530
}
527
531
}
528
532
529
- fn process_borrow_expr ( & mut self , access_hir_id : hir:: HirId ) {
530
- let borrower: & rustc_hir:: Expr < ' _ > ;
531
- if let Some ( addr_of_expr) = get_parent_expr_for_hir ( self . cx , access_hir_id) {
532
- if let Some ( borrower_expr) = get_parent_expr ( self . cx , addr_of_expr) {
533
- borrower = borrower_expr
534
- } else {
535
- return ;
536
- }
537
- } else {
538
- return ;
539
- }
540
-
541
- match & borrower. kind {
533
+ fn process_borrow_expr ( & mut self , borrower_expr : & ' hir rustc_hir:: Expr < ' hir > ) {
534
+ match & borrower_expr. kind {
542
535
hir:: ExprKind :: Call ( func_expr, ..) => {
543
536
// We only deal with resolved paths as this is the usual case. Other expression kinds like closures
544
537
// etc. are hard to track but might be a worthy improvement in the future
@@ -555,36 +548,45 @@ impl<'a, 'hir> ValueTracker<'a, 'hir> {
555
548
hir:: ExprKind :: MethodCall ( ..) => {
556
549
let msg = format ! (
557
550
"Unsupported borrow in MethodCall at: {}" ,
558
- SerializableSpan :: from_span( self . cx, borrower . span)
551
+ SerializableSpan :: from_span( self . cx, borrower_expr . span)
559
552
) ;
560
553
self . value_mutations . push ( ApplicabilityModifier :: Unknown ( msg) ) ;
561
554
} ,
562
555
_ => {
563
556
let msg = format ! (
564
557
"Unexpected borrow at: {}" ,
565
- SerializableSpan :: from_span( self . cx, borrower . span)
558
+ SerializableSpan :: from_span( self . cx, borrower_expr . span)
566
559
) ;
567
560
self . value_mutations . push ( ApplicabilityModifier :: Unknown ( msg) ) ;
568
561
} ,
569
562
}
570
563
}
564
+
565
+ fn process_consume_expr ( & mut self , consume_expr : & ' hir rustc_hir:: Expr < ' hir > ) {
566
+ // We are only interested in lint emissions. Other types like assignments might be
567
+ // interesting for further use or improvement but are to complex for now.
568
+ if let hir:: ExprKind :: Call ( func_expr, ..) = & consume_expr. kind { }
569
+ }
571
570
}
572
571
573
572
impl < ' a , ' hir > Delegate < ' hir > for ValueTracker < ' a , ' hir > {
574
573
fn consume ( & mut self , _place_with_id : & PlaceWithHirId < ' hir > , expr_id : hir:: HirId , _: ConsumeMode ) {
575
574
if self . is_value_expr ( expr_id) {
576
575
// TODO xFrednet 2021-02-17: Check if lint emission and extract lint ID
577
- if let Some ( hir:: Node :: Expr ( expr) ) = self . cx . tcx . hir ( ) . find ( expr_id) {
578
- let span = SerializableSpan :: from_span ( self . cx , expr. span ) ;
579
- log_to_file ( & format ! ( "- consume {}\n " , span) ) ;
576
+ if let Some ( expr) = get_parent_expr_for_hir ( self . cx , expr_id) {
577
+ log_to_file ( & format ! ( "- consume {:?}\n " , expr) ) ;
580
578
}
581
579
}
582
580
}
583
581
584
582
fn borrow ( & mut self , _place_with_id : & PlaceWithHirId < ' hir > , expr_id : hir:: HirId , bk : BorrowKind ) {
585
- if self . is_value_expr ( expr_id) {
586
- if let BorrowKind :: MutBorrow = bk {
587
- self . process_borrow_expr ( expr_id) ;
583
+ if_chain ! {
584
+ if self . is_value_expr( expr_id) ;
585
+ if let BorrowKind :: MutBorrow = bk;
586
+ if let Some ( addr_of_expr) = get_parent_expr_for_hir( self . cx, expr_id) ;
587
+ if let Some ( borrower_expr) = get_parent_expr( self . cx, addr_of_expr) ;
588
+ then {
589
+ self . process_borrow_expr( borrower_expr) ;
588
590
}
589
591
}
590
592
}
0 commit comments