diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 4c619f895de56..7460ef82ebee4 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -3323,6 +3323,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> { // giving `trans_item` access to this item, so also record a read. tcx.dep_graph.with_task(DepNode::TransCrateItem(def_id), || { tcx.dep_graph.read(DepNode::Hir(def_id)); + + // We are going to be accessing various tables + // generated by TypeckItemBody; we also assume + // that the body passes type check. These tables + // are not individually tracked, so just register + // a read here. + tcx.dep_graph.read(DepNode::TypeckItemBody(def_id)); + trans_item(self.ccx, i); }); diff --git a/src/test/compile-fail/dep-graph-assoc-type-trans.rs b/src/test/compile-fail/dep-graph-assoc-type-trans.rs new file mode 100644 index 0000000000000..d1ecff5984ac5 --- /dev/null +++ b/src/test/compile-fail/dep-graph-assoc-type-trans.rs @@ -0,0 +1,48 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that when a trait impl changes, fns whose body uses that trait +// must also be recompiled. + +// compile-flags: -Z incr-comp + +#![feature(rustc_attrs)] +#![allow(warnings)] + +fn main() { } + +pub trait Foo: Sized { + type T; + fn method(self) { } +} + +mod x { + use Foo; + + #[rustc_if_this_changed] + impl Foo for char { type T = char; } + + impl Foo for u32 { type T = u32; } +} + +mod y { + use Foo; + + #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK + pub fn use_char_assoc() { + // Careful here: in the representation, ::T gets + // normalized away, so at a certain point we had no edge to + // trans. (But now trans just depends on typeck.) + let x: ::T = 'a'; + } + + pub fn take_foo(t: T) { } +} diff --git a/src/test/compile-fail/dep-graph-trait-impl.rs b/src/test/compile-fail/dep-graph-trait-impl.rs index 4a7becca15d08..b38fdad9809ed 100644 --- a/src/test/compile-fail/dep-graph-trait-impl.rs +++ b/src/test/compile-fail/dep-graph-trait-impl.rs @@ -40,9 +40,8 @@ mod y { char::method('a'); } - // FIXME(#30741) tcx fulfillment cache not tracked #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK - #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path + #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_char() { take_foo::('a'); } @@ -53,9 +52,8 @@ mod y { u32::method(22); } - // FIXME(#30741) tcx fulfillment cache not tracked #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK - #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path + #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_u32() { take_foo::(22); }