@@ -887,15 +887,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
887887 . find_by_name_and_kind ( self . tcx ( ) , assoc_name, ty:: AssocKind :: Type , trait_def_id)
888888 . is_some ( )
889889 }
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 {
891891 self . tcx ( )
892892 . 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)
899894 . is_some ( )
900895 }
901896
@@ -1145,13 +1140,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11451140
11461141 // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
11471142 // 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 ) )
11551150 . expect ( "missing associated type" ) ;
11561151
11571152 if !assoc_item. vis . is_accessible_from ( def_scope, tcx) {
@@ -1657,11 +1652,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16571652 I : Iterator < Item = ty:: PolyTraitRef < ' tcx > > ,
16581653 {
16591654 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 ) => {
16651663 self . complain_about_assoc_type_not_found (
16661664 all_candidates,
16671665 & ty_param_name ( ) ,
@@ -1671,10 +1669,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16711669 return Err ( ErrorReported ) ;
16721670 }
16731671 } ;
1674-
16751672 debug ! ( "one_bound_for_assoc_type: bound = {:?}" , bound) ;
16761673
1677- if let Some ( bound2) = matching_candidates . next ( ) {
1674+ if let Some ( bound2) = next_cand {
16781675 debug ! ( "one_bound_for_assoc_type: bound2 = {:?}" , bound2) ;
16791676
16801677 let is_equality = is_equality ( ) ;
@@ -1759,6 +1756,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17591756 return Err ( ErrorReported ) ;
17601757 }
17611758 }
1759+
17621760 Ok ( bound)
17631761 }
17641762
@@ -1893,14 +1891,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18931891
18941892 // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
18951893 // 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+ } ;
19041905
19051906 let ty = self . projected_ty_from_poly_trait_ref ( span, item. def_id , assoc_segment, bound) ;
19061907 let ty = self . normalize_ty ( span, ty) ;
0 commit comments