22
33use either:: Either ;
44use hir_def:: {
5- GenericDefId , GenericParamId , Lookup , TraitId , TypeParamId ,
5+ AssocItemId , GenericDefId , GenericParamId , HasModule , Lookup , TraitId , TypeParamId ,
66 expr_store:: {
77 ExpressionStore , HygieneId ,
88 path:: {
@@ -19,6 +19,7 @@ use hir_def::{
1919} ;
2020use rustc_type_ir:: {
2121 AliasTerm , AliasTy , AliasTyKind ,
22+ fast_reject:: { TreatParams , simplify_type} ,
2223 inherent:: { GenericArgs as _, Region as _, Ty as _} ,
2324} ;
2425use smallvec:: SmallVec ;
@@ -34,6 +35,7 @@ use crate::{
3435 AssocTypeShorthandResolution , GenericPredicateSource , LifetimeElisionKind ,
3536 PathDiagnosticCallbackData ,
3637 } ,
38+ method_resolution:: InherentImpls ,
3739 next_solver:: {
3840 Binder , Clause , Const , DbInterner , EarlyBinder , ErrorGuaranteed , GenericArg , GenericArgs ,
3941 Predicate , ProjectionPredicate , Region , TraitRef , Ty ,
@@ -520,6 +522,51 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
520522 . skip_binder ( ) ;
521523 ( assoc_type, EarlyBinder :: bind ( trait_args) . instantiate ( interner, impl_trait. args ) )
522524 }
525+ // associated types in inherent impl
526+ Some ( TypeNs :: AdtId ( adt) ) => {
527+ let adt_ty = Ty :: new_adt (
528+ interner,
529+ adt,
530+ GenericArgs :: identity_for_item ( interner, adt. into ( ) ) ,
531+ ) ;
532+ let Some ( simplified) = simplify_type ( interner, adt_ty, TreatParams :: AsRigid ) else {
533+ return error_ty ( ) ;
534+ } ;
535+
536+ let module = adt. module ( db) ;
537+ let krate = module. krate ( db) ;
538+ let block = module. block ( db) ;
539+
540+ let mut found_alias = None ;
541+ InherentImpls :: for_each_crate_and_block ( db, krate, block, & mut |impls| {
542+ if found_alias. is_some ( ) {
543+ return ;
544+ }
545+ for & impl_id in impls. for_self_ty ( & simplified) {
546+ // skip trait impl, only need inherent impl
547+ if db. impl_signature ( impl_id) . target_trait . is_some ( ) {
548+ continue ;
549+ }
550+ for ( name, item) in impl_id. impl_items ( db) . items . iter ( ) {
551+ if name == assoc_name
552+ && let AssocItemId :: TypeAliasId ( alias_id) = item
553+ {
554+ found_alias = Some ( * alias_id) ;
555+ break ;
556+ }
557+ }
558+ if found_alias. is_some ( ) {
559+ break ;
560+ }
561+ }
562+ } ) ;
563+
564+ let Some ( alias_id) = found_alias else {
565+ return error_ty ( ) ;
566+ } ;
567+
568+ return self . lower_path_inner ( TyDefId :: TypeAliasId ( alias_id) , infer_args) ;
569+ }
523570 _ => return error_ty ( ) ,
524571 } ;
525572
0 commit comments