@@ -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 ,
@@ -295,9 +275,8 @@ impl LowerAssocMode {
295275
296276#[ derive( Debug , Clone , Copy ) ]
297277enum LoweredAssoc < ' tcx > {
298- Type ( Ty < ' tcx > , DefId ) ,
278+ Term ( DefId , GenericArgsRef < ' tcx > ) ,
299279 Variant { adt : Ty < ' tcx > , variant_did : DefId } ,
300- Const ( Const < ' tcx > ) ,
301280}
302281
303282/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -1177,6 +1156,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11771156 assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
11781157 permit_variants : bool ,
11791158 ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1159+ let tcx = self . tcx ( ) ;
11801160 match self . lower_assoc_path_shared (
11811161 hir_ref_id,
11821162 span,
@@ -1185,9 +1165,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11851165 assoc_segment,
11861166 LowerAssocMode :: Type { permit_variants } ,
11871167 ) ? {
1188- LoweredAssoc :: Type ( ty, def_id) => Ok ( ( ty, DefKind :: AssocTy , def_id) ) ,
1168+ LoweredAssoc :: Term ( def_id, args) => {
1169+ let assoc = tcx. associated_item ( def_id) ;
1170+ let ty = if matches ! ( assoc, ty:: AssocItem {
1171+ container: ty:: AssocItemContainer :: Impl ,
1172+ trait_item_def_id: None ,
1173+ ..
1174+ } ) {
1175+ Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new_from_args ( tcx, def_id, args) )
1176+ } else {
1177+ Ty :: new_projection_from_args ( tcx, def_id, args)
1178+ } ;
1179+ Ok ( ( ty, DefKind :: AssocTy , def_id) )
1180+ }
11891181 LoweredAssoc :: Variant { adt, variant_did } => Ok ( ( adt, DefKind :: Variant , variant_did) ) ,
1190- LoweredAssoc :: Const ( _) => unreachable ! ( "lowered assoc type to const somehow" ) ,
11911182 }
11921183 }
11931184
@@ -1200,21 +1191,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12001191 qself : & ' tcx hir:: Ty < ' tcx > ,
12011192 assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
12021193 ) -> Result < Const < ' tcx > , ErrorGuaranteed > {
1203- match self . lower_assoc_path_shared (
1194+ let tcx = self . tcx ( ) ;
1195+ let ( def_id, args) = match self . lower_assoc_path_shared (
12041196 hir_ref_id,
12051197 span,
12061198 qself_ty,
12071199 qself,
12081200 assoc_segment,
12091201 LowerAssocMode :: Const ,
12101202 ) ? {
1211- LoweredAssoc :: Type ( ..) => unreachable ! ( "lowered assoc const to type somehow" ) ,
1212- LoweredAssoc :: Variant { adt : _, variant_did } => {
1213- let uv = ty:: UnevaluatedConst :: new ( variant_did, ty:: List :: empty ( ) ) ;
1214- Ok ( Const :: new_unevaluated ( self . tcx ( ) , uv) )
1203+ LoweredAssoc :: Term ( def_id, args) => {
1204+ if !tcx. associated_item ( def_id) . is_type_const_capable ( tcx) {
1205+ let mut err = tcx. dcx ( ) . struct_span_err (
1206+ span,
1207+ "use of trait associated const without `#[type_const]`" ,
1208+ ) ;
1209+ err. note ( "the declaration in the trait must be marked with `#[type_const]`" ) ;
1210+ return Err ( err. emit ( ) ) ;
1211+ }
1212+ ( def_id, args)
12151213 }
1216- LoweredAssoc :: Const ( ct) => Ok ( ct) ,
1217- }
1214+ LoweredAssoc :: Variant { adt : _, variant_did } => ( variant_did, ty:: List :: empty ( ) ) ,
1215+ } ;
1216+ Ok ( Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( def_id, args) ) )
12181217 }
12191218
12201219 #[ instrument( level = "debug" , skip_all, ret) ]
@@ -1257,31 +1256,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12571256 }
12581257 }
12591258
1260- match mode {
1261- LowerAssocMode :: Type { .. } => {
1262- // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1263- if let Some ( ( ty, did) ) = self . probe_inherent_assoc_ty (
1264- assoc_segment,
1265- adt_def. did ( ) ,
1266- qself_ty,
1267- hir_ref_id,
1268- span,
1269- ) ? {
1270- return Ok ( LoweredAssoc :: Type ( ty, did) ) ;
1271- }
1272- }
1273- LowerAssocMode :: Const => {
1274- // FIXME(mgca): Support self types other than ADTs.
1275- if let Some ( ( ct, _) ) = self . probe_inherent_assoc_const (
1276- assoc_segment,
1277- adt_def. did ( ) ,
1278- qself_ty,
1279- hir_ref_id,
1280- span,
1281- ) ? {
1282- return Ok ( LoweredAssoc :: Const ( ct) ) ;
1283- }
1284- }
1259+ // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1260+ if let Some ( ( did, args) ) = self . probe_inherent_assoc_shared (
1261+ assoc_segment,
1262+ adt_def. did ( ) ,
1263+ qself_ty,
1264+ hir_ref_id,
1265+ span,
1266+ mode. kind ( ) ,
1267+ ) ? {
1268+ return Ok ( LoweredAssoc :: Term ( did, args) ) ;
12851269 }
12861270 }
12871271
@@ -1446,26 +1430,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14461430 let assoc_item = self
14471431 . probe_assoc_item ( assoc_ident, mode. kind ( ) , hir_ref_id, span, trait_did)
14481432 . expect ( "failed to find associated item" ) ;
1449- let result = match mode {
1450- LowerAssocMode :: Type { .. } => {
1451- let assoc_ty = self . lower_assoc_ty ( span, assoc_item. def_id , assoc_segment, bound) ;
1452- LoweredAssoc :: Type ( assoc_ty, assoc_item. def_id )
1453- }
1454- LowerAssocMode :: Const => {
1455- if assoc_item. has_type_const_attr ( tcx) {
1456- let assoc_ct =
1457- self . lower_assoc_const ( span, assoc_item. def_id , assoc_segment, bound) ;
1458- LoweredAssoc :: Const ( assoc_ct)
1459- } else {
1460- let mut err = tcx. dcx ( ) . struct_span_err (
1461- span,
1462- "use of trait associated const without `#[type_const]`" ,
1463- ) ;
1464- err. note ( "the declaration in the trait must be marked with `#[type_const]`" ) ;
1465- return Err ( err. emit ( ) ) ;
1466- }
1467- }
1468- } ;
1433+ let ( def_id, args) =
1434+ self . lower_assoc_shared ( span, assoc_item. def_id , assoc_segment, bound, mode. kind ( ) ) ?;
1435+ let result = LoweredAssoc :: Term ( def_id, args) ;
14691436
14701437 if let Some ( variant_def_id) = variant_resolution {
14711438 tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , hir_ref_id, span, |lint| {
@@ -1494,14 +1461,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14941461 Ok ( result)
14951462 }
14961463
1497- fn probe_inherent_assoc_ty (
1464+ fn probe_inherent_assoc_shared (
14981465 & self ,
14991466 segment : & hir:: PathSegment < ' tcx > ,
15001467 adt_did : DefId ,
15011468 self_ty : Ty < ' tcx > ,
15021469 block : HirId ,
15031470 span : Span ,
1504- ) -> Result < Option < ( Ty < ' tcx > , DefId ) > , ErrorGuaranteed > {
1471+ kind : ty:: AssocKind ,
1472+ ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
15051473 let tcx = self . tcx ( ) ;
15061474
15071475 // Don't attempt to look up inherent associated types when the feature is not enabled.
@@ -1510,70 +1478,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15101478 // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
15111479 // errors (#108491) which mask the feature-gate error, needlessly confusing users
15121480 // who use IATs by accident (#113265).
1513- if !tcx. features ( ) . inherent_associated_types ( ) {
1481+ if kind == ty :: AssocKind :: Type && !tcx. features ( ) . inherent_associated_types ( ) {
15141482 return Ok ( None ) ;
15151483 }
15161484
1517- let Some ( ( def_id, args) ) = self . probe_inherent_assoc_shared (
1518- segment,
1519- adt_did,
1520- self_ty,
1521- block,
1522- span,
1523- ty:: AssocKind :: Type ,
1524- ) ?
1525- else {
1526- return Ok ( None ) ;
1527- } ;
1528-
1529- let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new_from_args ( tcx, def_id, args) ) ;
1530- Ok ( Some ( ( ty, def_id) ) )
1531- }
1532-
1533- fn probe_inherent_assoc_const (
1534- & self ,
1535- segment : & hir:: PathSegment < ' tcx > ,
1536- adt_did : DefId ,
1537- self_ty : Ty < ' tcx > ,
1538- block : HirId ,
1539- span : Span ,
1540- ) -> Result < Option < ( Const < ' tcx > , DefId ) > , ErrorGuaranteed > {
1541- let tcx = self . tcx ( ) ;
1542-
1543- let Some ( ( def_id, args) ) = self . probe_inherent_assoc_shared (
1544- segment,
1545- adt_did,
1546- self_ty,
1547- block,
1548- span,
1549- ty:: AssocKind :: Const ,
1550- ) ?
1551- else {
1552- return Ok ( None ) ;
1553- } ;
1554-
1555- let ct = Const :: new_unevaluated ( tcx, ty:: UnevaluatedConst :: new ( def_id, args) ) ;
1556- Ok ( Some ( ( ct, def_id) ) )
1557- }
1558-
1559- fn probe_inherent_assoc_shared (
1560- & self ,
1561- segment : & hir:: PathSegment < ' tcx > ,
1562- adt_did : DefId ,
1563- self_ty : Ty < ' tcx > ,
1564- block : HirId ,
1565- span : Span ,
1566- kind : ty:: AssocKind ,
1567- ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
1568- let tcx = self . tcx ( ) ;
1569-
15701485 let name = segment. ident ;
15711486 let candidates: Vec < _ > = tcx
15721487 . inherent_impls ( adt_did)
15731488 . iter ( )
15741489 . filter_map ( |& impl_| {
1575- let ( item, scope) =
1576- self . probe_assoc_item_unchecked ( name, ty:: AssocKind :: Type , block, impl_) ?;
1490+ let ( item, scope) = self . probe_assoc_item_unchecked ( name, kind, block, impl_) ?;
15771491 Some ( ( impl_, ( item. def_id , scope) ) )
15781492 } )
15791493 . collect ( ) ;
0 commit comments