@@ -1897,7 +1897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18971897 . collect ( ) ;
18981898
18991899 if !private_fields. is_empty ( ) {
1900- self . report_private_fields ( adt_ty, span, private_fields, ast_fields) ;
1900+ self . report_private_fields ( adt_ty, span, expr . span , private_fields, ast_fields) ;
19011901 } else {
19021902 self . report_missing_fields (
19031903 adt_ty,
@@ -2056,6 +2056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20562056 & self ,
20572057 adt_ty : Ty < ' tcx > ,
20582058 span : Span ,
2059+ expr_span : Span ,
20592060 private_fields : Vec < & ty:: FieldDef > ,
20602061 used_fields : & ' tcx [ hir:: ExprField < ' tcx > ] ,
20612062 ) {
@@ -2100,6 +2101,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21002101 were = pluralize!( "was" , remaining_private_fields_len) ,
21012102 ) ) ;
21022103 }
2104+
2105+ if let ty:: Adt ( def, _) = adt_ty. kind ( ) {
2106+ let def_id = def. did ( ) ;
2107+ let mut items = self
2108+ . tcx
2109+ . inherent_impls ( def_id)
2110+ . iter ( )
2111+ . flat_map ( |i| self . tcx . associated_items ( i) . in_definition_order ( ) )
2112+ // Only assoc fn with no receivers.
2113+ . filter ( |item| {
2114+ matches ! ( item. kind, ty:: AssocKind :: Fn ) && !item. fn_has_self_parameter
2115+ } )
2116+ . filter_map ( |item| {
2117+ // Only assoc fns that return `Self`
2118+ let fn_sig = self . tcx . fn_sig ( item. def_id ) . skip_binder ( ) ;
2119+ let ret_ty = fn_sig. output ( ) ;
2120+ let ret_ty =
2121+ self . tcx . normalize_erasing_late_bound_regions ( self . param_env , ret_ty) ;
2122+ if !self . can_eq ( self . param_env , ret_ty, adt_ty) {
2123+ return None ;
2124+ }
2125+ let input_len = fn_sig. inputs ( ) . skip_binder ( ) . len ( ) ;
2126+ let order = !item. name . as_str ( ) . starts_with ( "new" ) ;
2127+ Some ( ( order, item. name , input_len) )
2128+ } )
2129+ . collect :: < Vec < _ > > ( ) ;
2130+ items. sort_by_key ( |( order, _, _) | * order) ;
2131+ let suggestion = |name, args| {
2132+ format ! (
2133+ "::{name}({})" ,
2134+ std:: iter:: repeat( "_" ) . take( args) . collect:: <Vec <_>>( ) . join( ", " )
2135+ )
2136+ } ;
2137+ match & items[ ..] {
2138+ [ ] => { }
2139+ [ ( _, name, args) ] => {
2140+ err. span_suggestion_verbose (
2141+ span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ,
2142+ format ! ( "you might have meant to use the `{name}` associated function" ) ,
2143+ suggestion ( name, * args) ,
2144+ Applicability :: MaybeIncorrect ,
2145+ ) ;
2146+ }
2147+ _ => {
2148+ err. span_suggestions (
2149+ span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ,
2150+ "you might have meant to use an associated function to build this type" ,
2151+ items
2152+ . iter ( )
2153+ . map ( |( _, name, args) | suggestion ( name, * args) )
2154+ . collect :: < Vec < String > > ( ) ,
2155+ Applicability :: MaybeIncorrect ,
2156+ ) ;
2157+ }
2158+ }
2159+ if let Some ( default_trait) = self . tcx . get_diagnostic_item ( sym:: Default )
2160+ && self
2161+ . infcx
2162+ . type_implements_trait ( default_trait, [ adt_ty] , self . param_env )
2163+ . may_apply ( )
2164+ {
2165+ err. multipart_suggestion (
2166+ "consider using the `Default` trait" ,
2167+ vec ! [
2168+ ( span. shrink_to_lo( ) , "<" . to_string( ) ) ,
2169+ (
2170+ span. shrink_to_hi( ) . with_hi( expr_span. hi( ) ) ,
2171+ " as std::default::Default>::default()" . to_string( ) ,
2172+ ) ,
2173+ ] ,
2174+ Applicability :: MaybeIncorrect ,
2175+ ) ;
2176+ }
2177+ }
2178+
21032179 err. emit ( ) ;
21042180 }
21052181
@@ -2703,7 +2779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27032779 self . get_field_candidates_considering_privacy ( span, ty, mod_id, id)
27042780 {
27052781 let field_names = found_fields. iter ( ) . map ( |field| field. name ) . collect :: < Vec < _ > > ( ) ;
2706- let candidate_fields: Vec < _ > = found_fields
2782+ let mut candidate_fields: Vec < _ > = found_fields
27072783 . into_iter ( )
27082784 . filter_map ( |candidate_field| {
27092785 self . check_for_nested_field_satisfying (
@@ -2724,6 +2800,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27242800 . collect :: < String > ( )
27252801 } )
27262802 . collect :: < Vec < _ > > ( ) ;
2803+ candidate_fields. sort ( ) ;
27272804
27282805 let len = candidate_fields. len ( ) ;
27292806 if len > 0 {
0 commit comments