Skip to content

Commit 709784a

Browse files
committed
[WIP]
1 parent 616fff2 commit 709784a

7 files changed

Lines changed: 79 additions & 44 deletions

File tree

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3434
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
3535
use rustc_middle::query::Providers;
3636
use rustc_middle::ty::typeck_results::{
37-
HasTypeDependentDefs, LocalTableInContext, LocalTableInContextMut, TypeDependentDef,
38-
TypeDependentDefs,
37+
HasTypeDependentDefs, LocalTableInContext, LocalTableInContextMut, TypeDependentDefs,
3938
};
4039
use rustc_middle::ty::util::{Discr, IntTypeExt};
4140
use rustc_middle::ty::{
@@ -520,12 +519,12 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
520519
// There's no place to record types from signatures?
521520
}
522521

523-
fn record_res(&self, hir_id: hir::HirId, result: TypeDependentDef) {
522+
fn record_res(&self, hir_id: hir::HirId, def_id: DefId) {
524523
LocalTableInContextMut::new(
525524
self.hir_id().owner,
526525
&mut self.type_dependent_defs.borrow_mut(),
527526
)
528-
.insert(hir_id, result);
527+
.insert(hir_id, Ok((self.tcx.def_kind(def_id), def_id)));
529528
}
530529

531530
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
@@ -2109,6 +2109,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
21092109
matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
21102110
}) =>
21112111
{
2112+
// FIXME(fmease): No longer true.
21122113
// First, ignore a qself that isn't a type or `Self` param. Those are the
21132114
// only ones that support `T::Assoc` anyways in HIR lowering.
21142115
let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind else {

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_macros::{TypeFoldable, TypeVisitable};
3737
use rustc_middle::middle::stability::AllowUnstable;
3838
use rustc_middle::mir::interpret::LitToConstInput;
3939
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
40-
use rustc_middle::ty::typeck_results::{HasTypeDependentDefs, TypeDependentDef};
40+
use rustc_middle::ty::typeck_results::HasTypeDependentDefs;
4141
use rustc_middle::ty::{
4242
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
4343
TypingMode, Upcast, fold_regions,
@@ -216,7 +216,7 @@ pub trait HirTyLowerer<'tcx>: HasTypeDependentDefs {
216216
fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
217217

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

221221
/// The inference context of the lowering context if applicable.
222222
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
@@ -1217,28 +1217,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12171217
/// Lower a [type-relative](hir::QPath::TypeRelative) path in type position to a type.
12181218
///
12191219
/// If the path refers to an enum variant and `permit_variants` holds,
1220-
/// the returned type is simply the provided self type `qself_ty`.
1220+
/// the returned type is simply the provided self type `self_ty`.
12211221
///
1222-
/// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e.,
1223-
/// `qself_ty` / `qself` is `A::B::C` and `assoc_segment` is `D`.
1224-
/// We return the lowered type and the `DefId` for the whole path.
1225-
///
1226-
/// We only support associated type paths whose self type is a type parameter or a `Self`
1227-
/// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
1228-
/// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
1229-
/// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
1230-
/// For the latter case, we report ambiguity.
1231-
/// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
1232-
///
1233-
/// At the time of writing, *inherent associated types* are also resolved here. This however
1234-
/// is [problematic][iat]. A proper implementation would be as non-trivial as the one
1235-
/// described in the previous paragraph and their modeling of projections would likely be
1236-
/// very similar in nature.
1237-
///
1238-
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
1239-
/// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
1240-
// FIXME(fmease): Update docs
1241-
//
12421222
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
12431223
// it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
12441224
#[instrument(level = "debug", skip_all, ret)]
@@ -1250,7 +1230,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12501230
qpath_hir_id: HirId,
12511231
span: Span,
12521232
permit_variants: PermitVariants,
1253-
) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1233+
) -> Result<(Ty<'tcx>, DefId), ErrorGuaranteed> {
12541234
let tcx = self.tcx();
12551235
match self.lower_type_relative_path(
12561236
self_ty,
@@ -1261,15 +1241,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12611241
LowerTypeRelativePathMode::Type(permit_variants),
12621242
)? {
12631243
TypeRelativePath::AssocItem(def_id, args) => {
1264-
let kind = tcx.def_kind(def_id);
1265-
self.record_res(qpath_hir_id, Ok((kind, def_id)));
12661244
let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
12671245
let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1268-
Ok((ty, kind, def_id))
1269-
}
1270-
TypeRelativePath::Variant { adt, variant_did } => {
1271-
Ok((adt, DefKind::Variant, variant_did))
1246+
Ok((ty, def_id))
12721247
}
1248+
TypeRelativePath::Variant { adt, variant_did } => Ok((adt, variant_did)),
12731249
}
12741250
}
12751251

@@ -1313,6 +1289,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13131289
}
13141290

