Skip to content

Commit 3a1bb48

Browse files
committed
[WIP]
1 parent 9d01b49 commit 3a1bb48

6 files changed

Lines changed: 74 additions & 42 deletions

File tree

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
3333
use rustc_middle::hir::nested_filter;
3434
use rustc_middle::query::Providers;
3535
use rustc_middle::ty::typeck_results::{
36-
HasTypeDependentDefs, LocalTableInContext, LocalTableInContextMut, TypeDependentDef,
37-
TypeDependentDefs,
36+
HasTypeDependentDefs, LocalTableInContext, LocalTableInContextMut, TypeDependentDefs,
3837
};
3938
use rustc_middle::ty::util::{Discr, IntTypeExt};
4039
use rustc_middle::ty::{
@@ -547,12 +546,12 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
547546
// There's no place to record types from signatures?
548547
}
549548

550-
fn record_res(&self, hir_id: hir::HirId, result: TypeDependentDef) {
549+
fn record_res(&self, hir_id: hir::HirId, def_id: DefId) {
551550
LocalTableInContextMut::new(
552551
self.hir_id().owner,
553552
&mut self.type_dependent_defs.borrow_mut(),
554553
)
555-
.insert(hir_id, result);
554+
.insert(hir_id, Ok((self.tcx.def_kind(def_id), def_id)));
556555
}
557556

558557
fn infcx(&self) -> Option<&InferCtxt<'tcx>> {

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,6 +2121,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21212121
matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
21222122
}) =>
21232123
{
2124+
// FIXME(fmease): No longer true.
21242125
// First, ignore a qself that isn't a type or `Self` param. Those are the
21252126
// only ones that support `T::Assoc` anyways in HIR lowering.
21262127
let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind else {

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3636
use rustc_infer::traits::DynCompatibilityViolation;
3737
use rustc_macros::{TypeFoldable, TypeVisitable};
3838
use rustc_middle::middle::stability::AllowUnstable;
39-
use rustc_middle::ty::typeck_results::{HasTypeDependentDefs, TypeDependentDef};
39+
use rustc_middle::ty::typeck_results::HasTypeDependentDefs;
4040
use rustc_middle::ty::{
4141
self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput,
4242
Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast,
@@ -220,7 +220,7 @@ pub trait HirTyLowerer<'tcx>: HasTypeDependentDefs {
220220
fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
221221

222222
/// Record the resolution of a HIR node corresponding to a type-dependent definition in this context.
223-
fn record_res(&self, hir_id: hir::HirId, result: TypeDependentDef);
223+
fn record_res(&self, hir_id: hir::HirId, result: DefId);
224224

225225
/// The inference context of the lowering context if applicable.
226226
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
@@ -1320,28 +1320,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13201320
/// Lower a [type-relative](hir::QPath::TypeRelative) path in type position to a type.
13211321
///
13221322
/// If the path refers to an enum variant and `permit_variants` holds,
1323-
/// the returned type is simply the provided self type `qself_ty`.
1323+
/// the returned type is simply the provided self type `self_ty`.
13241324
///
1325-
/// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e.,
1326-
/// `qself_ty` / `qself` is `A::B::C` and `assoc_segment` is `D`.
1327-
/// We return the lowered type and the `DefId` for the whole path.
1328-
///
1329-
/// We only support associated type paths whose self type is a type parameter or a `Self`
1330-
/// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
1331-
/// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
1332-
/// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
1333-
/// For the latter case, we report ambiguity.
1334-
/// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
1335-
///
1336-
/// At the time of writing, *inherent associated types* are also resolved here. This however
1337-
/// is [problematic][iat]. A proper implementation would be as non-trivial as the one
1338-
/// described in the previous paragraph and their modeling of projections would likely be
1339-
/// very similar in nature.
1340-
///
1341-
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
1342-
/// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
1343-
// FIXME(fmease): Update docs
1344-
//
13451325
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
13461326
// it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
13471327
#[instrument(level = "debug", skip_all, ret)]
@@ -1353,7 +1333,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13531333
qpath_hir_id: HirId,
13541334
span: Span,
13551335
permit_variants: PermitVariants,
1356-
) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1336+
) -> Result<(Ty<'tcx>, DefId), ErrorGuaranteed> {
13571337
let tcx = self.tcx();
13581338
match self.lower_type_relative_path(
13591339
self_ty,
@@ -1371,13 +1351,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13711351
);
13721352
let ty = Ty::new_alias(tcx, alias_ty);
13731353
let ty = self.check_param_uses_if_mcg(ty, span, false);
1374-
let kind = tcx.def_kind(def_id);
1375-
self.record_res(qpath_hir_id, Ok((kind, def_id)));
1376-
Ok((ty, kind, def_id))
1354+
Ok((ty, def_id))
13771355
}
13781356
TypeRelativePath::Variant { adt, variant_did } => {
13791357
let adt = self.check_param_uses_if_mcg(adt, span, false);
1380-
Ok((adt, DefKind::Variant, variant_did))
1358+
Ok((adt, variant_did))
13811359
}
13821360
TypeRelativePath::Ctor { .. } => {
13831361
let e = tcx.dcx().span_err(span, "expected type, found tuple constructor");
@@ -1436,6 +1414,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14361414
}
14371415

14381416
/// Lower a [type-relative][hir::QPath::TypeRelative] (and type-level) path.
1417+
///
1418+
/// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e., the self type is `A::B::C`
1419+
/// and the `segment` is `D`.
1420+
///
1421+
/// <!-- FIXME(fmease): No longer accurate -->
1422+
///
1423+
/// We only support associated item paths whose self type is a type parameter or a `Self`
1424+
/// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
1425+
/// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
1426+
/// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
1427+
/// For the latter case, we report ambiguity.
1428+
/// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
1429+
///
1430+
/// <!-- FIXME(fmease): Slightly outdated, too -->
1431+
///
1432+
/// At the time of writing, *inherent associated types* are also resolved here. This however
1433+
/// is problematic. A proper implementation would be as non-trivial as the one
1434+
/// described in the previous paragraph and their modeling of projections would likely be
1435+
/// very similar in nature.
1436+
///
1437+
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
14391438
#[instrument(level = "debug", skip_all, ret)]
14401439
fn lower_type_relative_path(
14411440
&self,
@@ -1485,6 +1484,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14851484
adt_def,
14861485
},
14871486
);
1487+
self.record_res(qpath_hir_id, variant_def.def_id);
14881488
return Ok(TypeRelativePath::Variant {
14891489
adt: self_ty,
14901490
variant_did: variant_def.def_id,
@@ -1496,15 +1496,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14961496
}
14971497

14981498
// FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1499-
if let Some((did, args)) = self.probe_inherent_assoc_item(
1499+
if let Some((def_id, args)) = self.probe_inherent_assoc_item(
15001500
segment,
15011501
adt_def.did(),
15021502
self_ty,
15031503
qpath_hir_id,
15041504
span,
15051505
mode.assoc_tag(),
15061506
)? {
1507-
return Ok(TypeRelativePath::AssocItem(did, args));
1507+
self.record_res(qpath_hir_id, def_id);
1508+
return Ok(TypeRelativePath::AssocItem(def_id, args));
15081509
}
15091510
}
15101511

@@ -1633,6 +1634,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
16331634
.probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
16341635
.expect("failed to find associated item");
16351636

1637+
self.record_res(qpath_hir_id, assoc_item.def_id);
1638+
16361639
Ok((assoc_item.def_id, bound))
16371640
}
16381641

