@@ -8,9 +8,10 @@ use rustc_middle::ty::util::IntTypeExt;
8
8
use rustc_middle:: ty:: { self , ImplTraitInTraitData , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
9
9
use rustc_span:: symbol:: Ident ;
10
10
use rustc_span:: { Span , DUMMY_SP } ;
11
+ use rustc_trait_selection:: traits;
11
12
12
- use super :: ItemCtxt ;
13
13
use super :: { bad_placeholder, is_suggestable_infer_ty} ;
14
+ use super :: { AstConv , ItemCtxt } ;
14
15
pub use opaque:: test_opaque_hidden_types;
15
16
16
17
mod opaque;
@@ -60,35 +61,77 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
60
61
. expect ( "const parameter types cannot be generic" ) ;
61
62
}
62
63
63
- Node :: TypeBinding ( binding @ & TypeBinding { hir_id : binding_id , .. } )
64
- if let Node :: TraitRef ( trait_ref ) = tcx . hir ( ) . get ( tcx . hir ( ) . parent_id ( binding_id ) ) =>
65
- {
64
+ Node :: TypeBinding (
65
+ binding @ & TypeBinding { hir_id : binding_id , ident , gen_args , span , .. } ,
66
+ ) if let Node :: TraitRef ( trait_ref ) = tcx . hir ( ) . get ( tcx . hir ( ) . parent_id ( binding_id ) ) => {
66
67
let Some ( trait_def_id) = trait_ref. trait_def_id ( ) else {
67
68
return Ty :: new_error_with_message (
68
69
tcx,
69
70
tcx. def_span ( def_id) ,
70
- "Could not find trait" ,
71
+ "could not find trait" ,
71
72
) ;
72
73
} ;
73
- let assoc_items = tcx. associated_items ( trait_def_id) ;
74
- let assoc_item = assoc_items. find_by_name_and_kind (
75
- tcx,
76
- binding. ident ,
77
- ty:: AssocKind :: Const ,
78
- def_id. to_def_id ( ) ,
74
+
75
+ // FIXME(associated_const_equality): Doing all this work *here* isn't great.
76
+ // Ideally, we would've computed this already somewhere else in a query.
77
+
78
+ let icx = ItemCtxt :: new ( tcx, trait_def_id. expect_local ( ) ) ;
79
+ let trait_segment = trait_ref. path . segments . last ( ) . unwrap ( ) ;
80
+ let ( trait_args, _) = icx. astconv ( ) . create_args_for_ast_path (
81
+ trait_ref. path . span ,
82
+ trait_def_id,
83
+ & [ ] ,
84
+ trait_segment,
85
+ trait_segment. args ( ) ,
86
+ trait_segment. infer_args ,
87
+ // FIXME(associated_const_equality): This isn't correct, it should be the concrete /
88
+ // instantiated self type. Theoretically, we could search for it in the HIR of the
89
+ // parent item but that's super fragile and hairy.
90
+ Some ( tcx. types . self_param ) ,
91
+ ty:: BoundConstness :: NotConst ,
79
92
) ;
80
- return if let Some ( assoc_item) = assoc_item {
81
- tcx. type_of ( assoc_item. def_id )
82
- . no_bound_vars ( )
83
- . expect ( "const parameter types cannot be generic" )
84
- } else {
85
- // FIXME(associated_const_equality): add a useful error message here.
86
- Ty :: new_error_with_message (
93
+ let trait_ref = ty:: Binder :: bind_with_vars (
94
+ ty:: TraitRef :: new ( tcx, trait_def_id, trait_args) ,
95
+ tcx. late_bound_vars ( trait_ref. hir_ref_id ) ,
96
+ ) ;
97
+
98
+ // We shouldn't need to deal with ambiguity since `add_predicates_for_ast_type_binding`
99
+ // should've already bailed out early in such case.
100
+ let Some ( ( assoc_item, parent_args) ) =
101
+ traits:: supertraits ( tcx, trait_ref) . find_map ( |trait_ref| {
102
+ tcx. associated_items ( trait_ref. def_id ( ) )
103
+ . find_by_name_and_kind (
104
+ tcx,
105
+ binding. ident ,
106
+ ty:: AssocKind :: Const ,
107
+ trait_ref. def_id ( ) ,
108
+ )
109
+ // FIXME(fmease): `skip_binder` is fishy!
110
+ . map ( |item| ( item, trait_ref. skip_binder ( ) . args ) )
111
+ } )
112
+ else {
113
+ return Ty :: new_error_with_message (
87
114
tcx,
88
115
tcx. def_span ( def_id) ,
89
- "Could not find associated const on trait" ,
90
- )
116
+ "could not find associated const on trait" ,
117
+ ) ;
91
118
} ;
119
+
120
+ let args = icx. astconv ( ) . create_args_for_associated_item (
121
+ span,
122
+ assoc_item. def_id ,
123
+ // FIXME(fmease): This is gross as hell!
124
+ & hir:: PathSegment {
125
+ ident,
126
+ hir_id,
127
+ res : def:: Res :: Err ,
128
+ args : Some ( gen_args) ,
129
+ infer_args : false ,
130
+ } ,
131
+ parent_args,
132
+ ) ;
133
+
134
+ return tcx. type_of ( assoc_item. def_id ) . instantiate ( tcx, args) ;
92
135
}
93
136
94
137
// This match arm is for when the def_id appears in a GAT whose
@@ -120,8 +163,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
120
163
. unwrap ( )
121
164
. 0
122
165
. def_id ;
123
- let item_ctxt = & ItemCtxt :: new ( tcx, item_def_id) as & dyn crate :: astconv:: AstConv < ' _ > ;
124
- let ty = item_ctxt. ast_ty_to_ty ( hir_ty) ;
166
+ let ty = ItemCtxt :: new ( tcx, item_def_id) . to_ty ( hir_ty) ;
125
167
126
168
// Iterate through the generics of the projection to find the one that corresponds to
127
169
// the def_id that this query was called with. We filter to only type and const args here
0 commit comments