@@ -441,10 +441,11 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
441441}
442442
443443struct CheckItemTypesVisitor < ' a , ' tcx : ' a > { ccx : & ' a CrateCtxt < ' a , ' tcx > }
444+ struct CheckItemBodiesVisitor < ' a , ' tcx : ' a > { ccx : & ' a CrateCtxt < ' a , ' tcx > }
444445
445446impl < ' a , ' tcx > Visitor < ' tcx > for CheckItemTypesVisitor < ' a , ' tcx > {
446447 fn visit_item ( & mut self , i : & ' tcx ast:: Item ) {
447- check_item ( self . ccx , i) ;
448+ check_item_type ( self . ccx , i) ;
448449 visit:: walk_item ( self , i) ;
449450 }
450451
@@ -460,6 +461,13 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
460461 }
461462}
462463
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+
463471pub fn check_item_types ( ccx : & CrateCtxt ) {
464472 let krate = ccx. tcx . map . krate ( ) ;
465473 let mut visit = wf:: CheckTypeWellFormedVisitor :: new ( ccx) ;
@@ -474,6 +482,11 @@ pub fn check_item_types(ccx: &CrateCtxt) {
474482
475483 ccx. tcx . sess . abort_if_errors ( ) ;
476484
485+ let mut visit = CheckItemBodiesVisitor { ccx : ccx } ;
486+ visit:: walk_crate ( & mut visit, krate) ;
487+
488+ ccx. tcx . sess . abort_if_errors ( ) ;
489+
477490 for drop_method_did in ccx. tcx . destructors . borrow ( ) . iter ( ) {
478491 if drop_method_did. krate == ast:: LOCAL_CRATE {
479492 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) {
713726 }
714727}
715728
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={})" ,
718731 it. id,
719732 ty:: item_path_str( ccx. tcx, local_def( it. id) ) ) ;
720733 let _indenter = indenter ( ) ;
721-
722734 match it. node {
735+ // Consts can play a role in type-checking, so they are included here.
723736 ast:: ItemStatic ( _, _, ref e) |
724737 ast:: ItemConst ( _, ref e) => check_const ( ccx, it. span , & * * e, it. id ) ,
725738 ast:: ItemEnum ( ref enum_definition, _) => {
@@ -728,16 +741,9 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
728741 & enum_definition. variants ,
729742 it. id ) ;
730743 }
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
736745 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) ;
741747 match ty:: impl_trait_ref ( ccx. tcx , local_def ( it. id ) ) {
742748 Some ( impl_trait_ref) => {
743749 check_impl_items_against_trait ( ccx,
@@ -747,39 +753,9 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
747753 }
748754 None => { }
749755 }
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-
764756 }
765- ast:: ItemTrait ( _, ref generics, _, ref trait_items ) => {
757+ ast:: ItemTrait ( _, ref generics, _, _ ) => {
766758 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- }
783759 }
784760 ast:: ItemStruct ( ..) => {
785761 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) {
814790 }
815791}
816792
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+
817844fn check_trait_on_unimplemented < ' a , ' tcx > ( ccx : & CrateCtxt < ' a , ' tcx > ,
818845 generics : & ast:: Generics ,
819846 item : & ast:: Item ) {
0 commit comments