@@ -23,7 +23,7 @@ use rustc_semver::RustcVersion;
23
23
use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
24
24
use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
25
25
use rustc_span:: source_map:: Span ;
26
- use rustc_span:: symbol:: sym;
26
+ use rustc_span:: symbol:: { sym, Symbol } ;
27
27
use rustc_target:: abi:: LayoutOf ;
28
28
use rustc_target:: spec:: abi:: Abi ;
29
29
use rustc_typeck:: hir_ty_to_ty;
@@ -307,14 +307,33 @@ fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str])
307
307
None
308
308
}
309
309
310
+ /// Checks if `qpath` has last segment with type parameter matching `diagnostic`
311
+ fn match_type_parameter_diagnostic ( cx : & LateContext < ' _ > , qpath : & QPath < ' _ > , diagnostic : Symbol ) -> Option < Span > {
312
+ let last = last_path_segment ( qpath) ;
313
+ if_chain ! {
314
+ if let Some ( ref params) = last. args;
315
+ if !params. parenthesized;
316
+ if let Some ( ty) = params. args. iter( ) . find_map( |arg| match arg {
317
+ GenericArg :: Type ( ty) => Some ( ty) ,
318
+ _ => None ,
319
+ } ) ;
320
+ if let TyKind :: Path ( ref qpath) = ty. kind;
321
+ if cx. qpath_res( qpath, ty. hir_id) . opt_def_id( ) == cx. tcx. get_diagnostic_item( diagnostic) ;
322
+ then {
323
+ return Some ( ty. span) ;
324
+ }
325
+ }
326
+ None
327
+ }
328
+
310
329
fn match_buffer_type ( cx : & LateContext < ' _ > , qpath : & QPath < ' _ > ) -> Option < & ' static str > {
311
- if match_type_parameter ( cx, qpath, & paths :: STRING ) . is_some ( ) {
330
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: string_type ) . is_some ( ) {
312
331
return Some ( "str" ) ;
313
332
}
314
- if match_type_parameter ( cx, qpath, & paths :: OS_STRING ) . is_some ( ) {
333
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: OsString ) . is_some ( ) {
315
334
return Some ( "std::ffi::OsStr" ) ;
316
335
}
317
- if match_type_parameter ( cx, qpath, & paths :: PATH_BUF ) . is_some ( ) {
336
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: PathBuf ) . is_some ( ) {
318
337
return Some ( "std::path::Path" ) ;
319
338
}
320
339
None
@@ -381,7 +400,7 @@ impl Types {
381
400
) ;
382
401
return ; // don't recurse into the type
383
402
}
384
- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
403
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
385
404
span_lint_and_help (
386
405
cx,
387
406
BOX_VEC ,
@@ -393,7 +412,7 @@ impl Types {
393
412
return ; // don't recurse into the type
394
413
}
395
414
} else if cx. tcx . is_diagnostic_item ( sym:: Rc , def_id) {
396
- if let Some ( span) = match_type_parameter ( cx, qpath, & paths :: RC ) {
415
+ if let Some ( span) = match_type_parameter_diagnostic ( cx, qpath, sym :: Rc ) {
397
416
let mut applicability = Applicability :: MachineApplicable ;
398
417
span_lint_and_sugg (
399
418
cx,
@@ -445,7 +464,7 @@ impl Types {
445
464
) ;
446
465
return ; // don't recurse into the type
447
466
}
448
- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
467
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
449
468
let vec_ty = match & last_path_segment ( qpath) . args . unwrap ( ) . args [ 0 ] {
450
469
GenericArg :: Type ( ty) => match & ty. kind {
451
470
TyKind :: Path ( qpath) => qpath,
@@ -498,7 +517,7 @@ impl Types {
498
517
) ;
499
518
return ; // don't recurse into the type
500
519
}
501
- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
520
+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
502
521
let vec_ty = match & last_path_segment ( qpath) . args . unwrap ( ) . args [ 0 ] {
503
522
GenericArg :: Type ( ty) => match & ty. kind {
504
523
TyKind :: Path ( qpath) => qpath,
0 commit comments