@@ -23,7 +23,7 @@ use rustc_semver::RustcVersion;
2323use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
2424use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
2525use rustc_span:: source_map:: Span ;
26- use rustc_span:: symbol:: sym;
26+ use rustc_span:: symbol:: { sym, Symbol } ;
2727use rustc_target:: abi:: LayoutOf ;
2828use rustc_target:: spec:: abi:: Abi ;
2929use rustc_typeck:: hir_ty_to_ty;
@@ -307,14 +307,33 @@ fn match_type_parameter(cx: &LateContext<'_>, qpath: &QPath<'_>, path: &[&str])
307307 None
308308}
309309
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+
310329fn 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 ( ) {
312331 return Some ( "str" ) ;
313332 }
314- if match_type_parameter ( cx, qpath, & paths :: OS_STRING ) . is_some ( ) {
333+ if match_type_parameter_diagnostic ( cx, qpath, sym :: OsString ) . is_some ( ) {
315334 return Some ( "std::ffi::OsStr" ) ;
316335 }
317- if match_type_parameter ( cx, qpath, & paths :: PATH_BUF ) . is_some ( ) {
336+ if match_type_parameter_diagnostic ( cx, qpath, sym :: PathBuf ) . is_some ( ) {
318337 return Some ( "std::path::Path" ) ;
319338 }
320339 None
@@ -381,7 +400,7 @@ impl Types {
381400 ) ;
382401 return ; // don't recurse into the type
383402 }
384- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
403+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
385404 span_lint_and_help (
386405 cx,
387406 BOX_VEC ,
@@ -393,7 +412,7 @@ impl Types {
393412 return ; // don't recurse into the type
394413 }
395414 } 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 ) {
397416 let mut applicability = Applicability :: MachineApplicable ;
398417 span_lint_and_sugg (
399418 cx,
@@ -445,7 +464,7 @@ impl Types {
445464 ) ;
446465 return ; // don't recurse into the type
447466 }
448- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
467+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
449468 let vec_ty = match & last_path_segment ( qpath) . args . unwrap ( ) . args [ 0 ] {
450469 GenericArg :: Type ( ty) => match & ty. kind {
451470 TyKind :: Path ( qpath) => qpath,
@@ -498,7 +517,7 @@ impl Types {
498517 ) ;
499518 return ; // don't recurse into the type
500519 }
501- if match_type_parameter ( cx, qpath, & paths :: VEC ) . is_some ( ) {
520+ if match_type_parameter_diagnostic ( cx, qpath, sym :: vec_type ) . is_some ( ) {
502521 let vec_ty = match & last_path_segment ( qpath) . args . unwrap ( ) . args [ 0 ] {
503522 GenericArg :: Type ( ty) => match & ty. kind {
504523 TyKind :: Path ( qpath) => qpath,
0 commit comments