@@ -18,7 +18,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
1818use rustc_middle:: traits:: util:: supertraits;
1919use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
2020use rustc_middle:: ty:: print:: with_crate_prefix;
21- use rustc_middle:: ty:: { self , DefIdTree , ToPredicate , Ty , TyCtxt , TypeVisitable } ;
21+ use rustc_middle:: ty:: { self , DefIdTree , GenericArgKind , ToPredicate , Ty , TyCtxt , TypeVisitable } ;
2222use rustc_middle:: ty:: { IsSuggestable , ToPolyTraitRef } ;
2323use rustc_span:: symbol:: { kw, sym, Ident } ;
2424use rustc_span:: Symbol ;
@@ -392,28 +392,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
392392 custom_span_label = true ;
393393 }
394394 if static_candidates. len ( ) == 1 {
395- let ty_str =
396- if let Some ( CandidateSource :: Impl ( impl_did) ) = static_candidates. get ( 0 ) {
397- // When the "method" is resolved through dereferencing, we really want the
398- // original type that has the associated function for accurate suggestions.
399- // (#61411)
400- let ty = tcx. at ( span) . type_of ( * impl_did) ;
401- match ( & ty. peel_refs ( ) . kind ( ) , & actual. peel_refs ( ) . kind ( ) ) {
402- ( ty:: Adt ( def, _) , ty:: Adt ( def_actual, _) ) if def == def_actual => {
403- // Use `actual` as it will have more `substs` filled in.
404- self . ty_to_value_string ( actual. peel_refs ( ) )
405- }
406- _ => self . ty_to_value_string ( ty. peel_refs ( ) ) ,
395+ let ( ty_str, placeholders) = if let Some ( CandidateSource :: Impl ( impl_did) ) =
396+ static_candidates. get ( 0 )
397+ {
398+ // When the "method" is resolved through dereferencing, we really want the
399+ // original type that has the associated function for accurate suggestions.
400+ // (#61411)
401+ let ty = tcx. at ( span) . type_of ( * impl_did) ;
402+ match ( & ty. peel_refs ( ) . kind ( ) , & actual. peel_refs ( ) . kind ( ) ) {
403+ ( ty:: Adt ( def, _) , ty:: Adt ( def_actual, substs) ) if def == def_actual => {
404+ // If there are any inferred arguments, (`{integer}`), we shouldn't mark
405+ // this as machine-applicable.
406+ let placeholders = substs
407+ . iter ( )
408+ . filter_map ( |arg| {
409+ if let GenericArgKind :: Type ( ty) = arg. unpack ( ) {
410+ Some ( ty)
411+ } else {
412+ None
413+ }
414+ } )
415+ . any ( |ty| matches ! ( ty. kind( ) , ty:: Infer ( _) ) ) ;
416+ // Use `actual` as it will have more `substs` filled in.
417+ ( self . ty_to_value_string ( actual. peel_refs ( ) ) , placeholders)
407418 }
408- } else {
409- self . ty_to_value_string ( actual. peel_refs ( ) )
410- } ;
419+ _ => ( self . ty_to_value_string ( ty. peel_refs ( ) ) , true ) ,
420+ }
421+ } else {
422+ ( self . ty_to_value_string ( actual. peel_refs ( ) ) , true )
423+ } ;
424+ let applicability = match placeholders {
425+ true => Applicability :: HasPlaceholders ,
426+ false => Applicability :: MachineApplicable ,
427+ } ;
411428 if let SelfSource :: MethodCall ( expr) = source {
412429 err. span_suggestion (
413430 expr. span . to ( span) ,
414431 "use associated function syntax instead" ,
415432 format ! ( "{}::{}" , ty_str, item_name) ,
416- Applicability :: MachineApplicable ,
433+ applicability ,
417434 ) ;
418435 } else {
419436 err. help ( & format ! ( "try with `{}::{}`" , ty_str, item_name, ) ) ;
0 commit comments