@@ -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 ,
@@ -298,9 +278,8 @@ impl LowerAssocMode {
298
278
299
279
#[ derive( Debug , Clone , Copy ) ]
300
280
enum LoweredAssoc < ' tcx > {
301
- Type ( Ty < ' tcx > , DefId ) ,
281
+ Term ( DefId , GenericArgsRef < ' tcx > ) ,
302
282
Variant { adt : Ty < ' tcx > , variant_did : DefId } ,
303
- Const ( Const < ' tcx > ) ,
304
283
}
305
284
306
285
/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -1184,6 +1163,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1184
1163
assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1185
1164
permit_variants : bool ,
1186
1165
) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1166
+ let tcx = self . tcx ( ) ;
1187
1167
match self . lower_assoc_path_shared (
1188
1168
hir_ref_id,
1189
1169
span,
@@ -1192,9 +1172,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1192
1172
assoc_segment,
1193
1173
LowerAssocMode :: Type { permit_variants } ,
1194
1174
) ? {
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
+ }
1196
1188
LoweredAssoc :: Variant { adt, variant_did } => Ok ( ( adt, DefKind :: Variant , variant_did) ) ,
1197
- LoweredAssoc :: Const ( _) => unreachable ! ( "lowered assoc type to const somehow" ) ,
1198
1189
}
1199
1190
}
1200
1191
@@ -1207,21 +1198,29 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1207
1198
qself : & ' tcx hir:: Ty < ' tcx > ,
1208
1199
assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1209
1200
) -> 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 (
1211
1203
hir_ref_id,
1212
1204
span,
1213
1205
qself_ty,
1214
1206
qself,
1215
1207
assoc_segment,
1216
1208
LowerAssocMode :: Const ,
1217
1209
) ? {
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)
1222
1220
}
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) ) )
1225
1224
}
1226
1225
1227
1226
#[ instrument( level = "debug" , skip_all, ret) ]
@@ -1264,31 +1263,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1264
1263
}
1265
1264
}
1266
1265
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) ) ;
1292
1276
}
1293
1277
}
1294
1278
@@ -1452,26 +1436,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1452
1436
let assoc_item = self
1453
1437
. probe_assoc_item ( assoc_ident, mode. kind ( ) , hir_ref_id, span, trait_did)
1454
1438
. 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) ;
1475
1442
1476
1443
if let Some ( variant_def_id) = variant_resolution {
1477
1444
tcx. node_span_lint ( AMBIGUOUS_ASSOCIATED_ITEMS , hir_ref_id, span, |lint| {
@@ -1500,14 +1467,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1500
1467
Ok ( result)
1501
1468
}
1502
1469
1503
- fn probe_inherent_assoc_ty (
1470
+ fn probe_inherent_assoc_shared (
1504
1471
& self ,
1505
1472
segment : & hir:: PathSegment < ' tcx > ,
1506
1473
adt_did : DefId ,
1507
1474
self_ty : Ty < ' tcx > ,
1508
1475
block : HirId ,
1509
1476
span : Span ,
1510
- ) -> Result < Option < ( Ty < ' tcx > , DefId ) > , ErrorGuaranteed > {
1477
+ kind : ty:: AssocKind ,
1478
+ ) -> Result < Option < ( DefId , GenericArgsRef < ' tcx > ) > , ErrorGuaranteed > {
1511
1479
let tcx = self . tcx ( ) ;
1512
1480
1513
1481
// Don't attempt to look up inherent associated types when the feature is not enabled.
@@ -1516,70 +1484,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1516
1484
// selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
1517
1485
// errors (#108491) which mask the feature-gate error, needlessly confusing users
1518
1486
// who use IATs by accident (#113265).
1519
- if !tcx. features ( ) . inherent_associated_types ( ) {
1487
+ if kind == ty :: AssocKind :: Type && !tcx. features ( ) . inherent_associated_types ( ) {
1520
1488
return Ok ( None ) ;
1521
1489
}
1522
1490
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
-
1576
1491
let name = segment. ident ;
1577
1492
let candidates: Vec < _ > = tcx
1578
1493
. inherent_impls ( adt_did)
1579
1494
. iter ( )
1580
1495
. 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_) ?;
1583
1497
Some ( ( impl_, ( item. def_id , scope) ) )
1584
1498
} )
1585
1499
. collect ( ) ;
0 commit comments