Skip over structs with no private fields that impl Deref
This commit is contained in:
parent
2a3fd5053f
commit
603ffebd37
@ -2582,10 +2582,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
match base_t.kind() {
|
match base_t.kind() {
|
||||||
ty::Adt(base_def, substs) if !base_def.is_enum() => {
|
ty::Adt(base_def, substs) if !base_def.is_enum() => {
|
||||||
let tcx = self.tcx;
|
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((
|
return Some((
|
||||||
base_def
|
fields
|
||||||
.non_enum_variant()
|
|
||||||
.fields
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
|
.filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
|
||||||
// For compile-time reasons put a limit on number of fields we search
|
// For compile-time reasons put a limit on number of fields we search
|
||||||
|
35
src/test/ui/suggestions/field-access-considering-privacy.rs
Normal file
35
src/test/ui/suggestions/field-access-considering-privacy.rs
Normal 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() {}
|
@ -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`.
|
Loading…
x
Reference in New Issue
Block a user