@@ -18,6 +18,7 @@ use front::map as ast_map;
1818use front:: map:: blocks:: FnLikeNode ;
1919use middle:: cstore:: { self , CrateStore , InlinedItem } ;
2020use middle:: { def, infer, subst, traits} ;
21+ use middle:: subst:: Subst ;
2122use middle:: def_id:: DefId ;
2223use middle:: pat_util:: def_to_path;
2324use middle:: ty:: { self , Ty } ;
@@ -48,7 +49,7 @@ fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
4849 match opt_def {
4950 Some ( def:: DefConst ( def_id) ) |
5051 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 )
5253 }
5354 Some ( def:: DefVariant ( enum_def, variant_def, _) ) => {
5455 lookup_variant_by_id ( tcx, enum_def, variant_def)
@@ -88,9 +89,17 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
8889 }
8990}
9091
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.
9199pub fn lookup_const_by_id < ' a , ' tcx : ' a > ( tcx : & ' a ty:: ctxt < ' tcx > ,
92100 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 > > )
94103 -> Option < & ' tcx Expr > {
95104 if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
96105 match tcx. map . find ( node_id) {
@@ -111,8 +120,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
111120 Some ( ref_id) => {
112121 let trait_id = tcx. trait_of_item ( def_id)
113122 . 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+ }
116128 resolve_trait_associated_const ( tcx, ti, trait_id,
117129 substs)
118130 }
@@ -158,8 +170,11 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
158170 // a trait-associated const if the caller gives us
159171 // the expression that refers to it.
160172 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+ }
163178 resolve_trait_associated_const ( tcx, ti, trait_id,
164179 substs) . map ( |e| e. id )
165180 }
@@ -1013,7 +1028,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
10131028 _ => ( None , None )
10141029 }
10151030 } 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 )
10171032 }
10181033 }
10191034 Some ( def:: DefAssociatedConst ( def_id) ) => {
@@ -1048,7 +1063,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
10481063 } ,
10491064 }
10501065 } 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 )
10521067 }
10531068 }
10541069 Some ( def:: DefVariant ( enum_def, variant_def, _) ) => {
@@ -1260,20 +1275,16 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
12601275 Ok ( None ) => {
12611276 return None
12621277 }
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
12691280 }
12701281 } ;
12711282
12721283 match selection {
12731284 traits:: VtableImpl ( ref impl_data) => {
12741285 match tcx. associated_consts ( impl_data. impl_def_id )
12751286 . 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 ) ,
12771288 None => match ti. node {
12781289 hir:: ConstTraitItem ( _, Some ( ref expr) ) => Some ( & * expr) ,
12791290 _ => None ,
0 commit comments