@@ -126,8 +126,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
126126 Some ( ref_id) => {
127127 let trait_id = ty:: trait_of_item ( tcx, def_id)
128128 . unwrap ( ) ;
129+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
130+ . substs ;
129131 resolve_trait_associated_const ( tcx, ti, trait_id,
130- ref_id )
132+ substs )
131133 }
132134 // Technically, without knowing anything about the
133135 // 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>,
172174 // a trait-associated const if the caller gives us
173175 // the expression that refers to it.
174176 Some ( ref_id) => {
177+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
178+ . substs ;
175179 resolve_trait_associated_const ( tcx, ti, trait_id,
176- ref_id ) . map ( |e| e. id )
180+ substs ) . map ( |e| e. id )
177181 }
178182 None => None
179183 }
@@ -633,9 +637,23 @@ pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
633637 uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
634638} }
635639
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.
636644pub fn eval_const_expr_partial < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
637645 e : & Expr ,
638646 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 > {
639657 fn fromb ( b : bool ) -> const_val { const_int ( b as i64 ) }
640658
641659 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>,
826844 def:: FromTrait ( trait_id) => match tcx. map . find ( def_id. node ) {
827845 Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
828846 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) ,
831852 Some ( & * * ty) )
832853 }
833854 _ => ( None , None )
@@ -926,10 +947,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
926947fn resolve_trait_associated_const < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
927948 ti : & ' tcx ast:: TraitItem ,
928949 trait_id : ast:: DefId ,
929- ref_id : ast :: NodeId )
950+ rcvr_substs : subst :: Substs < ' tcx > )
930951 -> Option < & ' tcx Expr >
931952{
932- let rcvr_substs = ty:: node_id_item_substs ( tcx, ref_id) . substs ;
933953 let subst:: SeparateVecsPerParamSpace {
934954 types : rcvr_type,
935955 selfs : rcvr_self,
@@ -1081,19 +1101,21 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<Ordering> {
10811101 } )
10821102}
10831103
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) } ) {
10901112 Ok ( a) => a,
10911113 Err ( e) => {
10921114 tcx. sess . span_err ( a. span , & e. description ( ) ) ;
10931115 return None ;
10941116 }
10951117 } ;
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 ) {
10971119 Ok ( b) => b,
10981120 Err ( e) => {
10991121 tcx. sess . span_err ( b. span , & e. description ( ) ) ;
0 commit comments