about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-05-27 21:19:11 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-05-31 19:59:57 -0400
commit4038b5b3eee3d26e07ec49b2e697975307488d67 (patch)
tree216df0247f29f7278fb125a456e7d0d1e0d76af1
parent63bb0847bdf58d7d021735184a9dfd48138ad8ab (diff)
downloadrust-4038b5b3eee3d26e07ec49b2e697975307488d67.tar.gz
rust-4038b5b3eee3d26e07ec49b2e697975307488d67.zip
add def-ids from nominal types into TraitSelect
This way we distinguish, in particular, `Foo: Sized`
and `Bar: Sized`, which fixes #33850.
-rw-r--r--src/librustc/ty/mod.rs23
-rw-r--r--src/test/incremental/struct_add_field.rs2
-rw-r--r--src/test/incremental/struct_change_field_name.rs2
-rw-r--r--src/test/incremental/struct_change_field_type.rs2
-rw-r--r--src/test/incremental/struct_change_field_type_cross_crate/b.rs2
-rw-r--r--src/test/incremental/struct_remove_field.rs2
6 files changed, 27 insertions, 6 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 423d57cfb32..2a22e13d31e 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<DefId> {
-        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<u32>: SomeTrait`,
+        // `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): 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 425aa3e07a0..cc8ef8aedd7 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 cf6f89bd8a4..fe29ad66b5f 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 2bd61a3f559..1a50d515db6 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 19f146ce176..7a4900d1d9a 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 db49a751627..ae6399463b8 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' };
 }