@@ -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 } ;
@@ -78,16 +77,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a TyCtxt,
78
77
}
79
78
80
79
/// * `def_id` is the id of the constant.
81
- /// * `maybe_ref_id` is the id of the expr referencing the constant.
82
- /// * `param_substs` is the monomorphization substitution for the expression.
80
+ /// * `substs` is the monomorphized substitutions for the expression.
83
81
///
84
- /// `maybe_ref_id` and `param_substs` are optional and are used for
85
- /// finding substitutions in associated constants. This generally
86
- /// happens in late/trans const evaluation.
82
+ /// `substs` is optional and is used for associated constants.
83
+ /// This generally happens in late/trans const evaluation.
87
84
pub fn lookup_const_by_id < ' a , ' tcx : ' a > ( tcx : & ' a TyCtxt < ' tcx > ,
88
85
def_id : DefId ,
89
- maybe_ref_id : Option < ast:: NodeId > ,
90
- param_substs : Option < & ' tcx subst:: Substs < ' tcx > > )
86
+ substs : Option < subst:: Substs < ' tcx > > )
91
87
-> Option < & ' tcx Expr > {
92
88
if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
93
89
match tcx. map . find ( node_id) {
@@ -100,29 +96,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
100
96
} ,
101
97
Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
102
98
hir:: ConstTraitItem ( _, _) => {
103
- match maybe_ref_id {
104
- // If we have a trait item, and we know the expression
105
- // that's the source of the obligation to resolve it,
99
+ if let Some ( substs) = substs {
100
+ // If we have a trait item and the substitutions for it,
106
101
// `resolve_trait_associated_const` will select an impl
107
102
// or the default.
108
- Some ( ref_id) => {
109
- let trait_id = tcx. trait_of_item ( def_id)
110
- . unwrap ( ) ;
111
- let mut substs = tcx. node_id_item_substs ( ref_id)
112
- . substs ;
113
- if let Some ( param_substs) = param_substs {
114
- substs = substs. subst ( tcx, param_substs) ;
115
- }
116
- resolve_trait_associated_const ( tcx, ti, trait_id,
117
- substs)
118
- }
103
+ let trait_id = tcx. trait_of_item ( def_id) . unwrap ( ) ;
104
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs)
105
+ } else {
119
106
// Technically, without knowing anything about the
120
107
// expression that generates the obligation, we could
121
108
// still return the default if there is one. However,
122
109
// it's safer to return `None` than to return some value
123
110
// that may differ from what you would get from
124
111
// correctly selecting an impl.
125
- None => None
112
+ None
126
113
}
127
114
}
128
115
_ => None
@@ -143,30 +130,23 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
143
130
}
144
131
None => { }
145
132
}
146
- let mut used_ref_id = false ;
133
+ let mut used_substs = false ;
147
134
let expr_id = match tcx. sess . cstore . maybe_get_item_ast ( tcx, def_id) {
148
135
cstore:: FoundAst :: Found ( & InlinedItem :: Item ( ref item) ) => match item. node {
149
136
hir:: ItemConst ( _, ref const_expr) => Some ( const_expr. id ) ,
150
137
_ => None
151
138
} ,
152
139
cstore:: FoundAst :: Found ( & InlinedItem :: TraitItem ( trait_id, ref ti) ) => match ti. node {
153
140
hir:: ConstTraitItem ( _, _) => {
154
- used_ref_id = true ;
155
- match maybe_ref_id {
141
+ used_substs = true ;
142
+ if let Some ( substs ) = substs {
156
143
// As mentioned in the comments above for in-crate
157
144
// constants, we only try to find the expression for
158
145
// a trait-associated const if the caller gives us
159
- // the expression that refers to it.
160
- Some ( ref_id) => {
161
- let mut substs = tcx. node_id_item_substs ( ref_id)
162
- . substs ;
163
- if let Some ( param_substs) = param_substs {
164
- substs = substs. subst ( tcx, param_substs) ;
165
- }
166
- resolve_trait_associated_const ( tcx, ti, trait_id,
167
- substs) . map ( |e| e. id )
168
- }
169
- None => None
146
+ // the substitutions for the reference to it.
147
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs) . map ( |e| e. id )
148
+ } else {
149
+ None
170
150
}
171
151
}
172
152
_ => None
@@ -177,10 +157,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
177
157
} ,
178
158
_ => None
179
159
} ;
180
- // If we used the reference expression , particularly to choose an impl
160
+ // If we used the substitutions , particularly to choose an impl
181
161
// of a trait-associated const, don't cache that, because the next
182
162
// lookup with the same def_id may yield a different result.
183
- if !used_ref_id {
163
+ if !used_substs {
184
164
tcx. extern_const_statics
185
165
. borrow_mut ( ) . insert ( def_id,
186
166
expr_id. unwrap_or ( ast:: DUMMY_NODE_ID ) ) ;
@@ -370,7 +350,8 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
370
350
PatKind :: Path ( path. clone ( ) ) ,
371
351
Some ( Def :: Const ( def_id) ) |
372
352
Some ( Def :: AssociatedConst ( def_id) ) => {
373
- let expr = lookup_const_by_id ( tcx, def_id, Some ( expr. id ) , None ) . unwrap ( ) ;
353
+ let substs = Some ( tcx. node_id_item_substs ( expr. id ) . substs ) ;
354
+ let expr = lookup_const_by_id ( tcx, def_id, substs) . unwrap ( ) ;
374
355
return const_expr_to_pat ( tcx, expr, span) ;
375
356
} ,
376
357
_ => unreachable ! ( ) ,
@@ -1014,7 +995,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
1014
995
_ => ( None , None )
1015
996
}
1016
997
} else {
1017
- ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) , None ) , None )
998
+ let substs = Some ( tcx. node_id_item_substs ( e. id ) . substs ) ;
999
+ ( lookup_const_by_id ( tcx, def_id, substs) , None )
1018
1000
}
1019
1001
}
1020
1002
Some ( Def :: AssociatedConst ( def_id) ) => {
@@ -1049,7 +1031,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
1049
1031
} ,
1050
1032
}
1051
1033
} else {
1052
- ( lookup_const_by_id ( tcx, def_id, Some ( e. id ) , None ) , None )
1034
+ let substs = Some ( tcx. node_id_item_substs ( e. id ) . substs ) ;
1035
+ ( lookup_const_by_id ( tcx, def_id, substs) , None )
1053
1036
}
1054
1037
}
1055
1038
Some ( Def :: Variant ( enum_def, variant_def) ) => {
@@ -1274,7 +1257,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
1274
1257
traits:: VtableImpl ( ref impl_data) => {
1275
1258
match tcx. associated_consts ( impl_data. impl_def_id )
1276
1259
. iter ( ) . find ( |ic| ic. name == ti. name ) {
1277
- Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None , None ) ,
1260
+ Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None ) ,
1278
1261
None => match ti. node {
1279
1262
hir:: ConstTraitItem ( _, Some ( ref expr) ) => Some ( & * expr) ,
1280
1263
_ => None ,
0 commit comments