@@ -31,7 +31,7 @@ use rustc_hir as hir;
31
31
use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
32
32
use rustc_hir:: def_id:: DefId ;
33
33
use rustc_hir:: intravisit:: Visitor ;
34
- use rustc_hir:: { ExprKind , QPath } ;
34
+ use rustc_hir:: { ExprKind , HirId , QPath } ;
35
35
use rustc_infer:: infer;
36
36
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
37
37
use rustc_infer:: infer:: InferOk ;
@@ -1948,7 +1948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1948
1948
"ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, expr_ty={:?}" ,
1949
1949
field, base, expr, expr_t
1950
1950
) ;
1951
- let mut err = self . no_such_field_err ( field, expr_t) ;
1951
+ let mut err = self . no_such_field_err ( field, expr_t, base . hir_id ) ;
1952
1952
1953
1953
match * expr_t. peel_refs ( ) . kind ( ) {
1954
1954
ty:: Array ( _, len) => {
@@ -2186,6 +2186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2186
2186
& self ,
2187
2187
field : Ident ,
2188
2188
expr_t : & ' tcx ty:: TyS < ' tcx > ,
2189
+ id : HirId ,
2189
2190
) -> DiagnosticBuilder < ' _ > {
2190
2191
let span = field. span ;
2191
2192
debug ! ( "no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})" , span, field, expr_t) ;
@@ -2203,9 +2204,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2203
2204
// try to add a suggestion in case the field is a nested field of a field of the Adt
2204
2205
if let Some ( ( fields, substs) ) = self . get_field_candidates ( span, & expr_t) {
2205
2206
for candidate_field in fields. iter ( ) {
2206
- if let Some ( field_path) =
2207
- self . check_for_nested_field ( span, field, candidate_field, substs, vec ! [ ] )
2208
- {
2207
+ if let Some ( field_path) = self . check_for_nested_field (
2208
+ span,
2209
+ field,
2210
+ candidate_field,
2211
+ substs,
2212
+ vec ! [ ] ,
2213
+ self . tcx . parent_module ( id) . to_def_id ( ) ,
2214
+ ) {
2209
2215
let field_path_str = field_path
2210
2216
. iter ( )
2211
2217
. map ( |id| id. name . to_ident_string ( ) )
@@ -2257,6 +2263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2257
2263
candidate_field : & ty:: FieldDef ,
2258
2264
subst : SubstsRef < ' tcx > ,
2259
2265
mut field_path : Vec < Ident > ,
2266
+ id : DefId ,
2260
2267
) -> Option < Vec < Ident > > {
2261
2268
debug ! (
2262
2269
"check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}" ,
@@ -2276,17 +2283,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2276
2283
let field_ty = candidate_field. ty ( self . tcx , subst) ;
2277
2284
if let Some ( ( nested_fields, subst) ) = self . get_field_candidates ( span, & field_ty) {
2278
2285
for field in nested_fields. iter ( ) {
2279
- let ident = field. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) ;
2280
- if ident == target_field {
2281
- return Some ( field_path) ;
2282
- } else {
2286
+ let accessible = field. vis . is_accessible_from ( id, self . tcx ) ;
2287
+ if accessible {
2288
+ let ident = field. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) ;
2289
+ if ident == target_field {
2290
+ return Some ( field_path) ;
2291
+ }
2283
2292
let field_path = field_path. clone ( ) ;
2284
2293
if let Some ( path) = self . check_for_nested_field (
2285
2294
span,
2286
2295
target_field,
2287
2296
field,
2288
2297
subst,
2289
2298
field_path,
2299
+ id,
2290
2300
) {
2291
2301
return Some ( path) ;
2292
2302
}
0 commit comments