@@ -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,72 @@ 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 = 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+
21032170 err. emit ( ) ;
21042171 }
21052172
0 commit comments