@@ -466,21 +466,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
466466 borrow_removal_span,
467467 } ) ;
468468 return true ;
469- } else if let Some ( ( deref_ty, _) ) =
470- self . autoderef ( expr. span , found_ty_inner) . silence_errors ( ) . nth ( 1 )
471- && self . can_eq ( self . param_env , deref_ty, peeled)
472- && error_tys_equate_as_ref
473- {
474- let sugg = prefix_wrap ( ".as_deref()" ) ;
475- err. subdiagnostic ( errors:: SuggestConvertViaMethod {
476- span : expr. span . shrink_to_hi ( ) ,
477- sugg,
478- expected,
479- found,
480- borrow_removal_span,
481- } ) ;
482- return true ;
483- } else if let ty:: Adt ( adt, _) = found_ty_inner. peel_refs ( ) . kind ( )
469+ } else if let ty:: Ref ( _, peeled_found_ty, _) = found_ty_inner. kind ( )
470+ && let ty:: Adt ( adt, _) = peeled_found_ty. peel_refs ( ) . kind ( )
484471 && self . tcx . is_lang_item ( adt. did ( ) , LangItem :: String )
485472 && peeled. is_str ( )
486473 // `Result::map`, conversely, does not take ref of the error type.
@@ -496,12 +483,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
496483 Applicability :: MachineApplicable ,
497484 ) ;
498485 return true ;
486+ } else {
487+ if !error_tys_equate_as_ref {
488+ return false ;
489+ }
490+ let mut steps = self . autoderef ( expr. span , found_ty_inner) . silence_errors ( ) ;
491+ if let Some ( ( deref_ty, _) ) = steps. nth ( 1 )
492+ && self . can_eq ( self . param_env , deref_ty, peeled)
493+ {
494+ let sugg = prefix_wrap ( ".as_deref()" ) ;
495+ err. subdiagnostic ( errors:: SuggestConvertViaMethod {
496+ span : expr. span . shrink_to_hi ( ) ,
497+ sugg,
498+ expected,
499+ found,
500+ borrow_removal_span,
501+ } ) ;
502+ return true ;
503+ }
504+ for ( deref_ty, n_step) in steps {
505+ if self . can_eq ( self . param_env , deref_ty, peeled) {
506+ let explicit_deref = "*" . repeat ( n_step) ;
507+ let sugg = prefix_wrap ( & format ! ( ".map(|v| &{explicit_deref}v)" ) ) ;
508+ err. subdiagnostic ( errors:: SuggestConvertViaMethod {
509+ span : expr. span . shrink_to_hi ( ) ,
510+ sugg,
511+ expected,
512+ found,
513+ borrow_removal_span,
514+ } ) ;
515+ return true ;
516+ }
517+ }
499518 }
500519 }
501520
502521 false
503522 }
504523
524+ /// If `ty` is `Option<T>`, returns `T, T, None`.
525+ /// If `ty` is `Result<T, E>`, returns `T, T, Some(E, E)`.
526+ /// Otherwise, returns `None`.
505527 fn deconstruct_option_or_result (
506528 & self ,
507529 found_ty : Ty < ' tcx > ,
0 commit comments