Skip over structs with no private fields that impl Deref

This commit is contained in:
Michael Goulet 2022-08-03 07:01:18 +00:00
parent 2a3fd5053f
commit 603ffebd37
3 changed files with 57 additions and 3 deletions

View File

@ -2582,10 +2582,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match base_t.kind() {
ty::Adt(base_def, substs) if !base_def.is_enum() => {
let tcx = self.tcx;
let fields = &base_def.non_enum_variant().fields;
// Some struct, e.g. some that impl `Deref`, have all private fields
// because you're expected to deref them to access the _real_ fields.
// This, for example, will help us suggest accessing a field through a `Box<T>`.
if fields.iter().all(|field| !field.vis.is_accessible_from(mod_id, tcx)) {
continue;
}
return Some((
base_def
.non_enum_variant()
.fields
fields
.iter()
.filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
// For compile-time reasons put a limit on number of fields we search

View File

@ -0,0 +1,35 @@
use a::TyCtxt;
mod a {
use std::ops::Deref;
pub struct TyCtxt<'tcx> {
gcx: &'tcx GlobalCtxt<'tcx>,
}
impl<'tcx> Deref for TyCtxt<'tcx> {
type Target = &'tcx GlobalCtxt<'tcx>;
fn deref(&self) -> &Self::Target {
&self.gcx
}
}
pub struct GlobalCtxt<'tcx> {
pub sess: &'tcx Session,
_t: &'tcx (),
}
pub struct Session {
pub opts: (),
}
}
mod b {
fn foo<'tcx>(tcx: crate::TyCtxt<'tcx>) {
tcx.opts;
//~^ ERROR no field `opts` on type `TyCtxt<'tcx>`
//~| HELP one of the expressions' fields has a field of the same name
}
}
fn main() {}

View File

@ -0,0 +1,14 @@
error[E0609]: no field `opts` on type `TyCtxt<'tcx>`
--> $DIR/field-access-considering-privacy.rs:29:13
|
LL | tcx.opts;
| ^^^^ unknown field
|
help: one of the expressions' fields has a field of the same name
|
LL | tcx.sess.opts;
| +++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0609`.