@@ -1897,7 +1897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1897
1897
. collect ( ) ;
1898
1898
1899
1899
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) ;
1901
1901
} else {
1902
1902
self . report_missing_fields (
1903
1903
adt_ty,
@@ -2056,6 +2056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2056
2056
& self ,
2057
2057
adt_ty : Ty < ' tcx > ,
2058
2058
span : Span ,
2059
+ expr_span : Span ,
2059
2060
private_fields : Vec < & ty:: FieldDef > ,
2060
2061
used_fields : & ' tcx [ hir:: ExprField < ' tcx > ] ,
2061
2062
) {
@@ -2100,6 +2101,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2100
2101
were = pluralize!( "was" , remaining_private_fields_len) ,
2101
2102
) ) ;
2102
2103
}
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
+
2103
2179
err. emit ( ) ;
2104
2180
}
2105
2181
@@ -2703,7 +2779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2703
2779
self . get_field_candidates_considering_privacy ( span, ty, mod_id, id)
2704
2780
{
2705
2781
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
2707
2783
. into_iter ( )
2708
2784
. filter_map ( |candidate_field| {
2709
2785
self . check_for_nested_field_satisfying (
@@ -2724,6 +2800,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2724
2800
. collect :: < String > ( )
2725
2801
} )
2726
2802
. collect :: < Vec < _ > > ( ) ;
2803
+ candidate_fields. sort ( ) ;
2727
2804
2728
2805
let len = candidate_fields. len ( ) ;
2729
2806
if len > 0 {
0 commit comments