@@ -637,6 +637,7 @@ pub fn provide(providers: &mut Providers) {
637
637
* providers = Providers {
638
638
typeck_item_bodies,
639
639
typeck_tables_of,
640
+ has_typeck_tables,
640
641
closure_type,
641
642
closure_kind,
642
643
adt_destructor,
@@ -664,55 +665,49 @@ fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
664
665
tcx. calculate_dtor ( def_id, & mut dropck:: check_drop_impl)
665
666
}
666
667
667
- fn typeck_tables_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
668
- def_id : DefId )
669
- -> & ' tcx ty:: TypeckTables < ' tcx > {
670
- // Closures' tables come from their outermost function,
671
- // as they are part of the same "inference environment".
672
- let outer_def_id = tcx. closure_base_def_id ( def_id) ;
673
- if outer_def_id != def_id {
674
- return tcx. typeck_tables_of ( outer_def_id) ;
675
- }
676
-
677
- let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
678
- let span = tcx. hir . span ( id) ;
679
- let unsupported = || {
680
- span_bug ! ( span, "can't type-check body of {:?}" , def_id) ;
681
- } ;
682
-
683
- // Figure out what primary body this item has.
684
- let mut fn_decl = None ;
685
- let body_id = match tcx. hir . get ( id) {
668
+ /// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
669
+ /// with information about it's body-id and fn-decl (if any). Otherwise,
670
+ /// returns `None`.
671
+ ///
672
+ /// If this function returns "some", then `typeck_tables(def_id)` will
673
+ /// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
674
+ /// may not succeed. In some cases where this function returns `None`
675
+ /// (notably closures), `typeck_tables(def_id)` would wind up
676
+ /// redirecting to the owning function.
677
+ fn primary_body_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
678
+ id : ast:: NodeId )
679
+ -> Option < ( hir:: BodyId , Option < & ' tcx hir:: FnDecl > ) >
680
+ {
681
+ match tcx. hir . get ( id) {
686
682
hir:: map:: NodeItem ( item) => {
687
683
match item. node {
688
684
hir:: ItemConst ( _, body) |
689
- hir:: ItemStatic ( _, _, body) => body ,
690
- hir :: ItemFn ( ref decl , .. , body) => {
691
- fn_decl = Some ( decl ) ;
692
- body
693
- }
694
- _ => unsupported ( )
685
+ hir:: ItemStatic ( _, _, body) =>
686
+ Some ( ( body, None ) ) ,
687
+ hir :: ItemFn ( ref decl , .. , body ) =>
688
+ Some ( ( body, Some ( decl ) ) ) ,
689
+ _ =>
690
+ None ,
695
691
}
696
692
}
697
693
hir:: map:: NodeTraitItem ( item) => {
698
694
match item. node {
699
- hir:: TraitItemKind :: Const ( _, Some ( body) ) => body,
700
- hir:: TraitItemKind :: Method ( ref sig,
701
- hir:: TraitMethod :: Provided ( body) ) => {
702
- fn_decl = Some ( & sig. decl ) ;
703
- body
704
- }
705
- _ => unsupported ( )
695
+ hir:: TraitItemKind :: Const ( _, Some ( body) ) =>
696
+ Some ( ( body, None ) ) ,
697
+ hir:: TraitItemKind :: Method ( ref sig, hir:: TraitMethod :: Provided ( body) ) =>
698
+ Some ( ( body, Some ( & sig. decl ) ) ) ,
699
+ _ =>
700
+ None ,
706
701
}
707
702
}
708
703
hir:: map:: NodeImplItem ( item) => {
709
704
match item. node {
710
- hir:: ImplItemKind :: Const ( _, body) => body ,
711
- hir :: ImplItemKind :: Method ( ref sig , body ) => {
712
- fn_decl = Some ( & sig . decl ) ;
713
- body
714
- }
715
- _ => unsupported ( )
705
+ hir:: ImplItemKind :: Const ( _, body) =>
706
+ Some ( ( body , None ) ) ,
707
+ hir :: ImplItemKind :: Method ( ref sig , body ) =>
708
+ Some ( ( body, Some ( & sig . decl ) ) ) ,
709
+ _ =>
710
+ None ,
716
711
}
717
712
}
718
713
hir:: map:: NodeExpr ( expr) => {
@@ -723,15 +718,47 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
723
718
// Assume that everything other than closures
724
719
// is a constant "initializer" expression.
725
720
match expr. node {
726
- hir:: ExprClosure ( ..) => {
727
- // We should've bailed out above for closures.
728
- span_bug ! ( expr. span, "unexpected closure" )
729
- }
730
- _ => hir:: BodyId { node_id : expr. id }
721
+ hir:: ExprClosure ( ..) =>
722
+ None ,
723
+ _ =>
724
+ Some ( ( hir:: BodyId { node_id : expr. id } , None ) ) ,
731
725
}
732
726
}
733
- _ => unsupported ( )
734
- } ;
727
+ _ => None ,
728
+ }
729
+ }
730
+
731
+ fn has_typeck_tables < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
732
+ def_id : DefId )
733
+ -> bool {
734
+ // Closures' tables come from their outermost function,
735
+ // as they are part of the same "inference environment".
736
+ let outer_def_id = tcx. closure_base_def_id ( def_id) ;
737
+ if outer_def_id != def_id {
738
+ return tcx. has_typeck_tables ( outer_def_id) ;
739
+ }
740
+
741
+ let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
742
+ primary_body_of ( tcx, id) . is_some ( )
743
+ }
744
+
745
+ fn typeck_tables_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
746
+ def_id : DefId )
747
+ -> & ' tcx ty:: TypeckTables < ' tcx > {
748
+ // Closures' tables come from their outermost function,
749
+ // as they are part of the same "inference environment".
750
+ let outer_def_id = tcx. closure_base_def_id ( def_id) ;
751
+ if outer_def_id != def_id {
752
+ return tcx. typeck_tables_of ( outer_def_id) ;
753
+ }
754
+
755
+ let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
756
+ let span = tcx. hir . span ( id) ;
757
+
758
+ // Figure out what primary body this item has.
759
+ let ( body_id, fn_decl) = primary_body_of ( tcx, id) . unwrap_or_else ( || {
760
+ span_bug ! ( span, "can't type-check body of {:?}" , def_id) ;
761
+ } ) ;
735
762
let body = tcx. hir . body ( body_id) ;
736
763
737
764
Inherited :: build ( tcx, id) . enter ( |inh| {
0 commit comments