@@ -98,13 +98,13 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
98
98
def_id : DefId ,
99
99
maybe_ref_id : Option < ast:: NodeId > ,
100
100
param_substs : Option < & ' tcx subst:: Substs < ' tcx > > )
101
- -> Option < & ' tcx Expr > {
101
+ -> Option < ( & ' tcx Expr , Option < ty :: Ty < ' tcx > > ) > {
102
102
if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
103
103
match tcx. map . find ( node_id) {
104
104
None => None ,
105
105
Some ( ast_map:: NodeItem ( it) ) => match it. node {
106
- hir:: ItemConst ( _ , ref const_expr) => {
107
- Some ( & const_expr)
106
+ hir:: ItemConst ( ref ty , ref const_expr) => {
107
+ Some ( ( & const_expr, ast_ty_to_prim_ty ( tcx , ty ) ) )
108
108
}
109
109
_ => None
110
110
} ,
@@ -123,8 +123,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
123
123
if let Some ( param_substs) = param_substs {
124
124
substs = substs. subst ( tcx, param_substs) ;
125
125
}
126
- resolve_trait_associated_const ( tcx, ti, trait_id,
127
- substs)
126
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs)
128
127
}
129
128
// Technically, without knowing anything about the
130
129
// expression that generates the obligation, we could
@@ -138,25 +137,27 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
138
137
_ => None
139
138
} ,
140
139
Some ( ast_map:: NodeImplItem ( ii) ) => match ii. node {
141
- hir:: ImplItemKind :: Const ( _ , ref expr) => {
142
- Some ( & expr)
140
+ hir:: ImplItemKind :: Const ( ref ty , ref expr) => {
141
+ Some ( ( & expr, ast_ty_to_prim_ty ( tcx , ty ) ) )
143
142
}
144
143
_ => None
145
144
} ,
146
145
Some ( _) => None
147
146
}
148
147
} else {
149
148
match tcx. extern_const_statics . borrow ( ) . get ( & def_id) {
150
- Some ( & ast :: DUMMY_NODE_ID ) => return None ,
151
- Some ( & expr_id) => {
152
- return Some ( tcx. map . expect_expr ( expr_id) ) ;
149
+ Some ( & None ) => return None ,
150
+ Some ( & Some ( ( expr_id, ty ) ) ) => {
151
+ return Some ( ( tcx. map . expect_expr ( expr_id) , ty ) ) ;
153
152
}
154
153
None => { }
155
154
}
156
155
let mut used_ref_id = false ;
157
- let expr_id = match tcx. sess . cstore . maybe_get_item_ast ( tcx, def_id) {
156
+ let expr_ty = match tcx. sess . cstore . maybe_get_item_ast ( tcx, def_id) {
158
157
cstore:: FoundAst :: Found ( & InlinedItem :: Item ( ref item) ) => match item. node {
159
- hir:: ItemConst ( _, ref const_expr) => Some ( const_expr. id ) ,
158
+ hir:: ItemConst ( ref ty, ref const_expr) => {
159
+ Some ( ( & * * const_expr, ast_ty_to_prim_ty ( tcx, ty) ) )
160
+ } ,
160
161
_ => None
161
162
} ,
162
163
cstore:: FoundAst :: Found ( & InlinedItem :: TraitItem ( trait_id, ref ti) ) => match ti. node {
@@ -173,16 +174,17 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
173
174
if let Some ( param_substs) = param_substs {
174
175
substs = substs. subst ( tcx, param_substs) ;
175
176
}
176
- resolve_trait_associated_const ( tcx, ti, trait_id,
177
- substs) . map ( |e| e. id )
177
+ resolve_trait_associated_const ( tcx, ti, trait_id, substs)
178
178
}
179
179
None => None
180
180
}
181
181
}
182
182
_ => None
183
183
} ,
184
184
cstore:: FoundAst :: Found ( & InlinedItem :: ImplItem ( _, ref ii) ) => match ii. node {
185
- hir:: ImplItemKind :: Const ( _, ref expr) => Some ( expr. id ) ,
185
+ hir:: ImplItemKind :: Const ( ref ty, ref expr) => {
186
+ Some ( ( & * * expr, ast_ty_to_prim_ty ( tcx, ty) ) )
187
+ } ,
186
188
_ => None
187
189
} ,
188
190
_ => None
@@ -192,10 +194,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
192
194
// lookup with the same def_id may yield a different result.
193
195
if !used_ref_id {
194
196
tcx. extern_const_statics
195
- . borrow_mut ( ) . insert ( def_id ,
196
- expr_id . unwrap_or ( ast :: DUMMY_NODE_ID ) ) ;
197
+ . borrow_mut ( )
198
+ . insert ( def_id , expr_ty . map ( | ( e , t ) | ( e . id , t ) ) ) ;
197
199
}
198
- expr_id . map ( |id| tcx . map . expect_expr ( id ) )
200
+ expr_ty
199
201
}
200
202
}
201
203
@@ -386,7 +388,7 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
386
388
PatKind :: Path ( path. clone ( ) ) ,
387
389
Some ( Def :: Const ( def_id) ) |
388
390
Some ( Def :: AssociatedConst ( def_id) ) => {
389
- let expr = lookup_const_by_id ( tcx, def_id, Some ( expr. id ) , None ) . unwrap ( ) ;
391
+ let ( expr, _ty ) = lookup_const_by_id ( tcx, def_id, Some ( expr. id ) , None ) . unwrap ( ) ;
390
392
return const_expr_to_pat ( tcx, expr, span) ;
391
393
} ,
392
394
_ => unreachable ! ( ) ,
@@ -778,90 +780,49 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
778
780
if def. depth != 0 {
779
781
signal ! ( e, UnresolvedPath ) ;
780
782
}
781
- Some ( def. full_def ( ) )
783
+ def. full_def ( )
782
784
} else {
783
- None
785
+ signal ! ( e , NonConstPath ) ;
784
786
} ;
785
- let ( const_expr, const_ty) = match opt_def {
786
- Some ( Def :: Const ( def_id) ) => {
787
- if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
788
- match tcx. map . find ( node_id) {
789
- Some ( ast_map:: NodeItem ( it) ) => match it. node {
790
- hir:: ItemConst ( ref ty, ref expr) => {
791
- ( Some ( & * * expr) , Some ( & * * ty) )
792
- }
793
- _ => ( None , None )
794
- } ,
795
- _ => ( None , None )
796
- }
787
+ match opt_def {
788
+ Def :: Const ( def_id) |
789
+ Def :: AssociatedConst ( def_id) => {
790
+ let maybe_ref_id = if let ExprTypeChecked = ty_hint {
791
+ Some ( e. id )
792
+ } else {
793
+ None
794
+ } ;
795
+ if let Some ( ( e, ty) ) = lookup_const_by_id ( tcx, def_id, maybe_ref_id, None ) {
796
+ let item_hint = match ty {
797
+ Some ( ty) => ty_hint. checked_or ( ty) ,
798
+ None => ty_hint,
799
+ } ;
800
+ try!( eval_const_expr_partial ( tcx, e, item_hint, None ) )
797
801
} else {
798
- ( lookup_const_by_id ( tcx , def_id , Some ( e . id ) , None ) , None )
802
+ signal ! ( e , NonConstPath ) ;
799
803
}
800
- }
801
- Some ( Def :: AssociatedConst ( def_id) ) => {
802
- if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
803
- match impl_or_trait_container ( tcx, def_id) {
804
- ty:: TraitContainer ( trait_id) => match tcx. map . find ( node_id) {
805
- Some ( ast_map:: NodeTraitItem ( ti) ) => match ti. node {
806
- hir:: ConstTraitItem ( ref ty, _) => {
807
- if let ExprTypeChecked = ty_hint {
808
- let substs = tcx. node_id_item_substs ( e. id ) . substs ;
809
- ( resolve_trait_associated_const ( tcx,
810
- ti,
811
- trait_id,
812
- substs) ,
813
- Some ( & * * ty) )
814
- } else {
815
- ( None , None )
816
- }
817
- }
818
- _ => ( None , None )
819
- } ,
820
- _ => ( None , None )
821
- } ,
822
- ty:: ImplContainer ( _) => match tcx. map . find ( node_id) {
823
- Some ( ast_map:: NodeImplItem ( ii) ) => match ii. node {
824
- hir:: ImplItemKind :: Const ( ref ty, ref expr) => {
825
- ( Some ( & * * expr) , Some ( & * * ty) )
826
- }
827
- _ => ( None , None )
828
- } ,
829
- _ => ( None , None )
830
- } ,
831
- }
804
+ } ,
805
+ Def :: Variant ( enum_def, variant_def) => {
806
+ if let Some ( const_expr) = lookup_variant_by_id ( tcx, enum_def, variant_def) {
807
+ try!( eval_const_expr_partial ( tcx, const_expr, ty_hint, None ) )
832
808
} else {
833
- ( lookup_const_by_id ( tcx , def_id , Some ( e . id ) , None ) , None )
809
+ signal ! ( e , NonConstPath ) ;
834
810
}
835
811
}
836
- Some ( Def :: Variant ( enum_def , variant_def ) ) => {
837
- ( lookup_variant_by_id ( tcx , enum_def , variant_def ) , None )
812
+ Def :: Struct ( .. ) => {
813
+ ConstVal :: Struct ( e . id )
838
814
}
839
- Some ( Def :: Struct ( ..) ) => {
840
- return Ok ( ConstVal :: Struct ( e. id ) )
841
- }
842
- Some ( Def :: Local ( _, id) ) => {
815
+ Def :: Local ( _, id) => {
843
816
debug ! ( "Def::Local({:?}): {:?}" , id, fn_args) ;
844
817
if let Some ( val) = fn_args. and_then ( |args| args. get ( & id) ) {
845
- return Ok ( val. clone ( ) ) ;
818
+ val. clone ( )
846
819
} else {
847
- ( None , None )
820
+ signal ! ( e , NonConstPath ) ;
848
821
}
849
822
} ,
850
- Some ( Def :: Method ( id) ) | Some ( Def :: Fn ( id) ) => return Ok ( Function ( id) ) ,
851
- _ => ( None , None )
852
- } ;
853
- let const_expr = match const_expr {
854
- Some ( actual_e) => actual_e,
855
- None => signal ! ( e, NonConstPath )
856
- } ;
857
- let item_hint = match const_ty {
858
- Some ( ty) => match ast_ty_to_prim_ty ( tcx, ty) {
859
- Some ( ty) => ty_hint. checked_or ( ty) ,
860
- None => ty_hint. erase_hint ( ) ,
861
- } ,
862
- None => ty_hint. erase_hint ( ) ,
863
- } ;
864
- try!( eval_const_expr_partial ( tcx, const_expr, item_hint, fn_args) )
823
+ Def :: Method ( id) | Def :: Fn ( id) => Function ( id) ,
824
+ _ => signal ! ( e, NonConstPath ) ,
825
+ }
865
826
}
866
827
hir:: ExprCall ( ref callee, ref args) => {
867
828
let sub_ty_hint = ty_hint. erase_hint ( ) ;
@@ -1097,28 +1058,11 @@ fn infer<'tcx>(
1097
1058
}
1098
1059
}
1099
1060
1100
- fn impl_or_trait_container ( tcx : & TyCtxt , def_id : DefId ) -> ty:: ImplOrTraitItemContainer {
1101
- // This is intended to be equivalent to tcx.impl_or_trait_item(def_id).container()
1102
- // for local def_id, but it can be called before tcx.impl_or_trait_items is complete.
1103
- if let Some ( node_id) = tcx. map . as_local_node_id ( def_id) {
1104
- if let Some ( ast_map:: NodeItem ( item) ) = tcx. map . find ( tcx. map . get_parent_node ( node_id) ) {
1105
- let container_id = tcx. map . local_def_id ( item. id ) ;
1106
- match item. node {
1107
- hir:: ItemImpl ( ..) => return ty:: ImplContainer ( container_id) ,
1108
- hir:: ItemTrait ( ..) => return ty:: TraitContainer ( container_id) ,
1109
- _ => ( )
1110
- }
1111
- }
1112
- panic ! ( "No impl or trait container for {:?}" , def_id) ;
1113
- }
1114
- panic ! ( "{:?} is not local" , def_id) ;
1115
- }
1116
-
1117
1061
fn resolve_trait_associated_const < ' a , ' tcx : ' a > ( tcx : & ' a TyCtxt < ' tcx > ,
1118
1062
ti : & ' tcx hir:: TraitItem ,
1119
1063
trait_id : DefId ,
1120
1064
rcvr_substs : subst:: Substs < ' tcx > )
1121
- -> Option < & ' tcx Expr >
1065
+ -> Option < ( & ' tcx Expr , Option < ty :: Ty < ' tcx > > ) >
1122
1066
{
1123
1067
let trait_ref = ty:: Binder (
1124
1068
rcvr_substs. erase_regions ( ) . to_trait_ref ( tcx, trait_id)
@@ -1151,7 +1095,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
1151
1095
. iter ( ) . find ( |ic| ic. name == ti. name ) {
1152
1096
Some ( ic) => lookup_const_by_id ( tcx, ic. def_id , None , None ) ,
1153
1097
None => match ti. node {
1154
- hir:: ConstTraitItem ( _, Some ( ref expr) ) => Some ( & * expr) ,
1098
+ hir:: ConstTraitItem ( ref ty, Some ( ref expr) ) => {
1099
+ Some ( ( & * expr, ast_ty_to_prim_ty ( tcx, ty) ) )
1100
+ } ,
1155
1101
_ => None ,
1156
1102
} ,
1157
1103
}
0 commit comments