@@ -128,8 +128,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
128128 Some ( ref_id) => {
129129 let trait_id = ty:: trait_of_item ( tcx, def_id)
130130 . unwrap ( ) ;
131+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
132+ . substs ;
131133 resolve_trait_associated_const ( tcx, ti, trait_id,
132- ref_id )
134+ substs )
133135 }
134136 // Technically, without knowing anything about the
135137 // 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>,
174176 // a trait-associated const if the caller gives us
175177 // the expression that refers to it.
176178 Some ( ref_id) => {
179+ let substs = ty:: node_id_item_substs ( tcx, ref_id)
180+ . substs ;
177181 resolve_trait_associated_const ( tcx, ti, trait_id,
178- ref_id ) . map ( |e| e. id )
182+ substs ) . map ( |e| e. id )
179183 }
180184 None => None
181185 }
@@ -702,9 +706,23 @@ pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
702706 uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
703707} }
704708
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.
705713pub fn eval_const_expr_partial < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
706714 e : & Expr ,
707715 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 > {
708726 fn fromb ( b : bool ) -> const_val { const_int ( b as i64 ) }
709727
710728 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>,
895913 def:: FromTrait ( trait_id) => match tcx. map . find ( def_id. node ) {
896914 Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
897915 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) ,
900921 Some ( & * * ty) )
901922 }
902923 _ => ( None , None )
@@ -995,10 +1016,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
9951016fn resolve_trait_associated_const < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
9961017 ti : & ' tcx ast:: TraitItem ,
9971018 trait_id : ast:: DefId ,
998- ref_id : ast :: NodeId )
1019+ rcvr_substs : subst :: Substs < ' tcx > )
9991020 -> Option < & ' tcx Expr >
10001021{
1001- let rcvr_substs = ty:: node_id_item_substs ( tcx, ref_id) . substs ;
10021022 let subst:: SeparateVecsPerParamSpace {
10031023 types : rcvr_type,
10041024 selfs : rcvr_self,
@@ -1150,19 +1170,21 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<Ordering> {
11501170 } )
11511171}
11521172
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) } ) {
11591181 Ok ( a) => a,
11601182 Err ( e) => {
11611183 tcx. sess . span_err ( a. span , & e. description ( ) ) ;
11621184 return None ;
11631185 }
11641186 } ;
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 ) {
11661188 Ok ( b) => b,
11671189 Err ( e) => {
11681190 tcx. sess . span_err ( b. span , & e. description ( ) ) ;
0 commit comments