Change:
Lets consider the following code () : Here, we try to access a property on an object of type . Up to the 1.50 version, the error message was the following : However, since Rust 1.51 and onward, the diagnostic message changed to this: While there is indead a property on the struct, this can't be accessed like that, applying the compiler suggestion implies making the property of public, which is not possible. The compiler should not look at non- properties when searching for properties with a matching name for diagnostic purposes. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
label +A-diagnostics
Related issue:

Discussion:
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; <del> use rustc_hir::{ExprKind, QPath}; </del> <ins> use rustc_hir::{ExprKind, HirId, QPath}; </ins> use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::InferOk;

"ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, expr_ty={:?}", field, base, expr, expr_t ); <del> let mut err = self.no_such_field_err(field, expr_t); </del> <ins> let mut err = self.no_such_field_err(field, expr_t, base.hir_id); </ins> match *expr_t.peel_refs().kind() { ty::Array(_, len) => {

&self, field: Ident, expr_t: &'tcx ty::TyS<'tcx>, <ins> id: HirId, </ins> ) -> DiagnosticBuilder<'_> { let span = field.span; debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);

// try to add a suggestion in case the field is a nested field of a field of the Adt if let Some((fields, substs)) = self.get_field_candidates(span, &expr_t) { for candidate_field in fields.iter() { <del> if let Some(field_path) = self.check_for_nested_field(span, field, candidate_field, substs, vec![]) { </del> <ins> if let Some(field_path) = self.check_for_nested_field( span, field, candidate_field, substs, vec![], self.tcx.parent_module(id).to_def_id(), ) { </ins> let field_path_str = field_path .iter() .map(|id| id.name.to_ident_string())

candidate_field: &ty::FieldDef, subst: SubstsRef<'tcx>, mut field_path: Vec<Ident>, <ins> id: DefId, </ins> ) -> Option<Vec<Ident>> { debug!( "check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",

let field_ty = candidate_field.ty(self.tcx, subst); if let Some((nested_fields, subst)) = self.get_field_candidates(span, &field_ty) { for field in nested_fields.iter() { <del> let ident = field.ident(self.tcx).normalize_to_macros_2_0(); if ident == target_field { return Some(field_path); } else { </del> <ins> let accessible = field.vis.is_accessible_from(id, self.tcx); if accessible { let ident = field.ident(self.tcx).normalize_to_macros_2_0(); if ident == target_field { return Some(field_path); } </ins> let field_path = field_path.clone(); if let Some(path) = self.check_for_nested_field( span,

field, subst, field_path, <ins> id, </ins> ) { return Some(path); }

<ins> // compile-flags: --crate-type lib pub struct S { pub val: string::MyString, } pub fn test(s: S) { dbg!(s.cap) //~ ERROR: no field `cap` on type `S` [E0609] } pub(crate) mod string { pub struct MyString { buf: MyVec, } struct MyVec { cap: usize, } } </ins>

<ins> error[E0609]: no field `cap` on type `S` --> $DIR/private-field.rs:7:12 | LL |     dbg!(s.cap) |            ^^^ unknown field | = note: available fields are: `val` error: aborting due to previous error For more information about this error, try `rustc --explain E0609`. </ins>