diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 423d57cfb328..2a22e13d31ec 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -946,7 +946,28 @@ impl<'tcx> TraitPredicate<'tcx> { /// Creates the dep-node for selecting/evaluating this trait reference. fn dep_node(&self) -> DepNode { - DepNode::TraitSelect(self.def_id(), vec![]) + // Ideally, the dep-node would just have all the input types + // in it. But they are limited to including def-ids. So as an + // approximation we include the def-ids for all nominal types + // found somewhere. This means that we will e.g. conflate the + // dep-nodes for `u32: SomeTrait` and `u64: SomeTrait`, but we + // would have distinct dep-nodes for `Vec: SomeTrait`, + // `Rc: SomeTrait`, and `(Vec, Rc): SomeTrait`. + // Note that it's always sound to conflate dep-nodes, it jus + // leads to more recompilation. + let def_ids: Vec<_> = + self.input_types() + .iter() + .flat_map(|t| t.walk()) + .filter_map(|t| match t.sty { + ty::TyStruct(adt_def, _) | + ty::TyEnum(adt_def, _) => + Some(adt_def.did), + _ => + None + }) + .collect(); + DepNode::TraitSelect(self.def_id(), def_ids) } pub fn input_types(&self) -> &[Ty<'tcx>] { diff --git a/src/test/incremental/struct_add_field.rs b/src/test/incremental/struct_add_field.rs index 425aa3e07a0e..cc8ef8aedd77 100644 --- a/src/test/incremental/struct_add_field.rs +++ b/src/test/incremental/struct_add_field.rs @@ -40,7 +40,7 @@ pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] // FIXME(#33850) should be clean +#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_name.rs b/src/test/incremental/struct_change_field_name.rs index cf6f89bd8a4c..fe29ad66b5fd 100644 --- a/src/test/incremental/struct_change_field_name.rs +++ b/src/test/incremental/struct_change_field_name.rs @@ -47,7 +47,7 @@ pub fn use_EmbedX(embed: EmbedX) -> u32 { //[cfail2]~^ ERROR attempted access of field `x` } -#[rustc_dirty(label="TypeckItemBody", cfg="cfail2")] // FIXME(#33850) should be clean +#[rustc_clean(label="TypeckItemBody", cfg="cfail2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type.rs b/src/test/incremental/struct_change_field_type.rs index 2bd61a3f559d..1a50d515db6d 100644 --- a/src/test/incremental/struct_change_field_type.rs +++ b/src/test/incremental/struct_change_field_type.rs @@ -45,7 +45,7 @@ pub fn use_EmbedX(x: EmbedX) -> u32 { x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] // FIXME(#33850) should be clean +#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type_cross_crate/b.rs b/src/test/incremental/struct_change_field_type_cross_crate/b.rs index 19f146ce176d..7a4900d1d9a9 100644 --- a/src/test/incremental/struct_change_field_type_cross_crate/b.rs +++ b/src/test/incremental/struct_change_field_type_cross_crate/b.rs @@ -28,7 +28,7 @@ pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] // FIXME(#33850) should be clean +#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_remove_field.rs b/src/test/incremental/struct_remove_field.rs index db49a7516275..ae6399463b81 100644 --- a/src/test/incremental/struct_remove_field.rs +++ b/src/test/incremental/struct_remove_field.rs @@ -44,7 +44,7 @@ pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] // FIXME(#33850) should be clean +#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; }