@@ -887,15 +887,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
887
887
. find_by_name_and_kind ( self . tcx ( ) , assoc_name, ty:: AssocKind :: Type , trait_def_id)
888
888
. is_some ( )
889
889
}
890
- fn trait_defines_associated_named ( & self , trait_def_id : DefId , assoc_name : Ident ) -> bool {
890
+ fn trait_defines_associated_const_named ( & self , trait_def_id : DefId , assoc_name : Ident ) -> bool {
891
891
self . tcx ( )
892
892
. associated_items ( trait_def_id)
893
- . find_by_name_and_kinds (
894
- self . tcx ( ) ,
895
- assoc_name,
896
- & [ ty:: AssocKind :: Type , ty:: AssocKind :: Const ] ,
897
- trait_def_id,
898
- )
893
+ . find_by_name_and_kind ( self . tcx ( ) , assoc_name, ty:: AssocKind :: Const , trait_def_id)
899
894
. is_some ( )
900
895
}
901
896
@@ -1145,13 +1140,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1145
1140
1146
1141
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
1147
1142
// of calling `filter_by_name_and_kind`.
1148
- let assoc_item = tcx
1149
- . associated_items ( candidate. def_id ( ) )
1150
- . filter_by_name_unhygienic ( assoc_ident. name )
1151
- . find ( |i| {
1152
- ( i . kind == ty :: AssocKind :: Type || i . kind == ty :: AssocKind :: Const )
1153
- && i . ident ( tcx ) . normalize_to_macros_2_0 ( ) == assoc_ident
1154
- } )
1143
+ let find_item_of_kind = |kind| {
1144
+ tcx . associated_items ( candidate. def_id ( ) )
1145
+ . filter_by_name_unhygienic ( assoc_ident. name )
1146
+ . find ( |i| i . kind == kind && i . ident ( tcx ) . normalize_to_macros_2_0 ( ) == assoc_ident )
1147
+ } ;
1148
+ let assoc_item = find_item_of_kind ( ty :: AssocKind :: Type )
1149
+ . or_else ( || find_item_of_kind ( ty :: AssocKind :: Const ) )
1155
1150
. expect ( "missing associated type" ) ;
1156
1151
1157
1152
if !assoc_item. vis . is_accessible_from ( def_scope, tcx) {
@@ -1657,11 +1652,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1657
1652
I : Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
1658
1653
{
1659
1654
let mut matching_candidates = all_candidates ( )
1660
- . filter ( |r| self . trait_defines_associated_named ( r. def_id ( ) , assoc_name) ) ;
1661
-
1662
- let bound = match matching_candidates. next ( ) {
1663
- Some ( bound) => bound,
1664
- None => {
1655
+ . filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) , assoc_name) ) ;
1656
+ let mut const_candidates = all_candidates ( )
1657
+ . filter ( |r| self . trait_defines_associated_const_named ( r. def_id ( ) , assoc_name) ) ;
1658
+
1659
+ let ( bound, next_cand) = match ( matching_candidates. next ( ) , const_candidates. next ( ) ) {
1660
+ ( Some ( bound) , _) => ( bound, matching_candidates. next ( ) ) ,
1661
+ ( None , Some ( bound) ) => ( bound, const_candidates. next ( ) ) ,
1662
+ ( None , None ) => {
1665
1663
self . complain_about_assoc_type_not_found (
1666
1664
all_candidates,
1667
1665
& ty_param_name ( ) ,
@@ -1671,10 +1669,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1671
1669
return Err ( ErrorReported ) ;
1672
1670
}
1673
1671
} ;
1674
-
1675
1672
debug ! ( "one_bound_for_assoc_type: bound = {:?}" , bound) ;
1676
1673
1677
- if let Some ( bound2) = matching_candidates . next ( ) {
1674
+ if let Some ( bound2) = next_cand {
1678
1675
debug ! ( "one_bound_for_assoc_type: bound2 = {:?}" , bound2) ;
1679
1676
1680
1677
let is_equality = is_equality ( ) ;
@@ -1759,6 +1756,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1759
1756
return Err ( ErrorReported ) ;
1760
1757
}
1761
1758
}
1759
+
1762
1760
Ok ( bound)
1763
1761
}
1764
1762
@@ -1893,14 +1891,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1893
1891
1894
1892
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
1895
1893
// of calling `filter_by_name_and_kind`.
1896
- let item = tcx
1897
- . associated_items ( trait_did)
1898
- . in_definition_order ( )
1899
- . find ( |i| {
1900
- i. kind . namespace ( ) == Namespace :: TypeNS
1901
- && i. ident ( tcx) . normalize_to_macros_2_0 ( ) == assoc_ident
1902
- } )
1903
- . expect ( "missing associated type" ) ;
1894
+ let item = tcx. associated_items ( trait_did) . in_definition_order ( ) . find ( |i| {
1895
+ i. kind . namespace ( ) == Namespace :: TypeNS
1896
+ && i. ident ( tcx) . normalize_to_macros_2_0 ( ) == assoc_ident
1897
+ } ) ;
1898
+ // Assume that if it's not matched, there must be a const defined with the same name
1899
+ // but it was used in a type position.
1900
+ let Some ( item) = item else {
1901
+ let msg = format ! ( "found associated const `{assoc_ident}` when type was expected" ) ;
1902
+ tcx. sess . struct_span_err ( span, & msg) . emit ( ) ;
1903
+ return Err ( ErrorReported ) ;
1904
+ } ;
1904
1905
1905
1906
let ty = self . projected_ty_from_poly_trait_ref ( span, item. def_id , assoc_segment, bound) ;
1906
1907
let ty = self . normalize_ty ( span, ty) ;
0 commit comments