diff options
author | cynecx <[email protected]> | 2021-03-20 18:07:23 +0000 |
---|---|---|
committer | cynecx <[email protected]> | 2021-03-20 18:07:23 +0000 |
commit | b1b456c64254e82c4edf065c9cc526bf8e734d68 (patch) | |
tree | 9a6f46fa0e7f882b5caba4012fb987b745a52315 /crates | |
parent | 30980396afa713a7b877c7962c5b45329230cdc5 (diff) |
hir_ty: check field visibility while iterating through autoderef candidates
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 79bbc5dab..9bf9f87e4 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -442,27 +442,49 @@ impl<'a> InferenceContext<'a> { | |||
442 | }, | 442 | }, |
443 | ) | 443 | ) |
444 | .find_map(|derefed_ty| { | 444 | .find_map(|derefed_ty| { |
445 | let def_db = self.db.upcast(); | ||
446 | let module = self.resolver.module(); | ||
447 | let is_visible = |field_id: &FieldId| { | ||
448 | module | ||
449 | .map(|mod_id| { | ||
450 | self.db.field_visibilities(field_id.parent)[field_id.local_id] | ||
451 | .is_visible_from(def_db, mod_id) | ||
452 | }) | ||
453 | .unwrap_or(true) | ||
454 | }; | ||
445 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { | 455 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
446 | TyKind::Tuple(_, substs) => { | 456 | TyKind::Tuple(_, substs) => { |
447 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 457 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
448 | } | 458 | } |
449 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 459 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
450 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { | 460 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
451 | let field = FieldId { parent: (*s).into(), local_id }; | 461 | let field = FieldId { parent: (*s).into(), local_id }; |
452 | self.write_field_resolution(tgt_expr, field); | 462 | let is_visible_in_ctx = is_visible(&field); |
453 | self.db.field_types((*s).into())[field.local_id] | 463 | self.write_field_resolution(tgt_expr, field); |
454 | .clone() | 464 | if is_visible_in_ctx { |
455 | .subst(¶meters) | 465 | Some( |
456 | }) | 466 | self.db.field_types((*s).into())[field.local_id] |
467 | .clone() | ||
468 | .subst(¶meters), | ||
469 | ) | ||
470 | } else { | ||
471 | None | ||
472 | } | ||
457 | } | 473 | } |
458 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 474 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
459 | 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)?; |
460 | let field = FieldId { parent: (*u).into(), local_id }; | 476 | let field = FieldId { parent: (*u).into(), local_id }; |
461 | self.write_field_resolution(tgt_expr, field); | 477 | let is_visible_in_ctx = is_visible(&field); |
462 | self.db.field_types((*u).into())[field.local_id] | 478 | self.write_field_resolution(tgt_expr, field); |
463 | .clone() | 479 | if is_visible_in_ctx { |
464 | .subst(¶meters) | 480 | Some( |
465 | }) | 481 | self.db.field_types((*u).into())[field.local_id] |
482 | .clone() | ||
483 | .subst(¶meters), | ||
484 | ) | ||
485 | } else { | ||
486 | None | ||
487 | } | ||
466 | } | 488 | } |
467 | _ => None, | 489 | _ => None, |
468 | } | 490 | } |