@@ -128,8 +128,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
128
128
Some ( ref_id) => {
129
129
let trait_id = ty:: trait_of_item ( tcx, def_id)
130
130
. unwrap ( ) ;
131
+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
132
+ . substs ;
131
133
resolve_trait_associated_const ( tcx, ti, trait_id,
132
- ref_id )
134
+ substs )
133
135
}
134
136
// Technically, without knowing anything about the
135
137
// expression that generates the obligation, we could
@@ -174,8 +176,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
174
176
// a trait-associated const if the caller gives us
175
177
// the expression that refers to it.
176
178
Some ( ref_id) => {
179
+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
180
+ . substs ;
177
181
resolve_trait_associated_const ( tcx, ti, trait_id,
178
- ref_id ) . map ( |e| e. id )
182
+ substs ) . map ( |e| e. id )
179
183
}
180
184
None => None
181
185
}
@@ -702,9 +706,23 @@ pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
702
706
uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
703
707
} }
704
708
709
+ // After type checking, `eval_const_expr_partial` should always suffice. The
710
+ // reason for providing `eval_const_expr_with_substs` is to allow
711
+ // trait-associated consts to be evaluated *during* type checking, when the
712
+ // substs for each expression have not been written into `tcx` yet.
705
713
pub fn eval_const_expr_partial < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
706
714
e : & Expr ,
707
715
ty_hint : Option < Ty < ' tcx > > ) -> EvalResult {
716
+ eval_const_expr_with_substs ( tcx, e, ty_hint, |id| {
717
+ ty:: node_id_item_substs ( tcx, id) . substs
718
+ } )
719
+ }
720
+
721
+ pub fn eval_const_expr_with_substs < ' tcx , S > ( tcx : & ty:: ctxt < ' tcx > ,
722
+ e : & Expr ,
723
+ ty_hint : Option < Ty < ' tcx > > ,
724
+ get_substs : S ) -> EvalResult
725
+ where S : Fn ( ast:: NodeId ) -> subst:: Substs < ' tcx > {
708
726
fn fromb ( b : bool ) -> const_val { const_int ( b as i64 ) }
709
727
710
728
let ety = ty_hint. or_else ( || ty:: expr_ty_opt ( tcx, e) ) ;
@@ -895,8 +913,11 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
895
913
def:: FromTrait ( trait_id) => match tcx. map . find ( def_id. node ) {
896
914
Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
897
915
ast:: ConstTraitItem ( ref ty, _) => {
898
- ( resolve_trait_associated_const ( tcx, ti,
899
- trait_id, e. id ) ,
916
+ let substs = get_substs ( e. id ) ;
917
+ ( resolve_trait_associated_const ( tcx,
918
+ ti,
919
+ trait_id,
920
+ substs) ,
900
921
Some ( & * * ty) )
901
922
}
902
923
_ => ( None , None )
@@ -995,10 +1016,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
995
1016
fn resolve_trait_associated_const < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
996
1017
ti : & ' tcx ast:: TraitItem ,
997
1018
trait_id : ast:: DefId ,
998
- ref_id : ast :: NodeId )
1019
+ rcvr_substs : subst :: Substs < ' tcx > )
999
1020
-> Option < & ' tcx Expr >
1000
1021
{
1001
- let rcvr_substs = ty:: node_id_item_substs ( tcx, ref_id) . substs ;
1002
1022
let subst:: SeparateVecsPerParamSpace {
1003
1023
types : rcvr_type,
1004
1024
selfs : rcvr_self,
@@ -1150,19 +1170,21 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<Ordering> {
1150
1170
} )
1151
1171
}
1152
1172
1153
- pub fn compare_lit_exprs < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
1154
- a : & Expr ,
1155
- b : & Expr ,
1156
- ty_hint : Option < Ty < ' tcx > > )
1157
- -> Option < Ordering > {
1158
- let a = match eval_const_expr_partial ( tcx, a, ty_hint) {
1173
+ pub fn compare_lit_exprs < ' tcx , S > ( tcx : & ty:: ctxt < ' tcx > ,
1174
+ a : & Expr ,
1175
+ b : & Expr ,
1176
+ ty_hint : Option < Ty < ' tcx > > ,
1177
+ get_substs : S ) -> Option < Ordering >
1178
+ where S : Fn ( ast:: NodeId ) -> subst:: Substs < ' tcx > {
1179
+ let a = match eval_const_expr_with_substs ( tcx, a, ty_hint,
1180
+ |id| { get_substs ( id) } ) {
1159
1181
Ok ( a) => a,
1160
1182
Err ( e) => {
1161
1183
tcx. sess . span_err ( a. span , & e. description ( ) ) ;
1162
1184
return None ;
1163
1185
}
1164
1186
} ;
1165
- let b = match eval_const_expr_partial ( tcx, b, ty_hint) {
1187
+ let b = match eval_const_expr_with_substs ( tcx, b, ty_hint, get_substs ) {
1166
1188
Ok ( b) => b,
1167
1189
Err ( e) => {
1168
1190
tcx. sess . span_err ( b. span , & e. description ( ) ) ;
0 commit comments