From 41b6b372a789d738ec38ef6850e924d0514266e6 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 23 Feb 2022 16:45:58 +0100 Subject: [PATCH] fix: Resolve private fields in type inference --- crates/hir_ty/src/infer.rs | 8 +++++++- crates/hir_ty/src/infer/expr.rs | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 173380654e..0a50df493f 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -13,8 +13,8 @@ //! to certain types. To record this, we use the union-find implementation from //! the `ena` crate, which is extracted from rustc. -use std::ops::Index; use std::sync::Arc; +use std::{collections::hash_map::Entry, ops::Index}; use chalk_ir::{cast::Cast, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags}; use hir_def::{ @@ -459,6 +459,12 @@ impl<'a> InferenceContext<'a> { self.result.field_resolutions.insert(expr, field); } + fn write_field_resolution_if_empty(&mut self, expr: ExprId, field: FieldId) { + if let Entry::Vacant(entry) = self.result.field_resolutions.entry(expr) { + entry.insert(field); + } + } + fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { self.result.variant_resolutions.insert(id, variant); } diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 13f64d6825..b08a9618d8 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -532,6 +532,11 @@ impl<'a> InferenceContext<'a> { .substitute(Interner, ¶meters), ) } else { + // Write down the first field resolution even if it is not visible + // This aids IDE features for private fields like goto def and in + // case of autoderef finding an applicable field, this will be + // overwritten in a following cycle + self.write_field_resolution_if_empty(tgt_expr, field); None } } @@ -546,6 +551,11 @@ impl<'a> InferenceContext<'a> { .substitute(Interner, ¶meters), ) } else { + // Write down the first field resolution even if it is not visible + // This aids IDE features for private fields like goto def and in + // case of autoderef finding an applicable field, this will be + // overwritten in a following cycle + self.write_field_resolution_if_empty(tgt_expr, field); None } }