Skip to content

Commit 25a92ee

Browse files
committed
Clean up (most of) the refactoring
1 parent c0ed1dd commit 25a92ee

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
@@ -445,47 +445,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
445445
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
446446
}
447447

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

296276
#[derive(Debug, Clone, Copy)]
297277
enum 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();

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)