diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-24 22:37:48 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-24 22:37:48 +0000 |
commit | d7db38fff9c251c36d0796309b43678bdf9e5bd8 (patch) | |
tree | 83b422d45c28e3ae9a2eac550ce8a6048bf5fd71 /crates/hir_ty/src/infer | |
parent | 9d81618f11eb403cc0644a22f30648393ec77cf6 (diff) | |
parent | d1156bb52e900c015afd490f509d744c7a5adf10 (diff) |
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: https://github.com/rust-lang/rust/blob/66ec64ccf31883cd2c28d045912a76179c0c6ed2/compiler/rustc_typeck/src/check/expr.rs#L1610
r? @flodiebold
Co-authored-by: cynecx <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 45 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 1 |
2 files changed, 34 insertions, 12 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 19249973c..3f3187ea2 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -443,27 +443,47 @@ impl<'a> InferenceContext<'a> { | |||
443 | }, | 443 | }, |
444 | ) | 444 | ) |
445 | .find_map(|derefed_ty| { | 445 | .find_map(|derefed_ty| { |
446 | let def_db = self.db.upcast(); | ||
447 | let module = self.resolver.module(); | ||
448 | let is_visible = |field_id: &FieldId| { | ||
449 | module | ||
450 | .map(|mod_id| { | ||
451 | self.db.field_visibilities(field_id.parent)[field_id.local_id] | ||
452 | .is_visible_from(def_db, mod_id) | ||
453 | }) | ||
454 | .unwrap_or(true) | ||
455 | }; | ||
446 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { | 456 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
447 | TyKind::Tuple(_, substs) => { | 457 | TyKind::Tuple(_, substs) => { |
448 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 458 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
449 | } | 459 | } |
450 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 460 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
451 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { | 461 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
452 | let field = FieldId { parent: (*s).into(), local_id }; | 462 | let field = FieldId { parent: (*s).into(), local_id }; |
463 | if is_visible(&field) { | ||
453 | self.write_field_resolution(tgt_expr, field); | 464 | self.write_field_resolution(tgt_expr, field); |
454 | self.db.field_types((*s).into())[field.local_id] | 465 | Some( |
455 | .clone() | 466 | self.db.field_types((*s).into())[field.local_id] |
456 | .subst(¶meters) | 467 | .clone() |
457 | }) | 468 | .subst(¶meters), |
469 | ) | ||
470 | } else { | ||
471 | None | ||
472 | } | ||
458 | } | 473 | } |
459 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 474 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
460 | self.db.union_data(*u).variant_data.field(name).map(|local_id| { | 475 | let local_id = self.db.union_data(*u).variant_data.field(name)?; |
461 | let field = FieldId { parent: (*u).into(), local_id }; | 476 | let field = FieldId { parent: (*u).into(), local_id }; |
477 | if is_visible(&field) { | ||
462 | self.write_field_resolution(tgt_expr, field); | 478 | self.write_field_resolution(tgt_expr, field); |
463 | self.db.field_types((*u).into())[field.local_id] | 479 | Some( |
464 | .clone() | 480 | self.db.field_types((*u).into())[field.local_id] |
465 | .subst(¶meters) | 481 | .clone() |
466 | }) | 482 | .subst(¶meters), |
483 | ) | ||
484 | } else { | ||
485 | None | ||
486 | } | ||
467 | } | 487 | } |
468 | _ => None, | 488 | _ => None, |
469 | } | 489 | } |
@@ -828,6 +848,7 @@ impl<'a> InferenceContext<'a> { | |||
828 | self.trait_env.clone(), | 848 | self.trait_env.clone(), |
829 | krate, | 849 | krate, |
830 | &traits_in_scope, | 850 | &traits_in_scope, |
851 | self.resolver.module(), | ||
831 | method_name, | 852 | method_name, |
832 | ) | 853 | ) |
833 | }); | 854 | }); |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 58cce56ab..cefa38509 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -230,6 +230,7 @@ impl<'a> InferenceContext<'a> { | |||
230 | self.trait_env.clone(), | 230 | self.trait_env.clone(), |
231 | krate, | 231 | krate, |
232 | &traits_in_scope, | 232 | &traits_in_scope, |
233 | None, | ||
233 | Some(name), | 234 | Some(name), |
234 | method_resolution::LookupMode::Path, | 235 | method_resolution::LookupMode::Path, |
235 | move |_ty, item| { | 236 | move |_ty, item| { |