@@ -153,7 +153,7 @@ pub trait HirTyLowerer<'tcx> {
153
153
assoc_name : Ident ,
154
154
) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
155
155
156
- /// Lower an associated type (from a trait) to a projection.
156
+ /// Lower an associated type/const (from a trait) to a projection.
157
157
///
158
158
/// This method has to be defined by the concrete lowering context because
159
159
/// dealing with higher-ranked trait references depends on its capabilities:
@@ -165,26 +165,6 @@ pub trait HirTyLowerer<'tcx> {
165
165
///
166
166
/// The canonical example of this is associated type `T::P` where `T` is a type
167
167
/// 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.
188
168
fn lower_assoc_shared (
189
169
& self ,
190
170
span : Span ,
@@ -295,9 +275,8 @@ impl LowerAssocMode {
295
275
296
276
#[ derive( Debug , Clone , Copy ) ]
297
277
enum LoweredAssoc < ' tcx > {
298
- Type ( Ty < ' tcx > , DefId ) ,
278
+ Term ( DefId , GenericArgsRef < ' tcx > ) ,
299
279
Variant { adt : Ty < ' tcx > , variant_did : DefId } ,
300
- Const ( Const < ' tcx > ) ,
301
280
}
302
281
303
282
/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -1177,6 +1156,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1177
1156
assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1178
1157
permit_variants : bool ,
1179
1158
) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1159
+ let tcx = self . tcx ( ) ;
1180
1160
match self . lower_assoc_path_shared (
1181
1161
hir_ref_id,
1182
1162
span,
@@ -1185,9 +1165,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1185
1165
assoc_segment,
1186
1166
LowerAssocMode :: Type { permit_variants } ,
1187
1167
) ? {
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
+ }
1189
1181
LoweredAssoc :: Variant { adt, variant_did } => Ok ( ( adt, DefKind :: Variant , variant_did) ) ,
1190
- LoweredAssoc :: Const ( _) => unreachable ! ( "lowered assoc type to const somehow" ) ,
1191
1182
}
1192
1183
}
1193
1184
@@ -1200,21 +1191,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1200
1191
qself : & ' tcx hir:: Ty < ' tcx > ,
1201
1192
assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1202
1193
) -> 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 (
1204
1196
hir_ref_id,
1205
1197
span,
1206
1198
qself_ty,
1207
1199
qself,
1208
1200
assoc_segment,
1209
1201
LowerAssocMode :: Const ,
1210
1202
) ? {
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)
1215
1213
}
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) ) )
1218
1217
}
1219
1218
1220
1219
#[ instrument( level = "debug" , skip_all, ret) ]
@@ -1257,31 +1256,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1257
1256
}
1258
1257
}
1259
1258
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) ) ;
1285
1269
}
1286
1270
}
1287
1271
@@ -1446,26 +1430,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1446
1430
let assoc_item = self
1447
1431
. probe_assoc_item ( assoc_ident, mode. kind ( ) , hir_ref_id, span, trait_did)
1448
1432
. 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) ;
1469
1436
1470
1437
if let Some ( variant_def_id) = variant_resolution {
1471
1438
tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , hir_ref_id, span, |lint| {
@@ -1494,14 +1461,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1494
1461
Ok ( result)
1495
1462
}
1496
1463
1497
- fn probe_inherent_assoc_ty (
1464
+ fn probe_inherent_assoc_shared (
1498
1465
& self ,
1499
1466
segment : & hir:: PathSegment < ' tcx > ,
1500
1467
adt_did : DefId ,
1501
1468
self_ty : Ty < ' tcx > ,
1502
1469
block : HirId ,
1503
1470
span : Span ,
1504
- ) -> Result < Option < ( Ty < ' tcx > , DefId ) > , ErrorGuaranteed > {
1471
+ kind : ty:: AssocKind ,
1472
+ ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
1505
1473
let tcx = self . tcx ( ) ;
1506
1474
1507
1475
// Don't attempt to look up inherent associated types when the feature is not enabled.
@@ -1510,70 +1478,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1510
1478
// selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
1511
1479
// errors (#108491) which mask the feature-gate error, needlessly confusing users
1512
1480
// who use IATs by accident (#113265).
1513
- if !tcx. features ( ) . inherent_associated_types ( ) {
1481
+ if kind == ty :: AssocKind :: Type && !tcx. features ( ) . inherent_associated_types ( ) {
1514
1482
return Ok ( None ) ;
1515
1483
}
1516
1484
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
-
1570
1485
let name = segment. ident ;
1571
1486
let candidates: Vec < _ > = tcx
1572
1487
. inherent_impls ( adt_did)
1573
1488
. iter ( )
1574
1489
. 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_) ?;
1577
1491
Some ( ( impl_, ( item. def_id , scope) ) )
1578
1492
} )
1579
1493
. collect ( ) ;
0 commit comments