@@ -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,72 @@ 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 = self . tcx . erase_late_bound_regions ( ret_ty) ;
2121
+ if !self . can_eq ( self . param_env , ret_ty, adt_ty) {
2122
+ return None ;
2123
+ }
2124
+ // Check for `-> Self`
2125
+ let input_len = fn_sig. inputs ( ) . skip_binder ( ) . len ( ) ;
2126
+ if def. did ( ) == def_id {
2127
+ let order = if item. name . as_str ( ) . starts_with ( "new" ) { 0 } else { 1 } ;
2128
+ Some ( ( order, item. name , input_len) )
2129
+ } else {
2130
+ None
2131
+ }
2132
+ } )
2133
+ . collect :: < Vec < _ > > ( ) ;
2134
+ items. sort_by_key ( |( order, _, _) | * order) ;
2135
+ match & items[ ..] {
2136
+ [ ] => { }
2137
+ [ ( _, name, args) ] => {
2138
+ err. span_suggestion_verbose (
2139
+ span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ,
2140
+ format ! ( "you might have meant to use the `{name}` associated function" , ) ,
2141
+ format ! (
2142
+ "::{name}({})" ,
2143
+ std:: iter:: repeat( "_" ) . take( * args) . collect:: <Vec <_>>( ) . join( ", " )
2144
+ ) ,
2145
+ Applicability :: MaybeIncorrect ,
2146
+ ) ;
2147
+ }
2148
+ _ => {
2149
+ err. span_suggestions (
2150
+ span. shrink_to_hi ( ) . with_hi ( expr_span. hi ( ) ) ,
2151
+ "you might have meant to use an associated function to build this type" ,
2152
+ items
2153
+ . iter ( )
2154
+ . map ( |( _, name, args) | {
2155
+ format ! (
2156
+ "::{name}({})" ,
2157
+ std:: iter:: repeat( "_" )
2158
+ . take( * args)
2159
+ . collect:: <Vec <_>>( )
2160
+ . join( ", " )
2161
+ )
2162
+ } )
2163
+ . collect :: < Vec < String > > ( ) ,
2164
+ Applicability :: MaybeIncorrect ,
2165
+ ) ;
2166
+ }
2167
+ }
2168
+ }
2169
+
2103
2170
err. emit ( ) ;
2104
2171
}
2105
2172
0 commit comments