@@ -13,9 +13,7 @@ use rustc::middle::const_val::ConstAggregate::*;
1313use rustc:: middle:: const_val:: ErrKind :: * ;
1414use rustc:: middle:: const_val:: { ByteArray , ConstVal , ConstEvalErr , EvalResult , ErrKind } ;
1515
16- use rustc:: hir:: map as hir_map;
1716use rustc:: hir:: map:: blocks:: FnLikeNode ;
18- use rustc:: traits;
1917use rustc:: hir:: def:: { Def , CtorKind } ;
2018use rustc:: hir:: def_id:: DefId ;
2119use rustc:: ty:: { self , Ty , TyCtxt } ;
@@ -54,33 +52,12 @@ macro_rules! math {
5452pub fn lookup_const_by_id < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
5553 key : ty:: ParamEnvAnd < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > )
5654 -> Option < ( DefId , & ' tcx Substs < ' tcx > ) > {
57- let ( def_id, _) = key. value ;
58- if let Some ( node_id) = tcx. hir . as_local_node_id ( def_id) {
59- match tcx. hir . find ( node_id) {
60- Some ( hir_map:: NodeTraitItem ( _) ) => {
61- // If we have a trait item and the substitutions for it,
62- // `resolve_trait_associated_const` will select an impl
63- // or the default.
64- resolve_trait_associated_const ( tcx, key)
65- }
66- _ => Some ( key. value )
67- }
68- } else {
69- match tcx. describe_def ( def_id) {
70- Some ( Def :: AssociatedConst ( _) ) => {
71- // As mentioned in the comments above for in-crate
72- // constants, we only try to find the expression for a
73- // trait-associated const if the caller gives us the
74- // substitutions for the reference to it.
75- if tcx. trait_of_item ( def_id) . is_some ( ) {
76- resolve_trait_associated_const ( tcx, key)
77- } else {
78- Some ( key. value )
79- }
80- }
81- _ => Some ( key. value )
82- }
83- }
55+ ty:: Instance :: resolve (
56+ tcx,
57+ key. param_env ,
58+ key. value . 0 ,
59+ key. value . 1 ,
60+ ) . map ( |instance| ( instance. def_id ( ) , instance. substs ) )
8461}
8562
8663pub struct ConstContext < ' a , ' tcx : ' a > {
@@ -119,6 +96,7 @@ type CastResult<'tcx> = Result<ConstVal<'tcx>, ErrKind<'tcx>>;
11996
12097fn eval_const_expr_partial < ' a , ' tcx > ( cx : & ConstContext < ' a , ' tcx > ,
12198 e : & ' tcx Expr ) -> EvalResult < ' tcx > {
99+ trace ! ( "eval_const_expr_partial: {:?}" , e) ;
122100 let tcx = cx. tcx ;
123101 let ty = cx. tables . expr_ty ( e) . subst ( tcx, cx. substs ) ;
124102 let mk_const = |val| tcx. mk_const ( ty:: Const { val, ty } ) ;
@@ -289,6 +267,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
289267 match cx. tables . qpath_def ( qpath, e. hir_id ) {
290268 Def :: Const ( def_id) |
291269 Def :: AssociatedConst ( def_id) => {
270+ let substs = tcx. normalize_associated_type_in_env ( & substs, cx. param_env ) ;
292271 match tcx. at ( e. span ) . const_eval ( cx. param_env . and ( ( def_id, substs) ) ) {
293272 Ok ( val) => val,
294273 Err ( ConstEvalErr { kind : TypeckError , .. } ) => {
@@ -486,67 +465,6 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
486465 Ok ( result)
487466}
488467
489- fn resolve_trait_associated_const < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
490- key : ty:: ParamEnvAnd < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > )
491- -> Option < ( DefId , & ' tcx Substs < ' tcx > ) > {
492- let param_env = key. param_env ;
493- let ( def_id, substs) = key. value ;
494- let trait_item = tcx. associated_item ( def_id) ;
495- let trait_id = trait_item. container . id ( ) ;
496- let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_id, substs) ) ;
497- debug ! ( "resolve_trait_associated_const: trait_ref={:?}" ,
498- trait_ref) ;
499-
500- tcx. infer_ctxt ( ) . enter ( |infcx| {
501- let mut selcx = traits:: SelectionContext :: new ( & infcx) ;
502- let obligation = traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) ,
503- param_env,
504- trait_ref. to_poly_trait_predicate ( ) ) ;
505- let selection = match selcx. select ( & obligation) {
506- Ok ( Some ( vtable) ) => vtable,
507- // Still ambiguous, so give up and let the caller decide whether this
508- // expression is really needed yet. Some associated constant values
509- // can't be evaluated until monomorphization is done in trans.
510- Ok ( None ) => {
511- return None
512- }
513- Err ( _) => {
514- return None
515- }
516- } ;
517-
518- // NOTE: this code does not currently account for specialization, but when
519- // it does so, it should hook into the param_env.reveal to determine when the
520- // constant should resolve.
521- match selection {
522- traits:: VtableImpl ( ref impl_data) => {
523- let name = trait_item. name ;
524- let ac = tcx. associated_items ( impl_data. impl_def_id )
525- . find ( |item| item. kind == ty:: AssociatedKind :: Const && item. name == name) ;
526- match ac {
527- // FIXME(eddyb) Use proper Instance resolution to
528- // get the correct Substs returned from here.
529- Some ( ic) => {
530- let substs = Substs :: identity_for_item ( tcx, ic. def_id ) ;
531- Some ( ( ic. def_id , substs) )
532- }
533- None => {
534- if trait_item. defaultness . has_value ( ) {
535- Some ( key. value )
536- } else {
537- None
538- }
539- }
540- }
541- }
542- traits:: VtableParam ( _) => None ,
543- _ => {
544- bug ! ( "resolve_trait_associated_const: unexpected vtable type {:?}" , selection)
545- }
546- }
547- } )
548- }
549-
550468fn cast_const_int < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
551469 val : ConstInt ,
552470 ty : Ty < ' tcx > )
0 commit comments