11use std:: { ops:: Index , sync:: Arc } ;
22
33use la_arena:: ArenaMap ;
4+ use mun_hir_input:: ModuleId ;
45use rustc_hash:: FxHashSet ;
56
67use crate :: {
@@ -24,8 +25,10 @@ mod unify;
2425
2526use crate :: {
2627 expr:: { LiteralFloat , LiteralFloatKind , LiteralInt , LiteralIntKind } ,
28+ has_module:: HasModule ,
2729 ids:: DefWithBodyId ,
28- resolve:: { resolver_for_expr, HasResolver } ,
30+ method_resolution:: lookup_method,
31+ resolve:: { resolver_for_expr, HasResolver , ResolveValueResult } ,
2932 ty:: {
3033 primitives:: { FloatTy , IntTy } ,
3134 TyKind ,
@@ -184,6 +187,13 @@ impl<'a> InferenceResultBuilder<'a> {
184187 }
185188 }
186189
190+ /// Returns the module in which the body is defined.
191+ pub fn module ( & self ) -> ModuleId {
192+ match self . body . owner ( ) {
193+ DefWithBodyId :: FunctionId ( func) => func. module ( self . db . upcast ( ) ) ,
194+ }
195+ }
196+
187197 /// Associate the given `ExprId` with the specified `Ty`.
188198 fn set_expr_type ( & mut self , expr : ExprId , ty : Ty ) {
189199 self . type_of_expr . insert ( expr, ty) ;
@@ -718,25 +728,73 @@ impl<'a> InferenceResultBuilder<'a> {
718728 }
719729 }
720730
731+ fn resolve_assoc_item (
732+ & mut self ,
733+ def : TypeNs ,
734+ path : & Path ,
735+ remaining_index : usize ,
736+ id : ExprId ,
737+ ) -> Option < ValueNs > {
738+ // We can only resolve the last element of the path.
739+ let name = if remaining_index == path. segments . len ( ) - 1 {
740+ & path. segments [ remaining_index]
741+ } else {
742+ return None ;
743+ } ;
744+
745+ // Infer the type of the definitions
746+ let type_for_def_fn = |def| self . db . type_for_def ( def, Namespace :: Types ) ;
747+ let root_ty = match def {
748+ TypeNs :: SelfType ( id) => self . db . type_for_impl_self ( id) ,
749+ TypeNs :: StructId ( id) => type_for_def_fn ( TypableDef :: Struct ( id. into ( ) ) ) ,
750+ TypeNs :: TypeAliasId ( id) => type_for_def_fn ( TypableDef :: TypeAlias ( id. into ( ) ) ) ,
751+ TypeNs :: PrimitiveType ( id) => type_for_def_fn ( TypableDef :: PrimitiveType ( id) ) ,
752+ } ;
753+
754+ // Resolve the value.
755+ let function_id = match lookup_method ( self . db , & root_ty, self . module ( ) , name) {
756+ Ok ( value) => value,
757+ Err ( Some ( value) ) => {
758+ self . diagnostics
759+ . push ( InferenceDiagnostic :: PathIsPrivate { id } ) ;
760+ value
761+ }
762+ _ => return None ,
763+ } ;
764+
765+ Some ( ValueNs :: FunctionId ( function_id) )
766+ }
767+
768+ fn resolve_value_path_inner (
769+ & mut self ,
770+ resolver : & Resolver ,
771+ path : & Path ,
772+ id : ExprId ,
773+ ) -> Option < ValueNs > {
774+ let value_or_partial = resolver. resolve_path_as_value ( self . db . upcast ( ) , path) ?;
775+ match value_or_partial {
776+ ResolveValueResult :: ValueNs ( it, vis) => {
777+ if !vis. is_visible_from ( self . db , self . module ( ) ) {
778+ self . diagnostics
779+ . push ( diagnostics:: InferenceDiagnostic :: PathIsPrivate { id } ) ;
780+ }
781+
782+ Some ( it)
783+ }
784+ ResolveValueResult :: Partial ( def, remaining_index) => {
785+ self . resolve_assoc_item ( def, path, remaining_index, id)
786+ }
787+ }
788+ }
789+
721790 fn infer_path_expr (
722791 & mut self ,
723792 resolver : & Resolver ,
724793 path : & Path ,
725794 id : ExprId ,
726795 check_params : & CheckParams ,
727796 ) -> Option < Ty > {
728- if let Some ( ( value, vis) ) = resolver. resolve_path_as_value_fully ( self . db . upcast ( ) , path) {
729- // Check visibility of this item
730- if !vis. is_visible_from (
731- self . db ,
732- self . resolver
733- . module ( )
734- . expect ( "resolver must have a module to be able to resolve modules" ) ,
735- ) {
736- self . diagnostics
737- . push ( diagnostics:: InferenceDiagnostic :: PathIsPrivate { id } ) ;
738- }
739-
797+ if let Some ( value) = self . resolve_value_path_inner ( resolver, path, id) {
740798 // Match based on what type of value we found
741799 match value {
742800 ValueNs :: ImplSelf ( i) => {
0 commit comments