@@ -126,8 +126,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
126
126
Some ( ref_id) => {
127
127
let trait_id = ty:: trait_of_item ( tcx, def_id)
128
128
. unwrap ( ) ;
129
+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
130
+ . substs ;
129
131
resolve_trait_associated_const ( tcx, ti, trait_id,
130
- ref_id )
132
+ substs )
131
133
}
132
134
// Technically, without knowing anything about the
133
135
// expression that generates the obligation, we could
@@ -172,8 +174,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
172
174
// a trait-associated const if the caller gives us
173
175
// the expression that refers to it.
174
176
Some ( ref_id) => {
177
+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
178
+ . substs ;
175
179
resolve_trait_associated_const ( tcx, ti, trait_id,
176
- ref_id ) . map ( |e| e. id )
180
+ substs ) . map ( |e| e. id )
177
181
}
178
182
None => None
179
183
}
@@ -633,9 +637,23 @@ pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
633
637
uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
634
638
} }
635
639
640
+ // After type checking, `eval_const_expr_partial` should always suffice. The
641
+ // reason for providing `eval_const_expr_with_substs` is to allow
642
+ // trait-associated consts to be evaluated *during* type checking, when the
643
+ // substs for each expression have not been written into `tcx` yet.
636
644
pub fn eval_const_expr_partial < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
637
645
e : & Expr ,
638
646
ty_hint : Option < Ty < ' tcx > > ) -> EvalResult {
647
+ eval_const_expr_with_substs ( tcx, e, ty_hint, |id| {
648
+ ty:: node_id_item_substs ( tcx, id) . substs
649
+ } )
650
+ }
651
+
652
+ pub fn eval_const_expr_with_substs < ' tcx , S > ( tcx : & ty:: ctxt < ' tcx > ,
653
+ e : & Expr ,
654
+ ty_hint : Option < Ty < ' tcx > > ,
655
+ get_substs : S ) -> EvalResult
656
+ where S : Fn ( ast:: NodeId ) -> subst:: Substs < ' tcx > {
639
657
fn fromb ( b : bool ) -> const_val { const_int ( b as i64 ) }
640
658
641
659
let ety = ty_hint. or_else ( || ty:: expr_ty_opt ( tcx, e) ) ;
@@ -826,8 +844,11 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
826
844
def:: FromTrait ( trait_id) => match tcx. map . find ( def_id. node ) {
827
845
Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
828
846
ast:: ConstTraitItem ( ref ty, _) => {
829
- ( resolve_trait_associated_const ( tcx, ti,
830
- trait_id, e. id ) ,
847
+ let substs = get_substs ( e. id ) ;
848
+ ( resolve_trait_associated_const ( tcx,
849
+ ti,
850
+ trait_id,
851
+ substs) ,
831
852
Some ( & * * ty) )
832
853
}
833
854
_ => ( None , None )
@@ -926,10 +947,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
926
947
fn resolve_trait_associated_const < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
927
948
ti : & ' tcx ast:: TraitItem ,
928
949
trait_id : ast:: DefId ,
929
- ref_id : ast :: NodeId )
950
+ rcvr_substs : subst :: Substs < ' tcx > )
930
951
-> Option < & ' tcx Expr >
931
952
{
932
- let rcvr_substs = ty:: node_id_item_substs ( tcx, ref_id) . substs ;
933
953
let subst:: SeparateVecsPerParamSpace {
934
954
types : rcvr_type,
935
955
selfs : rcvr_self,
@@ -1081,19 +1101,21 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<Ordering> {
1081
1101
} )
1082
1102
}
1083
1103
1084
- pub fn compare_lit_exprs < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
1085
- a : & Expr ,
1086
- b : & Expr ,
1087
- ty_hint : Option < Ty < ' tcx > > )
1088
- -> Option < Ordering > {
1089
- let a = match eval_const_expr_partial ( tcx, a, ty_hint) {
1104
+ pub fn compare_lit_exprs < ' tcx , S > ( tcx : & ty:: ctxt < ' tcx > ,
1105
+ a : & Expr ,
1106
+ b : & Expr ,
1107
+ ty_hint : Option < Ty < ' tcx > > ,
1108
+ get_substs : S ) -> Option < Ordering >
1109
+ where S : Fn ( ast:: NodeId ) -> subst:: Substs < ' tcx > {
1110
+ let a = match eval_const_expr_with_substs ( tcx, a, ty_hint,
1111
+ |id| { get_substs ( id) } ) {
1090
1112
Ok ( a) => a,
1091
1113
Err ( e) => {
1092
1114
tcx. sess . span_err ( a. span , & e. description ( ) ) ;
1093
1115
return None ;
1094
1116
}
1095
1117
} ;
1096
- let b = match eval_const_expr_partial ( tcx, b, ty_hint) {
1118
+ let b = match eval_const_expr_with_substs ( tcx, b, ty_hint, get_substs ) {
1097
1119
Ok ( b) => b,
1098
1120
Err ( e) => {
1099
1121
tcx. sess . span_err ( b. span , & e. description ( ) ) ;
0 commit comments