Skip to content

Commit 603ffeb

Browse files
Skip over structs with no private fields that impl Deref
1 parent 2a3fd50 commit 603ffeb

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

compiler/rustc_typeck/src/check/expr.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -2582,10 +2582,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25822582
match base_t.kind() {
25832583
ty::Adt(base_def, substs) if !base_def.is_enum() => {
25842584
let tcx = self.tcx;
2585+
let fields = &base_def.non_enum_variant().fields;
2586+
// Some struct, e.g. some that impl `Deref`, have all private fields
2587+
// because you're expected to deref them to access the _real_ fields.
2588+
// This, for example, will help us suggest accessing a field through a `Box<T>`.
2589+
if fields.iter().all(|field| !field.vis.is_accessible_from(mod_id, tcx)) {
2590+
continue;
2591+
}
25852592
return Some((
2586-
base_def
2587-
.non_enum_variant()
2588-
.fields
2593+
fields
25892594
.iter()
25902595
.filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
25912596
// For compile-time reasons put a limit on number of fields we search
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use a::TyCtxt;
2+
3+
mod a {
4+
use std::ops::Deref;
5+
pub struct TyCtxt<'tcx> {
6+
gcx: &'tcx GlobalCtxt<'tcx>,
7+
}
8+
9+
impl<'tcx> Deref for TyCtxt<'tcx> {
10+
type Target = &'tcx GlobalCtxt<'tcx>;
11+
12+
fn deref(&self) -> &Self::Target {
13+
&self.gcx
14+
}
15+
}
16+
17+
pub struct GlobalCtxt<'tcx> {
18+
pub sess: &'tcx Session,
19+
_t: &'tcx (),
20+
}
21+
22+
pub struct Session {
23+
pub opts: (),
24+
}
25+
}
26+
27+
mod b {
28+
fn foo<'tcx>(tcx: crate::TyCtxt<'tcx>) {
29+
tcx.opts;
30+
//~^ ERROR no field `opts` on type `TyCtxt<'tcx>`
31+
//~| HELP one of the expressions' fields has a field of the same name
32+
}
33+
}
34+
35+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0609]: no field `opts` on type `TyCtxt<'tcx>`
2+
--> $DIR/field-access-considering-privacy.rs:29:13
3+
|
4+
LL | tcx.opts;
5+
| ^^^^ unknown field
6+
|
7+
help: one of the expressions' fields has a field of the same name
8+
|
9+
LL | tcx.sess.opts;
10+
| +++++
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0609`.

0 commit comments

Comments
 (0)