mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 05:45:12 +00:00
Merge #7907
7907: Autoderef with visibility r=cynecx a=cynecx
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/7841.
I am not sure about the general approach here. Right now this simply tries to check whether the autoderef candidate is reachable from the current module. ~~However this doesn't exactly work with traits (see the `tests::macros::infer_derive_clone_in_core` test, which fails right now).~~ see comment below
Refs:
- `rustc_typeck` checking fields: 66ec64ccf3/compiler/rustc_typeck/src/check/expr.rs (L1610)
r? @flodiebold
Co-authored-by: cynecx <me@cynecx.net>
This commit is contained in:
commit
d7db38fff9
10 changed files with 250 additions and 37 deletions
|
@ -443,27 +443,47 @@ impl<'a> InferenceContext<'a> {
|
|||
},
|
||||
)
|
||||
.find_map(|derefed_ty| {
|
||||
let def_db = self.db.upcast();
|
||||
let module = self.resolver.module();
|
||||
let is_visible = |field_id: &FieldId| {
|
||||
module
|
||||
.map(|mod_id| {
|
||||
self.db.field_visibilities(field_id.parent)[field_id.local_id]
|
||||
.is_visible_from(def_db, mod_id)
|
||||
})
|
||||
.unwrap_or(true)
|
||||
};
|
||||
match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
|
||||
TyKind::Tuple(_, substs) => {
|
||||
name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
|
||||
}
|
||||
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
|
||||
self.db.struct_data(*s).variant_data.field(name).map(|local_id| {
|
||||
let field = FieldId { parent: (*s).into(), local_id };
|
||||
let local_id = self.db.struct_data(*s).variant_data.field(name)?;
|
||||
let field = FieldId { parent: (*s).into(), local_id };
|
||||
if is_visible(&field) {
|
||||
self.write_field_resolution(tgt_expr, field);
|
||||
self.db.field_types((*s).into())[field.local_id]
|
||||
.clone()
|
||||
.subst(¶meters)
|
||||
})
|
||||
Some(
|
||||
self.db.field_types((*s).into())[field.local_id]
|
||||
.clone()
|
||||
.subst(¶meters),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
|
||||
self.db.union_data(*u).variant_data.field(name).map(|local_id| {
|
||||
let field = FieldId { parent: (*u).into(), local_id };
|
||||
let local_id = self.db.union_data(*u).variant_data.field(name)?;
|
||||
let field = FieldId { parent: (*u).into(), local_id };
|
||||
if is_visible(&field) {
|
||||
self.write_field_resolution(tgt_expr, field);
|
||||
self.db.field_types((*u).into())[field.local_id]
|
||||
.clone()
|
||||
.subst(¶meters)
|
||||
})
|
||||
Some(
|
||||
self.db.field_types((*u).into())[field.local_id]
|
||||
.clone()
|
||||
.subst(¶meters),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -828,6 +848,7 @@ impl<'a> InferenceContext<'a> {
|
|||
self.trait_env.clone(),
|
||||
krate,
|
||||
&traits_in_scope,
|
||||
self.resolver.module(),
|
||||
method_name,
|
||||
)
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue