Skip to content

Commit e053fcb

Browse files
committed
Clean up (most of) the refactoring
1 parent ee29d12 commit e053fcb

File tree

4 files changed

+55
-222
lines changed

4 files changed

+55
-222
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -444,47 +444,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
444444
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
445445
}
446446

447-
fn lower_assoc_ty(
448-
&self,
449-
span: Span,
450-
item_def_id: DefId,
451-
item_segment: &hir::PathSegment<'tcx>,
452-
poly_trait_ref: ty::PolyTraitRef<'tcx>,
453-
) -> Ty<'tcx> {
454-
match self.lower_assoc_shared(
455-
span,
456-
item_def_id,
457-
item_segment,
458-
poly_trait_ref,
459-
ty::AssocKind::Type,
460-
) {
461-
Ok((def_id, args)) => Ty::new_projection_from_args(self.tcx(), def_id, args),
462-
Err(witness) => Ty::new_error(self.tcx(), witness),
463-
}
464-
}
465-
466-
fn lower_assoc_const(
467-
&self,
468-
span: Span,
469-
item_def_id: DefId,
470-
item_segment: &hir::PathSegment<'tcx>,
471-
poly_trait_ref: ty::PolyTraitRef<'tcx>,
472-
) -> Const<'tcx> {
473-
match self.lower_assoc_shared(
474-
span,
475-
item_def_id,
476-
item_segment,
477-
poly_trait_ref,
478-
ty::AssocKind::Const,
479-
) {
480-
Ok((def_id, args)) => {
481-
let uv = ty::UnevaluatedConst::new(def_id, args);
482-
Const::new_unevaluated(self.tcx(), uv)
483-
}
484-
Err(witness) => Const::new_error(self.tcx(), witness),
485-
}
486-
}
487-
488447
fn lower_assoc_shared(
489448
&self,
490449
span: Span,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 49 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
300280
enum 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();

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -308,47 +308,6 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
308308
))
309309
}
310310

311-
fn lower_assoc_ty(
312-
&self,
313-
span: Span,
314-
item_def_id: DefId,
315-
item_segment: &hir::PathSegment<'tcx>,
316-
poly_trait_ref: ty::PolyTraitRef<'tcx>,
317-
) -> Ty<'tcx> {
318-
match self.lower_assoc_shared(
319-
span,
320-
item_def_id,
321-
item_segment,
322-
poly_trait_ref,
323-
ty::AssocKind::Type,
324-
) {
325-
Ok((def_id, args)) => Ty::new_projection_from_args(self.tcx(), def_id, args),
326-
Err(witness) => Ty::new_error(self.tcx(), witness),
327-
}
328-
}
329-
330-
fn lower_assoc_const(
331-
&self,
332-
span: Span,
333-
item_def_id: DefId,
334-
item_segment: &hir::PathSegment<'tcx>,
335-
poly_trait_ref: ty::PolyTraitRef<'tcx>,
336-
) -> Const<'tcx> {
337-
match self.lower_assoc_shared(
338-
span,
339-
item_def_id,
340-
item_segment,
341-
poly_trait_ref,
342-
ty::AssocKind::Const,
343-
) {
344-
Ok((def_id, args)) => {
345-
let uv = ty::UnevaluatedConst::new(def_id, args);
346-
Const::new_unevaluated(self.tcx(), uv)
347-
}
348-
Err(witness) => Const::new_error(self.tcx(), witness),
349-
}
350-
}
351-
352311
fn lower_assoc_shared(
353312
&self,
354313
span: Span,

compiler/rustc_middle/src/ty/assoc.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ impl AssocItem {
109109
self.opt_rpitit_info.is_some()
110110
}
111111

112-
/// Does this associated item have the `#[type_const]` attribute,
113-
/// or (if it is in a trait impl), does the item from the original
114-
/// trait have this attribute?
115-
pub fn has_type_const_attr(&self, tcx: TyCtxt<'_>) -> bool {
112+
/// Returns true if:
113+
/// - This trait associated item has the `#[type_const]` attribute,
114+
/// - If it is in a trait impl, the item from the original trait has this attribute, or
115+
/// - It is an inherent assoc const.
116+
pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool {
116117
if self.kind != ty::AssocKind::Const {
117118
return false;
118119
}
@@ -121,7 +122,7 @@ impl AssocItem {
121122
(AssocItemContainer::Trait, _) => self.def_id,
122123
(AssocItemContainer::Impl, Some(trait_item_did)) => trait_item_did,
123124
// Inherent impl but this attr is only applied to trait assoc items.
124-
(AssocItemContainer::Impl, None) => return false,
125+
(AssocItemContainer::Impl, None) => return true,
125126
};
126127
tcx.has_attr(def_id, sym::type_const)
127128
}

0 commit comments

Comments
 (0)