@@ -39,6 +39,7 @@ use rustc_infer::traits::ObligationCause;
39
39
use rustc_middle:: middle:: stability:: AllowUnstable ;
40
40
use rustc_middle:: mir:: interpret:: { LitToConstError , LitToConstInput } ;
41
41
use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
42
+ use rustc_middle:: ty:: typeck_results:: { HasTypeDependentDefs , TypeDependentDef } ;
42
43
use rustc_middle:: ty:: {
43
44
self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty , TyCtxt ,
44
45
TypeVisitableExt ,
@@ -98,7 +99,7 @@ pub enum RegionInferReason<'a> {
98
99
/// the [`rustc_middle::ty`] representation.
99
100
///
100
101
/// This trait used to be called `AstConv`.
101
- pub trait HirTyLowerer < ' tcx > {
102
+ pub trait HirTyLowerer < ' tcx > : HasTypeDependentDefs {
102
103
fn tcx ( & self ) -> TyCtxt < ' tcx > ;
103
104
104
105
/// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
@@ -173,6 +174,8 @@ pub trait HirTyLowerer<'tcx> {
173
174
/// Record the lowered type of a HIR node in this context.
174
175
fn record_ty ( & self , hir_id : HirId , ty : Ty < ' tcx > , span : Span ) ;
175
176
177
+ fn record_res ( & self , hir_id : hir:: HirId , result : TypeDependentDef ) ;
178
+
176
179
/// The inference context of the lowering context if applicable.
177
180
fn infcx ( & self ) -> Option < & InferCtxt < ' tcx > > ;
178
181
@@ -192,6 +195,8 @@ pub trait HirTyLowerer<'tcx> {
192
195
{
193
196
self
194
197
}
198
+
199
+ fn upcast ( & self ) -> & dyn HasTypeDependentDefs ;
195
200
}
196
201
197
202
/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -992,6 +997,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
992
997
/// [type-relative]: hir::QPath::TypeRelative
993
998
/// [#22519]: https://github.com/rust-lang/rust/issues/22519
994
999
/// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
1000
+ // FIXME(fmease): Update docs
995
1001
//
996
1002
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
997
1003
// it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
@@ -1006,13 +1012,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1006
1012
permit_variants : bool ,
1007
1013
) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1008
1014
debug ! ( %qself_ty, ?assoc_segment. ident) ;
1015
+ let result = self . lower_assoc_path_inner (
1016
+ hir_ref_id,
1017
+ span,
1018
+ qself_ty,
1019
+ qself,
1020
+ assoc_segment,
1021
+ permit_variants,
1022
+ ) ;
1023
+ self . record_res ( hir_ref_id, result. map ( |( _, def_kind, def_id) | ( def_kind, def_id) ) ) ;
1024
+ result
1025
+ }
1026
+
1027
+ fn lower_assoc_path_inner (
1028
+ & self ,
1029
+ hir_ref_id : HirId ,
1030
+ span : Span ,
1031
+ qself_ty : Ty < ' tcx > ,
1032
+ qself : & ' tcx hir:: Ty < ' tcx > ,
1033
+ assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1034
+ permit_variants : bool ,
1035
+ ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
1009
1036
let tcx = self . tcx ( ) ;
1010
1037
1011
1038
let assoc_ident = assoc_segment. ident ;
1012
- let qself_res = if let hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) = & qself. kind {
1013
- path. res
1014
- } else {
1015
- Res :: Err
1039
+ let qself_res = match & qself. kind {
1040
+ hir:: TyKind :: Path ( qpath) => self . upcast ( ) . qpath_res ( qpath, qself. hir_id ) ,
1041
+ _ => Res :: Err ,
1016
1042
} ;
1017
1043
1018
1044
// Check if we have an enum variant or an inherent associated type.
@@ -1038,15 +1064,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1038
1064
}
1039
1065
1040
1066
// FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1041
- if let Some ( ( ty, did ) ) = self . probe_inherent_assoc_ty (
1067
+ if let Some ( ( ty, def_id ) ) = self . probe_inherent_assoc_ty (
1042
1068
assoc_ident,
1043
1069
assoc_segment,
1044
1070
adt_def. did ( ) ,
1045
1071
qself_ty,
1046
1072
hir_ref_id,
1047
1073
span,
1048
1074
) ? {
1049
- return Ok ( ( ty, DefKind :: AssocTy , did ) ) ;
1075
+ return Ok ( ( ty, DefKind :: AssocTy , def_id ) ) ;
1050
1076
}
1051
1077
}
1052
1078
@@ -1077,13 +1103,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1077
1103
) ?
1078
1104
}
1079
1105
(
1080
- & ty:: Param ( _) ,
1081
- Res :: SelfTyParam { trait_ : param_did } | Res :: Def ( DefKind :: TyParam , param_did) ,
1106
+ ty:: Param ( _) ,
1107
+ Res :: SelfTyParam { trait_ : param_def_id }
1108
+ | Res :: Def ( DefKind :: TyParam , param_def_id) ,
1082
1109
) => self . probe_single_ty_param_bound_for_assoc_ty (
1083
- param_did . expect_local ( ) ,
1110
+ param_def_id . expect_local ( ) ,
1084
1111
assoc_ident,
1085
1112
span,
1086
1113
) ?,
1114
+ ( ty:: Alias ( ty:: Projection , alias_ty) , Res :: Def ( DefKind :: AssocTy , _) ) => {
1115
+ // FIXME: Utilizing `item_bounds` for this is cycle-prone.
1116
+ let predicates = tcx. item_bounds ( alias_ty. def_id ) . instantiate ( tcx, alias_ty. args ) ;
1117
+
1118
+ self . probe_single_bound_for_assoc_item (
1119
+ || {
1120
+ let trait_refs = predicates. iter ( ) . filter_map ( |pred| {
1121
+ pred. as_trait_clause ( ) . map ( |t| t. map_bound ( |t| t. trait_ref ) )
1122
+ } ) ;
1123
+ traits:: transitive_bounds_that_define_assoc_item (
1124
+ tcx,
1125
+ trait_refs,
1126
+ assoc_ident,
1127
+ )
1128
+ } ,
1129
+ qself_ty,
1130
+ None ,
1131
+ ty:: AssocKind :: Type ,
1132
+ assoc_ident,
1133
+ span,
1134
+ None ,
1135
+ ) ?
1136
+ }
1087
1137
_ => {
1088
1138
let reported = if variant_resolution. is_some ( ) {
1089
1139
// Variant in type position
@@ -1187,6 +1237,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1187
1237
) ;
1188
1238
} ) ;
1189
1239
}
1240
+
1190
1241
Ok ( ( ty, DefKind :: AssocTy , assoc_ty. def_id ) )
1191
1242
}
1192
1243
0 commit comments