@@ -21,7 +21,6 @@ use crate::errors::{
2121} ;
2222use crate :: type_error_struct;
2323
24- use super :: suggest_call_constructor;
2524use crate :: errors:: { AddressOfTemporaryTaken , ReturnStmtOutsideOfFnBody , StructExprNonExhaustive } ;
2625use rustc_ast as ast;
2726use rustc_data_structures:: fx:: FxHashMap ;
@@ -44,7 +43,7 @@ use rustc_middle::middle::stability;
4443use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
4544use rustc_middle:: ty:: error:: TypeError :: FieldMisMatch ;
4645use rustc_middle:: ty:: subst:: SubstsRef ;
47- use rustc_middle:: ty:: { self , AdtKind , DefIdTree , Ty , TypeVisitable } ;
46+ use rustc_middle:: ty:: { self , AdtKind , Ty , TypeVisitable } ;
4847use rustc_session:: parse:: feature_err;
4948use rustc_span:: hygiene:: DesugaringKind ;
5049use rustc_span:: lev_distance:: find_best_match_for_name;
@@ -2280,35 +2279,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22802279 self . tcx ( ) . ty_error ( )
22812280 }
22822281
2283- fn check_call_constructor (
2284- & self ,
2285- err : & mut Diagnostic ,
2286- base : & ' tcx hir:: Expr < ' tcx > ,
2287- def_id : DefId ,
2288- ) {
2289- if let Some ( local_id) = def_id. as_local ( ) {
2290- let hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( local_id) ;
2291- let node = self . tcx . hir ( ) . get ( hir_id) ;
2292-
2293- if let Some ( fields) = node. tuple_fields ( ) {
2294- let kind = match self . tcx . opt_def_kind ( local_id) {
2295- Some ( DefKind :: Ctor ( of, _) ) => of,
2296- _ => return ,
2297- } ;
2298-
2299- suggest_call_constructor ( base. span , kind, fields. len ( ) , err) ;
2300- }
2301- } else {
2302- // The logic here isn't smart but `associated_item_def_ids`
2303- // doesn't work nicely on local.
2304- if let DefKind :: Ctor ( of, _) = self . tcx . def_kind ( def_id) {
2305- let parent_def_id = self . tcx . parent ( def_id) ;
2306- let fields = self . tcx . associated_item_def_ids ( parent_def_id) ;
2307- suggest_call_constructor ( base. span , of, fields. len ( ) , err) ;
2308- }
2309- }
2310- }
2311-
23122282 fn suggest_await_on_field_access (
23132283 & self ,
23142284 err : & mut Diagnostic ,
@@ -2378,12 +2348,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23782348 ty:: Opaque ( _, _) => {
23792349 self . suggest_await_on_field_access ( & mut err, ident, base, base_ty. peel_refs ( ) ) ;
23802350 }
2381- ty:: FnDef ( def_id, _) => {
2382- self . check_call_constructor ( & mut err, base, def_id) ;
2383- }
23842351 _ => { }
23852352 }
23862353
2354+ self . suggest_fn_call ( & mut err, base, base_ty, |output_ty| {
2355+ if let ty:: Adt ( def, _) = output_ty. kind ( ) && !def. is_enum ( ) {
2356+ def. non_enum_variant ( ) . fields . iter ( ) . any ( |field| {
2357+ field. ident ( self . tcx ) == ident
2358+ && field. vis . is_accessible_from ( expr. hir_id . owner . to_def_id ( ) , self . tcx )
2359+ } )
2360+ } else if let ty:: Tuple ( tys) = output_ty. kind ( )
2361+ && let Ok ( idx) = ident. as_str ( ) . parse :: < usize > ( )
2362+ {
2363+ idx < tys. len ( )
2364+ } else {
2365+ false
2366+ }
2367+ } ) ;
2368+
23872369 if ident. name == kw:: Await {
23882370 // We know by construction that `<expr>.await` is either on Rust 2015
23892371 // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
0 commit comments