@@ -40,8 +40,7 @@ use rustc_hash::FxHashSet;
4040use rustc_type_ir:: {
4141 AliasTyKind , BoundVarIndexKind , ConstKind , DebruijnIndex , ExistentialPredicate ,
4242 ExistentialProjection , ExistentialTraitRef , FnSig , Interner , OutlivesPredicate , TermKind ,
43- TyKind ,
44- TypeFoldable , TypeVisitableExt , Upcast , UpcastFrom , elaborate,
43+ TyKind , TypeFoldable , TypeVisitableExt , Upcast , UpcastFrom , elaborate,
4544 inherent:: { Clause as _, GenericArgs as _, IntoKind as _, Region as _, Ty as _} ,
4645} ;
4746use smallvec:: SmallVec ;
@@ -1681,10 +1680,16 @@ impl SupertraitsInfo {
16811680 }
16821681}
16831682
1684- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1685- enum TypeParamAssocTypeShorthandError {
1686- AssocTypeNotFound ,
1687- AmbiguousAssocType ,
1683+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
1684+ enum AssocTypeShorthandResolution {
1685+ Resolved ( StoredEarlyBinder < ( TypeAliasId , StoredGenericArgs ) > ) ,
1686+ Ambiguous {
1687+ /// If one resolution belongs to a sub-trait and one to a supertrait, this contains
1688+ /// the sub-trait's resolution. This can be `None` if there is no trait inheritance
1689+ /// relationship between the resolutions.
1690+ sub_trait_resolution : Option < StoredEarlyBinder < ( TypeAliasId , StoredGenericArgs ) > > ,
1691+ } ,
1692+ NotFound ,
16881693 Cycle ,
16891694}
16901695
@@ -1708,7 +1713,7 @@ fn resolve_type_param_assoc_type_shorthand(
17081713 def : GenericDefId ,
17091714 param : TypeParamId ,
17101715 assoc_name : Name ,
1711- ) -> Result < StoredEarlyBinder < ( TypeAliasId , StoredGenericArgs ) > , TypeParamAssocTypeShorthandError > {
1716+ ) -> AssocTypeShorthandResolution {
17121717 let generics = generics ( db, def) ;
17131718 let resolver = def. resolver ( db) ;
17141719 let mut ctx = TyLoweringContext :: new (
@@ -1719,13 +1724,13 @@ fn resolve_type_param_assoc_type_shorthand(
17191724 LifetimeElisionKind :: AnonymousReportError ,
17201725 ) ;
17211726 let interner = ctx. interner ;
1722- let mut result = None ;
17231727 let param_ty = Ty :: new_param (
17241728 interner,
17251729 param,
17261730 generics. type_or_const_param_idx ( param. into ( ) ) . unwrap ( ) as u32 ,
17271731 ) ;
17281732
1733+ let mut this_trait_resolution = None ;
17291734 if let GenericDefId :: TraitId ( containing_trait) = param. parent ( )
17301735 && param. local_id ( ) == GenericParams :: SELF_PARAM_ID_IN_SELF
17311736 {
@@ -1734,10 +1739,11 @@ fn resolve_type_param_assoc_type_shorthand(
17341739 containing_trait. trait_items ( db) . associated_type_by_name ( & assoc_name)
17351740 {
17361741 let args = GenericArgs :: identity_for_item ( interner, containing_trait. into ( ) ) ;
1737- result = Some ( StoredEarlyBinder :: bind ( ( assoc_type, args. store ( ) ) ) ) ;
1742+ this_trait_resolution = Some ( StoredEarlyBinder :: bind ( ( assoc_type, args. store ( ) ) ) ) ;
17381743 }
17391744 }
17401745
1746+ let mut supertraits_resolution = None ;
17411747 for maybe_parent_generics in
17421748 std:: iter:: successors ( Some ( & generics) , |generics| generics. parent_generics ( ) )
17431749 {
@@ -1783,34 +1789,53 @@ fn resolve_type_param_assoc_type_shorthand(
17831789 TypeParamId :: trait_self ( bounded_trait) ,
17841790 assoc_name. clone ( ) ,
17851791 ) ;
1786- let lookup_on_bounded_trait = match lookup_on_bounded_trait {
1787- Ok ( it) => it,
1788- Err (
1789- err @ ( TypeParamAssocTypeShorthandError :: AmbiguousAssocType
1790- | TypeParamAssocTypeShorthandError :: Cycle ) ,
1791- ) => return Err ( * err) ,
1792- Err ( TypeParamAssocTypeShorthandError :: AssocTypeNotFound ) => {
1792+ let assoc_type_and_args = match & lookup_on_bounded_trait {
1793+ AssocTypeShorthandResolution :: Resolved ( trait_ref) => trait_ref,
1794+ AssocTypeShorthandResolution :: Ambiguous {
1795+ sub_trait_resolution : Some ( trait_ref) ,
1796+ } => trait_ref,
1797+ AssocTypeShorthandResolution :: Ambiguous { sub_trait_resolution : None } => {
1798+ return AssocTypeShorthandResolution :: Ambiguous {
1799+ sub_trait_resolution : this_trait_resolution,
1800+ } ;
1801+ }
1802+ AssocTypeShorthandResolution :: NotFound => {
17931803 never ! ( "we checked that the trait defines this assoc type" ) ;
17941804 continue ;
17951805 }
1806+ AssocTypeShorthandResolution :: Cycle => return AssocTypeShorthandResolution :: Cycle ,
17961807 } ;
1797- let ( assoc_type, args) = lookup_on_bounded_trait
1798- . get_with ( |( assoc_type, args) | ( * assoc_type, args. as_ref ( ) ) )
1799- . skip_binder ( ) ;
1800- let args = EarlyBinder :: bind ( args) . instantiate ( interner, bounded_trait_ref. args ) ;
1801- let current_result = StoredEarlyBinder :: bind ( ( assoc_type, args. store ( ) ) ) ;
1802- // If we already have a result, this is an ambiguity - unless this is the same result, then we are fine
1803- // (e.g. rustc allows to write the same bound twice without ambiguity).
1804- if let Some ( existing_result) = result
1805- && existing_result != current_result
1806- {
1807- return Err ( TypeParamAssocTypeShorthandError :: AmbiguousAssocType ) ;
1808+ if let Some ( this_trait_resolution) = this_trait_resolution {
1809+ return AssocTypeShorthandResolution :: Ambiguous {
1810+ sub_trait_resolution : Some ( this_trait_resolution) ,
1811+ } ;
1812+ } else if supertraits_resolution. is_some ( ) {
1813+ return AssocTypeShorthandResolution :: Ambiguous { sub_trait_resolution : None } ;
1814+ } else {
1815+ let ( assoc_type, args) = assoc_type_and_args
1816+ . get_with ( |( assoc_type, args) | ( * assoc_type, args. as_ref ( ) ) )
1817+ . skip_binder ( ) ;
1818+ let args = EarlyBinder :: bind ( args) . instantiate ( interner, bounded_trait_ref. args ) ;
1819+ let current_result = StoredEarlyBinder :: bind ( ( assoc_type, args. store ( ) ) ) ;
1820+ supertraits_resolution = Some ( match lookup_on_bounded_trait {
1821+ AssocTypeShorthandResolution :: Resolved ( _) => {
1822+ AssocTypeShorthandResolution :: Resolved ( current_result)
1823+ }
1824+ AssocTypeShorthandResolution :: Ambiguous { .. } => {
1825+ AssocTypeShorthandResolution :: Ambiguous {
1826+ sub_trait_resolution : Some ( current_result) ,
1827+ }
1828+ }
1829+ AssocTypeShorthandResolution :: NotFound
1830+ | AssocTypeShorthandResolution :: Cycle => unreachable ! ( ) ,
1831+ } ) ;
18081832 }
1809- result = Some ( current_result) ;
18101833 }
18111834 }
18121835
1813- result. ok_or ( TypeParamAssocTypeShorthandError :: AssocTypeNotFound )
1836+ supertraits_resolution
1837+ . or_else ( || this_trait_resolution. map ( AssocTypeShorthandResolution :: Resolved ) )
1838+ . unwrap_or ( AssocTypeShorthandResolution :: NotFound )
18141839}
18151840
18161841fn resolve_type_param_assoc_type_shorthand_cycle_result (
@@ -1819,8 +1844,8 @@ fn resolve_type_param_assoc_type_shorthand_cycle_result(
18191844 _def : GenericDefId ,
18201845 _param : TypeParamId ,
18211846 _assoc_name : Name ,
1822- ) -> Result < StoredEarlyBinder < ( TypeAliasId , StoredGenericArgs ) > , TypeParamAssocTypeShorthandError > {
1823- Err ( TypeParamAssocTypeShorthandError :: Cycle )
1847+ ) -> AssocTypeShorthandResolution {
1848+ AssocTypeShorthandResolution :: Cycle
18241849}
18251850
18261851#[ inline]
@@ -2468,7 +2493,7 @@ fn fn_sig_for_struct_constructor(
24682493 let inputs_and_output =
24692494 Tys :: new_from_iter ( DbInterner :: new_no_crate ( db) , params. chain ( Some ( ret. as_ref ( ) ) ) ) ;
24702495 StoredEarlyBinder :: bind ( StoredPolyFnSig :: new ( Binder :: dummy ( FnSig {
2471- abi : FnAbi :: RustCall ,
2496+ abi : FnAbi :: Rust ,
24722497 c_variadic : false ,
24732498 safety : Safety :: Safe ,
24742499 inputs_and_output,
@@ -2487,7 +2512,7 @@ fn fn_sig_for_enum_variant_constructor(
24872512 let inputs_and_output =
24882513 Tys :: new_from_iter ( DbInterner :: new_no_crate ( db) , params. chain ( Some ( ret. as_ref ( ) ) ) ) ;
24892514 StoredEarlyBinder :: bind ( StoredPolyFnSig :: new ( Binder :: dummy ( FnSig {
2490- abi : FnAbi :: RustCall ,
2515+ abi : FnAbi :: Rust ,
24912516 c_variadic : false ,
24922517 safety : Safety :: Safe ,
24932518 inputs_and_output,
@@ -2569,19 +2594,22 @@ pub(crate) fn associated_ty_item_bounds<'db>(
25692594 EarlyBinder :: bind ( BoundExistentialPredicates :: new_from_slice ( & bounds) )
25702595}
25712596
2572- pub ( crate ) fn associated_type_by_name_including_super_traits < ' db > (
2597+ pub ( crate ) fn associated_type_by_name_including_super_traits_allow_ambiguity < ' db > (
25732598 db : & ' db dyn HirDatabase ,
25742599 trait_ref : TraitRef < ' db > ,
25752600 name : Name ,
25762601) -> Option < ( TypeAliasId , GenericArgs < ' db > ) > {
2577- let assoc_type = resolve_type_param_assoc_type_shorthand (
2578- db,
2579- trait_ref. def_id . 0 . into ( ) ,
2580- TypeParamId :: trait_self ( trait_ref. def_id . 0 ) ,
2581- name. clone ( ) ,
2582- )
2583- . as_ref ( )
2584- . ok ( ) ?;
2602+ let ( AssocTypeShorthandResolution :: Resolved ( assoc_type)
2603+ | AssocTypeShorthandResolution :: Ambiguous { sub_trait_resolution : Some ( assoc_type) } ) =
2604+ resolve_type_param_assoc_type_shorthand (
2605+ db,
2606+ trait_ref. def_id . 0 . into ( ) ,
2607+ TypeParamId :: trait_self ( trait_ref. def_id . 0 ) ,
2608+ name. clone ( ) ,
2609+ )
2610+ else {
2611+ return None ;
2612+ } ;
25852613 let ( assoc_type, trait_args) = assoc_type
25862614 . get_with ( |( assoc_type, trait_args) | ( * assoc_type, trait_args. as_ref ( ) ) )
25872615 . skip_binder ( ) ;
0 commit comments