Skip to content

Commit

Permalink
Skip over structs with no private fields that impl Deref
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 3, 2022
1 parent 2a3fd50 commit 603ffeb
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
11 changes: 8 additions & 3 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions src/test/ui/suggestions/field-access-considering-privacy.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/field-access-considering-privacy.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 603ffeb

Please sign in to comment.