@@ -21,7 +21,6 @@ use rustc::ty::{self, Ty, TyCtxt};
21
21
use rustc:: ty:: maps:: Providers ;
22
22
use rustc:: ty:: util:: IntTypeExt ;
23
23
use rustc:: ty:: subst:: { Substs , Subst } ;
24
- use rustc:: traits:: Reveal ;
25
24
use rustc:: util:: common:: ErrorReported ;
26
25
use rustc:: util:: nodemap:: DefIdMap ;
27
26
@@ -49,24 +48,21 @@ macro_rules! math {
49
48
}
50
49
}
51
50
52
- /// * `def_id` is the id of the constant.
53
- /// * `substs` is the monomorphized substitutions for the expression.
54
- ///
55
- /// `substs` is optional and is used for associated constants.
56
- /// This generally happens in late/trans const evaluation.
51
+ /// * `DefId` is the id of the constant.
52
+ /// * `Substs` is the monomorphized substitutions for the expression.
57
53
pub fn lookup_const_by_id < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
58
- def_id : DefId ,
59
- substs : & ' tcx Substs < ' tcx > )
54
+ key : ty:: ParamEnvAnd < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > )
60
55
-> Option < ( DefId , & ' tcx Substs < ' tcx > ) > {
56
+ let ( def_id, _) = key. value ;
61
57
if let Some ( node_id) = tcx. hir . as_local_node_id ( def_id) {
62
58
match tcx. hir . find ( node_id) {
63
59
Some ( hir_map:: NodeTraitItem ( _) ) => {
64
60
// If we have a trait item and the substitutions for it,
65
61
// `resolve_trait_associated_const` will select an impl
66
62
// or the default.
67
- resolve_trait_associated_const ( tcx, def_id , substs )
63
+ resolve_trait_associated_const ( tcx, key )
68
64
}
69
- _ => Some ( ( def_id , substs ) )
65
+ _ => Some ( key . value )
70
66
}
71
67
} else {
72
68
match tcx. describe_def ( def_id) {
@@ -76,31 +72,34 @@ pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
76
72
// trait-associated const if the caller gives us the
77
73
// substitutions for the reference to it.
78
74
if tcx. trait_of_item ( def_id) . is_some ( ) {
79
- resolve_trait_associated_const ( tcx, def_id , substs )
75
+ resolve_trait_associated_const ( tcx, key )
80
76
} else {
81
- Some ( ( def_id , substs ) )
77
+ Some ( key . value )
82
78
}
83
79
}
84
- _ => Some ( ( def_id , substs ) )
80
+ _ => Some ( key . value )
85
81
}
86
82
}
87
83
}
88
84
89
85
pub struct ConstContext < ' a , ' tcx : ' a > {
90
86
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
91
87
tables : & ' a ty:: TypeckTables < ' tcx > ,
88
+ param_env : ty:: ParamEnv < ' tcx > ,
92
89
substs : & ' tcx Substs < ' tcx > ,
93
90
fn_args : Option < DefIdMap < ConstVal < ' tcx > > >
94
91
}
95
92
96
93
impl < ' a , ' tcx > ConstContext < ' a , ' tcx > {
97
94
pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
98
- tables : & ' a ty:: TypeckTables < ' tcx > ,
99
- substs : & ' tcx Substs < ' tcx > ) -> Self {
95
+ param_env_and_substs : ty:: ParamEnvAnd < ' tcx , & ' tcx Substs < ' tcx > > ,
96
+ tables : & ' a ty:: TypeckTables < ' tcx > )
97
+ -> Self {
100
98
ConstContext {
101
99
tcx,
100
+ param_env : param_env_and_substs. param_env ,
102
101
tables,
103
- substs,
102
+ substs : param_env_and_substs . value ,
104
103
fn_args : None
105
104
}
106
105
}
@@ -279,7 +278,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
279
278
match cx. tables . qpath_def ( qpath, e. id ) {
280
279
Def :: Const ( def_id) |
281
280
Def :: AssociatedConst ( def_id) => {
282
- match tcx. at ( e. span ) . const_eval ( ( def_id, substs) ) {
281
+ match tcx. at ( e. span ) . const_eval ( cx . param_env . and ( ( def_id, substs) ) ) {
283
282
Ok ( val) => val,
284
283
Err ( ConstEvalErr { kind : TypeckError , .. } ) => {
285
284
signal ! ( e, TypeckError ) ;
@@ -323,10 +322,9 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
323
322
324
323
if tcx. fn_sig ( def_id) . abi ( ) == Abi :: RustIntrinsic {
325
324
let layout_of = |ty : Ty < ' tcx > | {
326
- ty. layout ( tcx, ty:: ParamEnv :: empty ( traits:: Reveal :: All ) )
327
- . map_err ( |err| {
328
- ConstEvalErr { span : e. span , kind : LayoutError ( err) }
329
- } )
325
+ ty. layout ( tcx, cx. param_env ) . map_err ( |err| {
326
+ ConstEvalErr { span : e. span , kind : LayoutError ( err) }
327
+ } )
330
328
} ;
331
329
match & tcx. item_name ( def_id) . as_str ( ) [ ..] {
332
330
"size_of" => {
@@ -377,7 +375,8 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
377
375
}
378
376
debug ! ( "const call({:?})" , call_args) ;
379
377
let callee_cx = ConstContext {
380
- tcx : tcx,
378
+ tcx,
379
+ param_env : cx. param_env ,
381
380
tables : tcx. typeck_tables_of ( def_id) ,
382
381
substs : substs,
383
382
fn_args : Some ( call_args)
@@ -477,17 +476,17 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
477
476
}
478
477
479
478
fn resolve_trait_associated_const < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
480
- def_id : DefId ,
481
- substs : & ' tcx Substs < ' tcx > )
479
+ key : ty:: ParamEnvAnd < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > )
482
480
-> Option < ( DefId , & ' tcx Substs < ' tcx > ) > {
481
+ let param_env = key. param_env ;
482
+ let ( def_id, substs) = key. value ;
483
483
let trait_item = tcx. associated_item ( def_id) ;
484
484
let trait_id = trait_item. container . id ( ) ;
485
485
let trait_ref = ty:: Binder ( ty:: TraitRef :: new ( trait_id, substs) ) ;
486
486
debug ! ( "resolve_trait_associated_const: trait_ref={:?}" ,
487
487
trait_ref) ;
488
488
489
489
tcx. infer_ctxt ( ) . enter ( |infcx| {
490
- let param_env = ty:: ParamEnv :: empty ( Reveal :: UserFacing ) ;
491
490
let mut selcx = traits:: SelectionContext :: new ( & infcx) ;
492
491
let obligation = traits:: Obligation :: new ( traits:: ObligationCause :: dummy ( ) ,
493
492
param_env,
@@ -506,10 +505,8 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
506
505
} ;
507
506
508
507
// NOTE: this code does not currently account for specialization, but when
509
- // it does so, it should hook into the Reveal to determine when the
510
- // constant should resolve; this will also require plumbing through to this
511
- // function whether we are in "trans mode" to pick the right Reveal
512
- // when constructing the inference context above.
508
+ // it does so, it should hook into the param_env.reveal to determine when the
509
+ // constant should resolve.
513
510
match selection {
514
511
traits:: VtableImpl ( ref impl_data) => {
515
512
let name = trait_item. name ;
@@ -524,15 +521,16 @@ fn resolve_trait_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
524
521
}
525
522
None => {
526
523
if trait_item. defaultness . has_value ( ) {
527
- Some ( ( def_id , substs ) )
524
+ Some ( key . value )
528
525
} else {
529
526
None
530
527
}
531
528
}
532
529
}
533
530
}
531
+ traits:: VtableParam ( _) => None ,
534
532
_ => {
535
- bug ! ( "resolve_trait_associated_const: unexpected vtable type" )
533
+ bug ! ( "resolve_trait_associated_const: unexpected vtable type {:?}" , selection )
536
534
}
537
535
}
538
536
} )
@@ -761,13 +759,13 @@ pub fn provide(providers: &mut Providers) {
761
759
}
762
760
763
761
fn const_eval < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
764
- ( def_id , substs ) : ( DefId , & ' tcx Substs < ' tcx > ) )
762
+ key : ty :: ParamEnvAnd < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > )
765
763
-> EvalResult < ' tcx > {
766
- let ( def_id, substs) = if let Some ( resolved) = lookup_const_by_id ( tcx, def_id , substs ) {
764
+ let ( def_id, substs) = if let Some ( resolved) = lookup_const_by_id ( tcx, key ) {
767
765
resolved
768
766
} else {
769
767
return Err ( ConstEvalErr {
770
- span : tcx. def_span ( def_id ) ,
768
+ span : tcx. def_span ( key . value . 0 ) ,
771
769
kind : TypeckError
772
770
} ) ;
773
771
} ;
@@ -779,5 +777,5 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
779
777
} else {
780
778
tcx. sess . cstore . item_body ( tcx, def_id)
781
779
} ;
782
- ConstContext :: new ( tcx, tables , substs ) . eval ( & body. value )
780
+ ConstContext :: new ( tcx, key . param_env . and ( substs ) , tables ) . eval ( & body. value )
783
781
}
0 commit comments