@@ -153,7 +153,7 @@ pub trait HirTyLowerer<'tcx> {
153153 assoc_name : Ident ,
154154 ) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
155155
156- /// Lower an associated type (from a trait) to a projection.
156+ /// Lower an associated type/const (from a trait) to a projection.
157157 ///
158158 /// This method has to be defined by the concrete lowering context because
159159 /// dealing with higher-ranked trait references depends on its capabilities:
@@ -165,26 +165,6 @@ pub trait HirTyLowerer<'tcx> {
165165 ///
166166 /// The canonical example of this is associated type `T::P` where `T` is a type
167167 /// param constrained by `T: for<'a> Trait<'a>` and where `Trait` defines `P`.
168- fn lower_assoc_ty (
169- & self ,
170- span : Span ,
171- item_def_id : DefId ,
172- item_segment : & hir:: PathSegment < ' tcx > ,
173- poly_trait_ref : ty:: PolyTraitRef < ' tcx > ,
174- ) -> Ty < ' tcx > ;
175-
176- /// Lower an associated constant (from a trait) to a [`ty::Const`].
177- fn lower_assoc_const (
178- & self ,
179- span : Span ,
180- item_def_id : DefId ,
181- item_segment : & hir:: PathSegment < ' tcx > ,
182- poly_trait_ref : ty:: PolyTraitRef < ' tcx > ,
183- ) -> Const < ' tcx > ;
184-
185- /// Helper function; use [`Self::lower_assoc_ty`] or [`Self::lower_assoc_const`] instead.
186- ///
187- /// The logic for lowering associated items that is the same between types and consts.
188168 fn lower_assoc_shared (
189169 & self ,
190170 span : Span ,
@@ -298,9 +278,8 @@ impl LowerAssocMode {
298278
299279#[ derive( Debug , Clone , Copy ) ]
300280enum LoweredAssoc < ' tcx > {
301- Type ( Ty < ' tcx > , DefId ) ,
281+ Term ( DefId , GenericArgsRef < ' tcx > ) ,
302282 Variant { adt : Ty < ' tcx > , variant_did : DefId } ,
303- Const ( Const < ' tcx > ) ,
304283}
305284
306285/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -1184,6 +1163,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11841163 assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
11851164 permit_variants : bool ,
11861165 ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1166+ let tcx = self . tcx ( ) ;
11871167 match self . lower_assoc_path_shared (
11881168 hir_ref_id,
11891169 span,
@@ -1192,9 +1172,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11921172 assoc_segment,
11931173 LowerAssocMode :: Type { permit_variants } ,
11941174 ) ? {
1195- LoweredAssoc :: Type ( ty, def_id) => Ok ( ( ty, DefKind :: AssocTy , def_id) ) ,
1175+ LoweredAssoc :: Term ( def_id, args) => {
1176+ let assoc = tcx. associated_item ( def_id) ;
1177+ let ty = if matches ! ( assoc, ty:: AssocItem {
1178+ container: ty:: AssocItemContainer :: Impl ,
1179+ trait_item_def_id: None ,
1180+ ..
1181+ } ) {
1182+ Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new_from_args ( tcx, def_id, args) )
1183+ } else {
1184+ Ty :: new_projection_from_args ( tcx, def_id, args)
1185+ } ;
1186+ Ok ( ( ty, DefKind :: AssocTy , def_id) )
1187+ }
11961188 LoweredAssoc :: Variant { adt, variant_did } => Ok ( ( adt, DefKind :: Variant , variant_did) ) ,
1197- LoweredAssoc :: Const ( _) => unreachable ! ( "lowered assoc type to const somehow" ) ,
11981189 }
11991190 }
12001191
@@ -1207,21 +1198,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12071198 qself : & ' tcx hir:: Ty < ' tcx > ,
12081199 assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
12091200 ) -> Result < Const < ' tcx > , ErrorGuaranteed > {
1210- match self . lower_assoc_path_shared (
1201+ let tcx = self . tcx ( ) ;
1202+ let ( def_id, args) = match self . lower_assoc_path_shared (
12111203 hir_ref_id,
12121204 span,
12131205 qself_ty,
12141206 qself,
12151207 assoc_segment,
12161208 LowerAssocMode :: Const ,
12171209 ) ? {
1218- LoweredAssoc :: Type ( ..) => unreachable ! ( "lowered assoc const to type somehow" ) ,
1219- LoweredAssoc :: Variant { adt : _, variant_did } => {
1220- let uv = ty:: UnevaluatedConst :: new ( variant_did, ty:: List :: empty ( ) ) ;
1221- Ok ( Const :: new_unevaluated ( self . tcx ( ) , uv) )
1210+ LoweredAssoc :: Term ( def_id, args) => {
1211+ if !tcx. associated_item ( def_id) . is_type_const_capable ( tcx) {
1212+ let mut err = tcx. dcx ( ) . struct_span_err (
1213+ span,
1214+ "use of trait associated const without `#[type_const]`" ,
1215+ ) ;
1216+ err. note ( "the declaration in the trait must be marked with `#[type_const]`" ) ;
1217+ return Err ( err. emit ( ) ) ;
1218+ }
1219+ ( def_id, args)
12221220 }
1223- LoweredAssoc :: Const ( ct) => Ok ( ct) ,
1224- }
1221+ LoweredAssoc :: Variant { adt : _, variant_did } => ( variant_did, ty:: List :: empty ( ) ) ,
1222+ } ;
1223+ Ok ( Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( def_id, args) ) )
12251224 }
12261225
12271226 #[ instrument( level = "debug" , skip_all, ret) ]
@@ -1264,31 +1263,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12641263 }
12651264 }
12661265
1267- match mode {
1268- LowerAssocMode :: Type { .. } => {
1269- // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1270- if let Some ( ( ty, did) ) = self . probe_inherent_assoc_ty (
1271- assoc_segment,
1272- adt_def. did ( ) ,
1273- qself_ty,
1274- hir_ref_id,
1275- span,
1276- ) ? {
1277- return Ok ( LoweredAssoc :: Type ( ty, did) ) ;
1278- }
1279- }
1280- LowerAssocMode :: Const => {
1281- // FIXME(mgca): Support self types other than ADTs.
1282- if let Some ( ( ct, _) ) = self . probe_inherent_assoc_const (
1283- assoc_segment,
1284- adt_def. did ( ) ,
1285- qself_ty,
1286- hir_ref_id,
1287- span,
1288- ) ? {
1289- return Ok ( LoweredAssoc :: Const ( ct) ) ;
1290- }
1291- }
1266+ // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1267+ if let Some ( ( did, args) ) = self . probe_inherent_assoc_shared (
1268+ assoc_segment,
1269+ adt_def. did ( ) ,
1270+ qself_ty,
1271+ hir_ref_id,
1272+ span,
1273+ mode. kind ( ) ,
1274+ ) ? {
1275+ return Ok ( LoweredAssoc :: Term ( did, args) ) ;
12921276 }
12931277 }
12941278
@@ -1452,26 +1436,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14521436 let assoc_item = self
14531437 . probe_assoc_item ( assoc_ident, mode. kind ( ) , hir_ref_id, span, trait_did)
14541438 . expect ( "failed to find associated item" ) ;
1455- let result = match mode {
1456- LowerAssocMode :: Type { .. } => {
1457- let assoc_ty = self . lower_assoc_ty ( span, assoc_item. def_id , assoc_segment, bound) ;
1458- LoweredAssoc :: Type ( assoc_ty, assoc_item. def_id )
1459- }
1460- LowerAssocMode :: Const => {
1461- if assoc_item. has_type_const_attr ( tcx) {
1462- let assoc_ct =
1463- self . lower_assoc_const ( span, assoc_item. def_id , assoc_segment, bound) ;
1464- LoweredAssoc :: Const ( assoc_ct)
1465- } else {
1466- let mut err = tcx. dcx ( ) . struct_span_err (
1467- span,
1468- "use of trait associated const without `#[type_const]`" ,
1469- ) ;
1470- err. note ( "the declaration in the trait must be marked with `#[type_const]`" ) ;
1471- return Err ( err. emit ( ) ) ;
1472- }
1473- }
1474- } ;
1439+ let ( def_id, args) =
1440+ self . lower_assoc_shared ( span, assoc_item. def_id , assoc_segment, bound, mode. kind ( ) ) ?;
1441+ let result = LoweredAssoc :: Term ( def_id, args) ;
14751442
14761443 if let Some ( variant_def_id) = variant_resolution {
14771444 tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , hir_ref_id, span, |lint| {
@@ -1500,14 +1467,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15001467 Ok ( result)
15011468 }
15021469
1503- fn probe_inherent_assoc_ty (
1470+ fn probe_inherent_assoc_shared (
15041471 & self ,
15051472 segment : & hir:: PathSegment < ' tcx > ,
15061473 adt_did : DefId ,
15071474 self_ty : Ty < ' tcx > ,
15081475 block : HirId ,
15091476 span : Span ,
1510- ) -> Result < Option < ( Ty < ' tcx > , DefId ) > , ErrorGuaranteed > {
1477+ kind : ty:: AssocKind ,
1478+ ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
15111479 let tcx = self . tcx ( ) ;
15121480
15131481 // Don't attempt to look up inherent associated types when the feature is not enabled.
@@ -1516,70 +1484,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15161484 // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
15171485 // errors (#108491) which mask the feature-gate error, needlessly confusing users
15181486 // who use IATs by accident (#113265).
1519- if !tcx. features ( ) . inherent_associated_types ( ) {
1487+ if kind == ty :: AssocKind :: Type && !tcx. features ( ) . inherent_associated_types ( ) {
15201488 return Ok ( None ) ;
15211489 }
15221490
1523- let Some ( ( def_id, args) ) = self . probe_inherent_assoc_shared (
1524- segment,
1525- adt_did,
1526- self_ty,
1527- block,
1528- span,
1529- ty:: AssocKind :: Type ,
1530- ) ?
1531- else {
1532- return Ok ( None ) ;
1533- } ;
1534-
1535- let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new_from_args ( tcx, def_id, args) ) ;
1536- Ok ( Some ( ( ty, def_id) ) )
1537- }
1538-
1539- fn probe_inherent_assoc_const (
1540- & self ,
1541- segment : & hir:: PathSegment < ' tcx > ,
1542- adt_did : DefId ,
1543- self_ty : Ty < ' tcx > ,
1544- block : HirId ,
1545- span : Span ,
1546- ) -> Result < Option < ( Const < ' tcx > , DefId ) > , ErrorGuaranteed > {
1547- let tcx = self . tcx ( ) ;
1548-
1549- let Some ( ( def_id, args) ) = self . probe_inherent_assoc_shared (
1550- segment,
1551- adt_did,
1552- self_ty,
1553- block,
1554- span,
1555- ty:: AssocKind :: Const ,
1556- ) ?
1557- else {
1558- return Ok ( None ) ;
1559- } ;
1560-
1561- let ct = Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( def_id, args) ) ;
1562- Ok ( Some ( ( ct, def_id) ) )
1563- }
1564-
1565- fn probe_inherent_assoc_shared (
1566- & self ,
1567- segment : & hir:: PathSegment < ' tcx > ,
1568- adt_did : DefId ,
1569- self_ty : Ty < ' tcx > ,
1570- block : HirId ,
1571- span : Span ,
1572- kind : ty:: AssocKind ,
1573- ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
1574- let tcx = self . tcx ( ) ;
1575-
15761491 let name = segment. ident ;
15771492 let candidates: Vec < _ > = tcx
15781493 . inherent_impls ( adt_did)
15791494 . iter ( )
15801495 . filter_map ( |& impl_| {
1581- let ( item, scope) =
1582- self . probe_assoc_item_unchecked ( name, ty:: AssocKind :: Type , block, impl_) ?;
1496+ let ( item, scope) = self . probe_assoc_item_unchecked ( name, kind, block, impl_) ?;
15831497 Some ( ( impl_, ( item. def_id , scope) ) )
15841498 } )
15851499 . collect ( ) ;
0 commit comments