@@ -19,7 +19,6 @@ use front::map::blocks::FnLikeNode;
19
19
use middle:: cstore:: { self , CrateStore , InlinedItem } ;
20
20
use middle:: { infer, subst, traits} ;
21
21
use middle:: def:: Def ;
22
- use middle:: subst:: Subst ;
23
22
use middle:: def_id:: DefId ;
24
23
use middle:: pat_util:: def_to_path;
25
24
use middle:: ty:: { self , Ty , TyCtxt } ;
@@ -89,16 +88,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::TyCtxt,
89
88
}
90
89
91
90
/// * `def_id` is the id of the constant.
92
- /// * `maybe_ref_id` is the id of the expr referencing the constant.
93
- /// * `param_substs` is the monomorphization substitution for the expression.
91
+ /// * `substs` is the monomorphized substitutions for the expression.
94
92
///
95
- /// `maybe_ref_id` and `param_substs` are optional and are used for
96
- /// finding substitutions in associated constants. This generally
97
- /// happens in late/trans const evaluation.
93
+ /// `substs` is optional and is used for associated constants.
94
+ /// This generally happens in late/trans const evaluation.
98
95
pub fn lookup_const_by_id < ' a , ' tcx : ' a > ( tcx : & ' a TyCtxt < ' tcx > ,
99
96
def_id : DefId ,
100
- maybe_ref_id : Option < ast:: NodeId > ,
101
- param_substs : Option < & ' tcx subst:: Substs < ' tcx > > )
97
+ substs : Option < subst:: Substs < ' tcx > > )
102
98
-> Option < ( & ' tcx Expr , Option < ty:: Ty < ' tcx > > ) > {
103
99
if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
104
100
match tcx. map . find ( node_id) {
@@ -111,28 +107,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
111
107
} ,
112
108
Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
113
109
hir:: ConstTraitItem ( _, _) => {
114
- match maybe_ref_id {
115
- // If we have a trait item, and we know the expression
116
- // that's the source of the obligation to resolve it,
110
+ if let Some ( substs) = substs {
111
+ // If we have a trait item and the substitutions for it,
117
112
// `resolve_trait_associated_const` will select an impl
118
113
// or the default.
119
- Some ( ref_id) => {
120
- let trait_id = tcx. trait_of_item ( def_id)
121
- . unwrap ( ) ;
122
- let mut substs = tcx. node_id_item_substs ( ref_id)
123
- . substs ;
124
- if let Some ( param_substs) = param_substs {
125
- substs = substs. subst ( tcx, param_substs) ;
126
- }
127
- resolve_trait_associated_const ( tcx, ti, trait_id, substs)
128
- }
114
+ let trait_id = tcx. trait_of_item ( def_id) . unwrap ( ) ;
115
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs)
116
+ } else {
129
117
// Technically, without knowing anything about the
130
118
// expression that generates the obligation, we could
131
119
// still return the default if there is one. However,
132
120
// it's safer to return `None` than to return some value
133
121
// that may differ from what you would get from
134
122
// correctly selecting an impl.
135
- None => None
123
+ None
136
124
}
137
125
}
138
126
_ => None
@@ -153,7 +141,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
153
141
}
154
142
None => { }
155
143
}
156
- let mut used_ref_id = false ;
144
+ let mut used_substs = false ;
157
145
let expr_ty = match tcx. sess . cstore . maybe_get_item_ast ( tcx, def_id) {
158
146
cstore:: FoundAst :: Found ( & InlinedItem :: Item ( ref item) ) => match item. node {
159
147
hir:: ItemConst ( ref ty, ref const_expr) => {
@@ -163,21 +151,15 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
163
151
} ,
164
152
cstore:: FoundAst :: Found ( & InlinedItem :: TraitItem ( trait_id, ref ti) ) => match ti. node {
165
153
hir:: ConstTraitItem ( _, _) => {
166
- used_ref_id = true ;
167
- match maybe_ref_id {
154
+ used_substs = true ;
155
+ if let Some ( substs ) = substs {
168
156
// As mentioned in the comments above for in-crate
169
157
// constants, we only try to find the expression for
170
158
// a trait-associated const if the caller gives us
171
- // the expression that refers to it.
172
- Some ( ref_id) => {
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
- }
178
- resolve_trait_associated_const ( tcx, ti, trait_id, substs)
179
- }
180
- None => None
159
+ // the substitutions for the reference to it.
160
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs)
161
+ } else {
162
+ None
181
163
}
182
164
}
183
165
_ => None
@@ -190,10 +172,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
190
172
} ,
191
173
_ => None
192
174
} ;
193
- // If we used the reference expression , particularly to choose an impl
175
+ // If we used the substitutions , particularly to choose an impl
194
176
// of a trait-associated const, don't cache that, because the next
195
177
// lookup with the same def_id may yield a different result.
196
- if !used_ref_id {
178
+ if !used_substs {
197
179
tcx. extern_const_statics
198
180
. borrow_mut ( )
199
181
. insert ( def_id, expr_ty. map ( |( e, t) | ( e. id , t) ) ) ;
@@ -389,7 +371,8 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
389
371
PatKind :: Path ( path. clone ( ) ) ,
390
372
Some ( Def :: Const ( def_id) ) |
391
373
Some ( Def :: AssociatedConst ( def_id) ) => {
392
- let ( expr, _ty) = lookup_const_by_id ( tcx, def_id, Some ( expr. id ) , None ) . unwrap ( ) ;
374
+ let substs = Some ( tcx. node_id_item_substs ( expr. id ) . substs ) ;
375
+ let ( expr, _ty) = lookup_const_by_id ( tcx, def_id, substs) . unwrap ( ) ;
393
376
return const_expr_to_pat ( tcx, expr, span) ;
394
377
} ,
395
378
_ => unreachable ! ( ) ,
@@ -788,12 +771,12 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
788
771
match opt_def {
789
772
Def :: Const ( def_id) |
790
773
Def :: AssociatedConst ( def_id) => {
791
- let maybe_ref_id = if let ExprTypeChecked = ty_hint {
792
- Some ( e. id )
774
+ let substs = if let ExprTypeChecked = ty_hint {
775
+ Some ( tcx . node_id_item_substs ( e. id ) . substs )
793
776
} else {
794
777
None
795
778
} ;
796
- if let Some ( ( e, ty) ) = lookup_const_by_id ( tcx, def_id, maybe_ref_id , None ) {
779
+ if let Some ( ( e, ty) ) = lookup_const_by_id ( tcx, def_id, substs ) {
797
780
let item_hint = match ty {
798
781
Some ( ty) => ty_hint. checked_or ( ty) ,
799
782
None => ty_hint,
@@ -1077,7 +1060,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
1077
1060
traits:: VtableImpl ( ref impl_data) => {
1078
1061
match tcx. associated_consts ( impl_data. impl_def_id )
1079
1062
. iter ( ) . find ( |ic| ic. name == ti. name ) {
1080
- Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None , None ) ,
1063
+ Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None ) ,
1081
1064
None => match ti. node {
1082
1065
hir:: ConstTraitItem ( ref ty, Some ( ref expr) ) => {
1083
1066
Some ( ( & * expr, ast_ty_to_prim_ty ( tcx, ty) ) )
0 commit comments