@@ -2700,12 +2703,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
27002703
path_span,
27012704
PermitVariants::Yes,
27022705
);
2703-
let ty = result
2704-
.map(|(ty, _, _)| ty)
2705-
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
2706+
let ty =
2707+
result.map(|(ty, _)| ty).unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
27062708

27072709
ResolvedStructPath {
2708-
res: result.map(|(_, kind, def_id)| Res::Def(kind, def_id)),
2710+
res: result.map(|(_, def_id)| Res::Def(self.tcx().def_kind(def_id), def_id)),
27092711
ty,
27102712
}
27112713
}
@@ -3210,7 +3212,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
32103212
hir_ty.span,
32113213
PermitVariants::No,
32123214
)
3213-
.map(|(ty, _, _)| ty)
3215+
.map(|(ty, _)| ty)
32143216
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
32153217
}
32163218
hir::TyKind::Array(ty, length) => {

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
1818
};
1919
use rustc_infer::infer::{self, RegionVariableOrigin};
2020
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
21-
use rustc_middle::ty::typeck_results::{HasTypeDependentDefs, TypeDependentDef};
21+
use rustc_middle::ty::typeck_results::HasTypeDependentDefs;
2222
use rustc_middle::ty::{
2323
self, CantBeErased, Const, Flags, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized,
2424
};
@@ -450,8 +450,8 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
450450
self.write_ty(hir_id, ty)
451451
}
452452

453-
fn record_res(&self, hir_id: HirId, result: TypeDependentDef) {
454-
self.write_resolution(hir_id, result);
453+
fn record_res(&self, hir_id: HirId, def_id: DefId) {
454+
self.write_resolution(hir_id, Ok((self.tcx.def_kind(def_id), def_id)));
455455
}
456456

457457
fn infcx(&self) -> Option<&infer::InferCtxt<'tcx>> {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// FIXME(fmease): Description.
2+
//@ check-pass
3+
4+
#![feature(return_type_notation)]
5+
6+
trait TraitA { type Assoc: TraitB; }
7+
trait TraitB { fn assoc() -> impl Sized; }
8+
9+
fn scope<T: TraitA>()
10+
where
11+
T::Assoc::assoc(..): Iterator<Item = u8>,
12+
{
13+
let _: Vec<u8> = T::Assoc::assoc().collect();
14+
}
15+
16+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// FIXME(fmease): Description.
2+
//@ check-pass
3+
4+
#![feature(min_generic_const_args)]
5+
#![expect(incomplete_features)]
6+
7+
trait TraitA { type Assoc: TraitB; }
8+
trait TraitB { #[type_const] const ASSOC: usize; }
9+
10+
fn scope<T: TraitA>() -> [u8; T::Assoc::ASSOC] {
11+
[0; T::Assoc::ASSOC]
12+
}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)