mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 03:44:24 +00:00
process trait/impl items directly from the visitor callback
The current setup processes impl/trait items while visiting the impl/trait. This means we basically have this setup: <Lots> -> TypeckItemBody(Impl) -> Tables(ImplItem{0,1,2,3}) But this was largely an artifact of the older code. By moving the processing of items into method dedicated for their use, we produce this setup: <Little> -> TypeckItemBody(ImplItem0) -> Tables(ImplItem0) ... <Little> -> TypeckItemBody(ImplItem3) -> Tables(ImplItem3)
This commit is contained in:
parent
fc57e40ce7
commit
c6b65ac748
@ -570,16 +570,43 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
25
src/test/compile-fail/dep_graph_crosscontaminate_tables.rs
Normal file
25
src/test/compile-fail/dep_graph_crosscontaminate_tables.rs
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user