13151291
/// Lower a [type-relative][hir::QPath::TypeRelative] (and type-level) path.
1292+
///
1293+
/// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e., the self type is `A::B::C`
1294+
/// and the `segment` is `D`.
1295+
///
1296+
/// <!-- FIXME(fmease): No longer accurate -->
1297+
///
1298+
/// We only support associated item paths whose self type is a type parameter or a `Self`
1299+
/// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
1300+
/// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
1301+
/// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
1302+
/// For the latter case, we report ambiguity.
1303+
/// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
1304+
///
1305+
/// <!-- FIXME(fmease): Slightly outdated, too -->
1306+
///
1307+
/// At the time of writing, *inherent associated types* are also resolved here. This however
1308+
/// is problematic. A proper implementation would be as non-trivial as the one
1309+
/// described in the previous paragraph and their modeling of projections would likely be
1310+
/// very similar in nature.
1311+
///
1312+
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
13161313
#[instrument(level = "debug", skip_all, ret)]
13171314
fn lower_type_relative_path(
13181315
&self,
@@ -1345,6 +1342,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13451342
adt_def,
13461343
},
13471344
);
1345+
self.record_res(qpath_hir_id, variant_def.def_id);
13481346
return Ok(TypeRelativePath::Variant {
13491347
adt: self_ty,
13501348
variant_did: variant_def.def_id,
@@ -1356,15 +1354,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13561354
}
13571355

13581356
// FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1359-
if let Some((did, args)) = self.probe_inherent_assoc_item(
1357+
if let Some((def_id, args)) = self.probe_inherent_assoc_item(
13601358
segment,
13611359
adt_def.did(),
13621360
self_ty,
13631361
qpath_hir_id,
13641362
span,
13651363
mode.assoc_tag(),
13661364
)? {
1367-
return Ok(TypeRelativePath::AssocItem(did, args));
1365+
self.record_res(qpath_hir_id, def_id);
1366+
return Ok(TypeRelativePath::AssocItem(def_id, args));
13681367
}
13691368
}
13701369

@@ -1500,6 +1499,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15001499
.probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
15011500
.expect("failed to find associated item");
15021501

1502+
self.record_res(qpath_hir_id, assoc_item.def_id);
1503+
15031504
Ok((assoc_item.def_id, bound))
15041505
}
15051506

@@ -2718,7 +2719,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
27182719
hir_ty.span,
27192720
PermitVariants::No,
27202721
)
2721-
.map(|(ty, _, _)| ty)
2722+
.map(|(ty, _)| ty)
27222723
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
27232724
}
27242725
hir::TyKind::Array(ty, length) => {

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,12 +1307,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13071307
path_span,
13081308
PermitVariants::Yes,
13091309
);
1310-
let ty = result
1311-
.map(|(ty, _, _)| ty)
1312-
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
1310+
let ty =
1311+
result.map(|(ty, _)| ty).unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
13131312
let ty = LoweredTy::from_raw(self, path_span, ty);
13141313

1315-
(result.map_or(Res::Err, |(_, kind, def_id)| Res::Def(kind, def_id)), ty)
1314+
(
1315+
result.map_or(Res::Err, |(_, def_id)| {
1316+
Res::Def(self.tcx().def_kind(def_id), def_id)
1317+
}),
1318+
ty,
1319+
)
13161320
}
13171321
}
13181322
}

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
1717
};
1818
use rustc_infer::infer::{self, RegionVariableOrigin};
1919
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
20-
use rustc_middle::ty::typeck_results::{HasTypeDependentDefs, TypeDependentDef};
20+
use rustc_middle::ty::typeck_results::HasTypeDependentDefs;
2121
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
2222
use rustc_session::Session;
2323
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
@@ -439,8 +439,8 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
439439
self.write_ty(hir_id, ty)
440440
}
441441

442-
fn record_res(&self, hir_id: HirId, result: TypeDependentDef) {
443-
self.write_resolution(hir_id, result);
442+
fn record_res(&self, hir_id: HirId, def_id: DefId) {
443+
self.write_resolution(hir_id, Ok((self.tcx.def_kind(def_id), def_id)));
444444
}
445445

446446
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)