@@ -973,7 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
973
973
error : MethodError < ' tcx > ,
974
974
) {
975
975
let rcvr = & args[ 0 ] ;
976
- let try_alt_rcvr = |err : & mut DiagnosticBuilder < ' _ > , new_rcvr_t| {
976
+ let try_alt_rcvr = |err : & mut DiagnosticBuilder < ' _ > , new_rcvr_t, pre : & str , post : & str | {
977
977
if let Some ( new_rcvr_t) = new_rcvr_t {
978
978
if let Ok ( pick) = self . lookup_probe (
979
979
span,
@@ -986,11 +986,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
986
986
// Make sure the method is defined for the *actual* receiver:
987
987
// we don't want to treat `Box<Self>` as a receiver if
988
988
// it only works because of an autoderef to `&self`
989
- if pick. autoderefs == 0 {
989
+ if pick. autoderefs == 0
990
+ // We don't want to suggest a container type when the missing method is
991
+ // `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is
992
+ // far from what the user really wants.
993
+ && Some ( pick. item . container . id ( ) ) != self . tcx . lang_items ( ) . clone_trait ( )
994
+ {
990
995
err. span_label (
991
996
pick. item . ident . span ,
992
997
& format ! ( "the method is available for `{}` here" , new_rcvr_t) ,
993
998
) ;
999
+ err. multipart_suggestion (
1000
+ "consider wrapping the receiver expression with the appropriate type" ,
1001
+ vec ! [
1002
+ ( rcvr. span. shrink_to_lo( ) , format!( "{}({}" , pre, post) ) ,
1003
+ ( rcvr. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
1004
+ ] ,
1005
+ Applicability :: MaybeIncorrect ,
1006
+ ) ;
994
1007
}
995
1008
}
996
1009
}
@@ -1008,10 +1021,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1008
1021
// Try alternative arbitrary self types that could fulfill this call.
1009
1022
// FIXME: probe for all types that *could* be arbitrary self-types, not
1010
1023
// just this list.
1011
- try_alt_rcvr ( & mut err, self . tcx . mk_lang_item ( rcvr_t, LangItem :: OwnedBox ) ) ;
1012
- try_alt_rcvr ( & mut err, self . tcx . mk_lang_item ( rcvr_t, LangItem :: Pin ) ) ;
1013
- try_alt_rcvr ( & mut err, self . tcx . mk_diagnostic_item ( rcvr_t, sym:: Arc ) ) ;
1014
- try_alt_rcvr ( & mut err, self . tcx . mk_diagnostic_item ( rcvr_t, sym:: Rc ) ) ;
1024
+ for ( rcvr_t, post) in & [
1025
+ ( rcvr_t, "" ) ,
1026
+ ( self . tcx . mk_mut_ref ( & ty:: ReErased , rcvr_t) , "&mut " ) ,
1027
+ ( self . tcx . mk_imm_ref ( & ty:: ReErased , rcvr_t) , "&" ) ,
1028
+ ] {
1029
+ for ( rcvr_t, pre) in & [
1030
+ ( self . tcx . mk_lang_item ( rcvr_t, LangItem :: OwnedBox ) , "Box::new" ) ,
1031
+ ( self . tcx . mk_lang_item ( rcvr_t, LangItem :: Pin ) , "Pin::new" ) ,
1032
+ ( self . tcx . mk_diagnostic_item ( rcvr_t, sym:: Arc ) , "Arc::new" ) ,
1033
+ ( self . tcx . mk_diagnostic_item ( rcvr_t, sym:: Rc ) , "Rc::new" ) ,
1034
+ ] {
1035
+ try_alt_rcvr ( & mut err, * rcvr_t, pre, post) ;
1036
+ }
1037
+ }
1015
1038
}
1016
1039
err. emit ( ) ;
1017
1040
}
0 commit comments