@@ -441,10 +441,11 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
441
441
}
442
442
443
443
struct CheckItemTypesVisitor < ' a , ' tcx : ' a > { ccx : & ' a CrateCtxt < ' a , ' tcx > }
444
+ struct CheckItemBodiesVisitor < ' a , ' tcx : ' a > { ccx : & ' a CrateCtxt < ' a , ' tcx > }
444
445
445
446
impl < ' a , ' tcx > Visitor < ' tcx > for CheckItemTypesVisitor < ' a , ' tcx > {
446
447
fn visit_item ( & mut self , i : & ' tcx ast:: Item ) {
447
- check_item ( self . ccx , i) ;
448
+ check_item_type ( self . ccx , i) ;
448
449
visit:: walk_item ( self , i) ;
449
450
}
450
451
@@ -460,6 +461,13 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
460
461
}
461
462
}
462
463
464
+ impl < ' a , ' tcx > Visitor < ' tcx > for CheckItemBodiesVisitor < ' a , ' tcx > {
465
+ fn visit_item ( & mut self , i : & ' tcx ast:: Item ) {
466
+ check_item_body ( self . ccx , i) ;
467
+ visit:: walk_item ( self , i) ;
468
+ }
469
+ }
470
+
463
471
pub fn check_item_types ( ccx : & CrateCtxt ) {
464
472
let krate = ccx. tcx . map . krate ( ) ;
465
473
let mut visit = wf:: CheckTypeWellFormedVisitor :: new ( ccx) ;
@@ -474,6 +482,11 @@ pub fn check_item_types(ccx: &CrateCtxt) {
474
482
475
483
ccx. tcx . sess . abort_if_errors ( ) ;
476
484
485
+ let mut visit = CheckItemBodiesVisitor { ccx : ccx } ;
486
+ visit:: walk_crate ( & mut visit, krate) ;
487
+
488
+ ccx. tcx . sess . abort_if_errors ( ) ;
489
+
477
490
for drop_method_did in ccx. tcx . destructors . borrow ( ) . iter ( ) {
478
491
if drop_method_did. krate == ast:: LOCAL_CRATE {
479
492
let drop_impl_did = ccx. tcx . map . get_parent_did ( drop_method_did. node ) ;
@@ -713,13 +726,13 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
713
726
}
714
727
}
715
728
716
- pub fn check_item < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > , it : & ' tcx ast:: Item ) {
717
- debug ! ( "check_item (it.id={}, it.ident={})" ,
729
+ pub fn check_item_type < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > , it : & ' tcx ast:: Item ) {
730
+ debug ! ( "check_item_type (it.id={}, it.ident={})" ,
718
731
it. id,
719
732
ty:: item_path_str( ccx. tcx, local_def( it. id) ) ) ;
720
733
let _indenter = indenter ( ) ;
721
-
722
734
match it. node {
735
+ // Consts can play a role in type-checking, so they are included here.
723
736
ast:: ItemStatic ( _, _, ref e) |
724
737
ast:: ItemConst ( _, ref e) => check_const ( ccx, it. span , & * * e, it. id ) ,
725
738
ast:: ItemEnum ( ref enum_definition, _) => {
@@ -728,16 +741,9 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
728
741
& enum_definition. variants ,
729
742
it. id ) ;
730
743
}
731
- ast:: ItemFn ( ref decl, _, _, _, ref body) => {
732
- let fn_pty = ty:: lookup_item_type ( ccx. tcx , ast_util:: local_def ( it. id ) ) ;
733
- let param_env = ParameterEnvironment :: for_item ( ccx. tcx , it. id ) ;
734
- check_bare_fn ( ccx, & * * decl, & * * body, it. id , it. span , fn_pty. ty , param_env) ;
735
- }
744
+ ast:: ItemFn ( _, _, _, _, _) => { } // entirely within check_item_body
736
745
ast:: ItemImpl ( _, _, _, _, _, ref impl_items) => {
737
- debug ! ( "ItemImpl {} with id {}" , token:: get_ident( it. ident) , it. id) ;
738
-
739
- let impl_pty = ty:: lookup_item_type ( ccx. tcx , ast_util:: local_def ( it. id ) ) ;
740
-
746
+ debug ! ( "ItemImpl {} with id {}" , token:: get_ident( it. ident) , it. id) ;
741
747
match ty:: impl_trait_ref ( ccx. tcx , local_def ( it. id ) ) {
742
748
Some ( impl_trait_ref) => {
743
749
check_impl_items_against_trait ( ccx,
@@ -747,39 +753,9 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
747
753
}
748
754
None => { }
749
755
}
750
-
751
- for impl_item in impl_items {
752
- match impl_item. node {
753
- ast:: MethodImplItem ( ref sig, ref body) => {
754
- check_method_body ( ccx, & impl_pty. generics , sig, body,
755
- impl_item. id , impl_item. span ) ;
756
- }
757
- ast:: TypeImplItem ( _) |
758
- ast:: MacImplItem ( _) => {
759
- // Nothing to do here.
760
- }
761
- }
762
- }
763
-
764
756
}
765
- ast:: ItemTrait ( _, ref generics, _, ref trait_items ) => {
757
+ ast:: ItemTrait ( _, ref generics, _, _ ) => {
766
758
check_trait_on_unimplemented ( ccx, generics, it) ;
767
- let trait_def = ty:: lookup_trait_def ( ccx. tcx , local_def ( it. id ) ) ;
768
- for trait_item in trait_items {
769
- match trait_item. node {
770
- ast:: MethodTraitItem ( _, None ) => {
771
- // Nothing to do, since required methods don't have
772
- // bodies to check.
773
- }
774
- ast:: MethodTraitItem ( ref sig, Some ( ref body) ) => {
775
- check_method_body ( ccx, & trait_def. generics , sig, body,
776
- trait_item. id , trait_item. span ) ;
777
- }
778
- ast:: TypeTraitItem ( ..) => {
779
- // Nothing to do.
780
- }
781
- }
782
- }
783
759
}
784
760
ast:: ItemStruct ( ..) => {
785
761
check_struct ( ccx, it. id , it. span ) ;
@@ -814,6 +790,57 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
814
790
}
815
791
}
816
792
793
+ pub fn check_item_body < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > , it : & ' tcx ast:: Item ) {
794
+ debug ! ( "check_item_body(it.id={}, it.ident={})" ,
795
+ it. id,
796
+ ty:: item_path_str( ccx. tcx, local_def( it. id) ) ) ;
797
+ let _indenter = indenter ( ) ;
798
+ match it. node {
799
+ ast:: ItemFn ( ref decl, _, _, _, ref body) => {
800
+ let fn_pty = ty:: lookup_item_type ( ccx. tcx , ast_util:: local_def ( it. id ) ) ;
801
+ let param_env = ParameterEnvironment :: for_item ( ccx. tcx , it. id ) ;
802
+ check_bare_fn ( ccx, & * * decl, & * * body, it. id , it. span , fn_pty. ty , param_env) ;
803
+ }
804
+ ast:: ItemImpl ( _, _, _, _, _, ref impl_items) => {
805
+ debug ! ( "ItemImpl {} with id {}" , token:: get_ident( it. ident) , it. id) ;
806
+
807
+ let impl_pty = ty:: lookup_item_type ( ccx. tcx , ast_util:: local_def ( it. id ) ) ;
808
+
809
+ for impl_item in impl_items {
810
+ match impl_item. node {
811
+ ast:: MethodImplItem ( ref sig, ref body) => {
812
+ check_method_body ( ccx, & impl_pty. generics , sig, body,
813
+ impl_item. id , impl_item. span ) ;
814
+ }
815
+ ast:: TypeImplItem ( _) |
816
+ ast:: MacImplItem ( _) => {
817
+ // Nothing to do here.
818
+ }
819
+ }
820
+ }
821
+ }
822
+ ast:: ItemTrait ( _, _, _, ref trait_items) => {
823
+ let trait_def = ty:: lookup_trait_def ( ccx. tcx , local_def ( it. id ) ) ;
824
+ for trait_item in trait_items {
825
+ match trait_item. node {
826
+ ast:: MethodTraitItem ( _, None ) => {
827
+ // Nothing to do, since required methods don't have
828
+ // bodies to check.
829
+ }
830
+ ast:: MethodTraitItem ( ref sig, Some ( ref body) ) => {
831
+ check_method_body ( ccx, & trait_def. generics , sig, body,
832
+ trait_item. id , trait_item. span ) ;
833
+ }
834
+ ast:: TypeTraitItem ( ..) => {
835
+ // Nothing to do.
836
+ }
837
+ }
838
+ }
839
+ }
840
+ _ => { /* nothing to do */ }
841
+ }
842
+ }
843
+
817
844
fn check_trait_on_unimplemented < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > ,
818
845
generics : & ast:: Generics ,
819
846
item : & ast:: Item ) {
0 commit comments