@@ -18,6 +18,7 @@ use front::map as ast_map;
18
18
use front:: map:: blocks:: FnLikeNode ;
19
19
use middle:: cstore:: { self , CrateStore , InlinedItem } ;
20
20
use middle:: { def, infer, subst, traits} ;
21
+ use middle:: subst:: Subst ;
21
22
use middle:: def_id:: DefId ;
22
23
use middle:: pat_util:: def_to_path;
23
24
use middle:: ty:: { self , Ty } ;
@@ -48,7 +49,7 @@ fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
48
49
match opt_def {
49
50
Some ( def:: DefConst ( def_id) ) |
50
51
Some ( def:: DefAssociatedConst ( def_id) ) => {
51
- lookup_const_by_id ( tcx, def_id, Some ( e. id ) )
52
+ lookup_const_by_id ( tcx, def_id, Some ( e. id ) , None )
52
53
}
53
54
Some ( def:: DefVariant ( enum_def, variant_def, _) ) => {
54
55
lookup_variant_by_id ( tcx, enum_def, variant_def)
@@ -88,9 +89,17 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
88
89
}
89
90
}
90
91
92
+ /// * `def_id` is the id of the constant.
93
+ /// * `maybe_ref_id` is the id of the expr referencing the constant.
94
+ /// * `param_substs` is the monomorphization substitution for the expression.
95
+ ///
96
+ /// `maybe_ref_id` and `param_substs` are optional and are used for
97
+ /// finding substitutions in associated constants. This generally
98
+ /// happens in late/trans const evaluation.
91
99
pub fn lookup_const_by_id < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
92
100
def_id : DefId ,
93
- maybe_ref_id : Option < ast:: NodeId > )
101
+ maybe_ref_id : Option < ast:: NodeId > ,
102
+ param_substs : Option < & ' tcx subst:: Substs < ' tcx > > )
94
103
-> Option < & ' tcx Expr > {
95
104
if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
96
105
match tcx. map . find ( node_id) {
@@ -111,8 +120,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
111
120
Some ( ref_id) => {
112
121
let trait_id = tcx. trait_of_item ( def_id)
113
122
. unwrap ( ) ;
114
- let substs = tcx. node_id_item_substs ( ref_id)
115
- . substs ;
123
+ let mut substs = tcx. node_id_item_substs ( ref_id)
124
+ . substs ;
125
+ if let Some ( param_substs) = param_substs {
126
+ substs = substs. subst ( tcx, param_substs) ;
127
+ }
116
128
resolve_trait_associated_const ( tcx, ti, trait_id,
117
129
substs)
118
130
}
@@ -158,8 +170,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
158
170
// a trait-associated const if the caller gives us
159
171
// the expression that refers to it.
160
172
Some ( ref_id) => {
161
- let substs = tcx. node_id_item_substs ( ref_id)
162
- . substs ;
173
+ let mut substs = tcx. node_id_item_substs ( ref_id)
174
+ . substs ;
175
+ if let Some ( param_substs) = param_substs {
176
+ substs = substs. subst ( tcx, param_substs) ;
177
+ }
163
178
resolve_trait_associated_const ( tcx, ti, trait_id,
164
179
substs) . map ( |e| e. id )
165
180
}
@@ -1013,7 +1028,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
1013
1028
_ => ( None , None )
1014
1029
}
1015
1030
} else {
1016
- ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) ) , None )
1031
+ ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) , None ) , None )
1017
1032
}
1018
1033
}
1019
1034
Some ( def:: DefAssociatedConst ( def_id) ) => {
@@ -1048,7 +1063,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
1048
1063
} ,
1049
1064
}
1050
1065
} else {
1051
- ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) ) , None )
1066
+ ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) , None ) , None )
1052
1067
}
1053
1068
}
1054
1069
Some ( def:: DefVariant ( enum_def, variant_def, _) ) => {
@@ -1260,20 +1275,16 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
1260
1275
Ok ( None ) => {
1261
1276
return None
1262
1277
}
1263
- Err ( e) => {
1264
- tcx. sess . span_bug ( ti. span ,
1265
- & format ! ( "Encountered error `{:?}` when trying \
1266
- to select an implementation for \
1267
- constant trait item reference.",
1268
- e) )
1278
+ Err ( _) => {
1279
+ return None
1269
1280
}
1270
1281
} ;
1271
1282
1272
1283
match selection {
1273
1284
traits:: VtableImpl ( ref impl_data) => {
1274
1285
match tcx. associated_consts ( impl_data. impl_def_id )
1275
1286
. iter ( ) . find ( |ic| ic. name == ti. name ) {
1276
- Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None ) ,
1287
+ Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None , None ) ,
1277
1288
None => match ti. node {
1278
1289
hir:: ConstTraitItem ( _, Some ( ref expr) ) => Some ( & * expr) ,
1279
1290
_ => None ,
0 commit comments