@@ -13,7 +13,6 @@ use rustc_hir::{
1313use rustc_infer:: infer:: { self , TyCtxtInferExt } ;
1414use rustc_infer:: traits;
1515use rustc_middle:: lint:: in_external_macro;
16- use rustc_middle:: ty:: subst:: GenericArgKind ;
1716use rustc_middle:: ty:: { self , Binder , IsSuggestable , Subst , ToPredicate , Ty } ;
1817use rustc_span:: symbol:: sym;
1918use rustc_span:: Span ;
@@ -238,25 +237,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
238237 ) ;
239238 }
240239 }
241- } else if found. to_string ( ) . starts_with ( "Option<" )
242- && expected. to_string ( ) == "Option<&str>"
240+ } else if let ty:: Adt ( found_adt, found_substs) = found. kind ( )
241+ && self . tcx . is_diagnostic_item ( sym:: Option , found_adt. did ( ) )
242+ && let ty:: Adt ( expected_adt, expected_substs) = expected. kind ( )
243+ && self . tcx . is_diagnostic_item ( sym:: Option , expected_adt. did ( ) )
244+ && let ty:: Ref ( _, inner_ty, _) = expected_substs. type_at ( 0 ) . kind ( )
245+ && inner_ty. is_str ( )
243246 {
244- if let ty:: Adt ( _def , subst ) = found . kind ( ) {
245- if subst . len ( ) != 0 {
246- if let GenericArgKind :: Type ( ty ) = subst [ 0 ] . unpack ( ) {
247- let peeled = ty . peel_refs ( ) . to_string ( ) ;
248- if peeled == "String" {
249- let ref_cnt = ty . to_string ( ) . len ( ) - peeled . len ( ) ;
250- let result = format ! ( ".map(|x| &*{}x)" , "*" . repeat ( ref_cnt ) ) ;
251- err . span_suggestion_verbose (
252- expr . span . shrink_to_hi ( ) ,
253- "try converting the passed type into a `&str`" ,
254- result ,
255- Applicability :: MaybeIncorrect ,
256- ) ;
257- }
258- }
259- }
247+ let ty = found_substs . type_at ( 0 ) ;
248+ let mut peeled = ty ;
249+ let mut ref_cnt = 0 ;
250+ while let ty :: Ref ( _ , inner , _ ) = peeled . kind ( ) {
251+ peeled = * inner ;
252+ ref_cnt += 1 ;
253+ }
254+ if let ty :: Adt ( adt , _ ) = peeled . kind ( )
255+ && self . tcx . is_diagnostic_item ( sym :: String , adt . did ( ) )
256+ {
257+ err . span_suggestion_verbose (
258+ expr . span . shrink_to_hi ( ) ,
259+ "try converting the passed type into a `&str`" ,
260+ format ! ( ".map(|x| &*{}x)" , "*" . repeat ( ref_cnt ) ) ,
261+ Applicability :: MaybeIncorrect ,
262+ ) ;
260263 }
261264 }
262265 }
0 commit comments