aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
authorcynecx <[email protected]>2021-03-20 18:07:23 +0000
committercynecx <[email protected]>2021-03-20 18:07:23 +0000
commitb1b456c64254e82c4edf065c9cc526bf8e734d68 (patch)
tree9a6f46fa0e7f882b5caba4012fb987b745a52315 /crates/hir_ty
parent30980396afa713a7b877c7962c5b45329230cdc5 (diff)
hir_ty: check field visibility while iterating through autoderef candidates
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/infer/expr.rs50
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(&parameters) 465 Some(
456 }) 466 self.db.field_types((*s).into())[field.local_id]
467 .clone()
468 .subst(&parameters),
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(&parameters) 480 Some(
465 }) 481 self.db.field_types((*u).into())[field.local_id]
482 .clone()
483 .subst(&parameters),
484 )
485 } else {
486 None
487 }
466 } 488 }
467 _ => None, 489 _ => None,
468 } 490 }