diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e240c70aaa3a56baf77c2959f0dd7e319d1504b0..02f5d77f249ceac091fb0df79de580b3ca0937e6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -570,16 +570,43 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr) { } impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { - fn visit_item(&mut self, i: &'tcx hir::Item) { - check_item_body(self.ccx, i); + fn visit_item(&mut self, item: &'tcx hir::Item) { + match item.node { + hir::ItemFn(ref decl, .., body_id) => { + check_bare_fn(self.ccx, &decl, body_id, item.id, item.span); + } + _ => { } + } } - fn visit_trait_item(&mut self, _item: &'tcx hir::TraitItem) { - // done as part of `visit_item` above + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { + match trait_item.node { + hir::TraitItemKind::Const(_, Some(expr)) => { + check_const(self.ccx, expr, trait_item.id) + } + hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => { + check_bare_fn(self.ccx, &sig.decl, body_id, trait_item.id, trait_item.span); + } + hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | + hir::TraitItemKind::Const(_, None) | + hir::TraitItemKind::Type(..) => { + // Nothing to do. + } + } } - fn visit_impl_item(&mut self, _item: &'tcx hir::ImplItem) { - // done as part of `visit_item` above + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + match impl_item.node { + hir::ImplItemKind::Const(_, expr) => { + check_const(self.ccx, expr, impl_item.id) + } + hir::ImplItemKind::Method(ref sig, body_id) => { + check_bare_fn(self.ccx, &sig.decl, body_id, impl_item.id, impl_item.span); + } + hir::ImplItemKind::Type(_) => { + // Nothing to do here. + } + } } } @@ -897,55 +924,6 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } -pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { - debug!("check_item_body(it.id={}, it.name={})", - it.id, - ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id))); - let _indenter = indenter(); - match it.node { - hir::ItemFn(ref decl, .., body_id) => { - check_bare_fn(ccx, &decl, body_id, it.id, it.span); - } - hir::ItemImpl(.., ref impl_item_refs) => { - debug!("ItemImpl {} with id {}", it.name, it.id); - - for impl_item_ref in impl_item_refs { - let impl_item = ccx.tcx.map.impl_item(impl_item_ref.id); - match impl_item.node { - hir::ImplItemKind::Const(_, expr) => { - check_const(ccx, expr, impl_item.id) - } - hir::ImplItemKind::Method(ref sig, body_id) => { - check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span); - } - hir::ImplItemKind::Type(_) => { - // Nothing to do here. - } - } - } - } - hir::ItemTrait(.., ref trait_item_refs) => { - for trait_item_ref in trait_item_refs { - let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id); - match trait_item.node { - hir::TraitItemKind::Const(_, Some(expr)) => { - check_const(ccx, expr, trait_item.id) - } - hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => { - check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span); - } - hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | - hir::TraitItemKind::Const(_, None) | - hir::TraitItemKind::Type(..) => { - // Nothing to do. - } - } - } - } - _ => {/* nothing to do */ } - } -} - fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId, item: &hir::Item) { diff --git a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs new file mode 100644 index 0000000000000000000000000000000000000000..06fea1a8f296912f322809198a974d825d2fb7bc --- /dev/null +++ b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs @@ -0,0 +1,25 @@ +#![feature(rustc_attrs)] + +struct Foo { + x: u8 +} + +impl Foo { + // Changing the item `new`... + #[rustc_if_this_changed(HirBody)] + fn new() -> Foo { + Foo { x: 0 } + } + + // ...should not cause us to recompute the tables for `with`! + #[rustc_then_this_would_need(Tables)] //~ ERROR no path + fn with(x: u8) -> Foo { + Foo { x: x } + } +} + +fn main() { + let f = Foo::new(); + let g = Foo::with(22); + assert_eq!(f.x, g.x - 22); +}