-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
coherence check affected by module ordering #52050
Comments
This may be related to incremental compilation. @Rantanen follows up with this: Got curious about this so did some research into it. This feels like a rustc bug. The offending file is After mod boolobject;
mod bytearray;
mod dict; // <- dict
pub mod exc;
mod floatob;
mod iterator;
mod list;
mod module; // <- module
mod sequence;
mod set;
mod slice;
mod stringdata;
mod stringutils;
mod tuple;
mod typeobject; // <- typeobject This causes the compilation error. I could fix this in two ways.
Also once the crate has been built successfully, it will continue to compile just fine even with Also looking at the error message. That is an impl for |
Nominating as it seems pretty important to know what is happening here. |
I can reproduce the problem following the given steps. |
Nominating as P-high, I will investigate. |
visited for triage. @nikomatsakis is currently out, but scheduled to be back early next week, so we'll just wait until next team mtg to see what progress is made. |
egads I forgot about this. I will try to make progress on it this week. |
Huh. Very curious. So I am able to reproduce the error (and lack of error) -- though with modern compilers something has changed with respect to proc macros so I had to remove a few Applying But reordering modules in the way described by @Rantanen did not (for me) make the error go away. I was however testing with Also, just applying cargo fmt to |
The error does seem to arise if I format just these two files: |
Actually, just |
specifically this diff: diff --git a/src/lib.rs b/src/lib.rs
index 729185a..640234b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -197,23 +197,23 @@ macro_rules! wrap_function (
};
);
-pub mod python;
-mod err;
+#[doc(hidden)]
+pub mod argparse;
+pub mod buffer;
+#[doc(hidden)]
+pub mod callback;
mod conversion;
+mod err;
+pub mod freelist;
mod instance;
+mod noargs;
mod object;
-mod objects;
mod objectprotocol;
-mod noargs;
+mod objects;
+pub mod prelude;
+pub mod python;
mod pythonrun;
-#[doc(hidden)]
-pub mod callback;
pub mod typeob;
-#[doc(hidden)]
-pub mod argparse;
-pub mod buffer;
-pub mod freelist;
-pub mod prelude;
// re-export for simplicity
#[doc(hidden)] |
Yep, that's fixed on master since the v0.3.0 tag |
This diff seems to suffice to make the error start to happen: Unstaged changes (1)
modified src/lib.rs
@@ -201,10 +201,10 @@ pub mod python;
mod err;
mod conversion;
mod instance;
+mod noargs;
mod object;
mod objects;
mod objectprotocol;
-mod noargs;
mod pythonrun;
#[doc(hidden)]
pub mod callback; |
OK so it turns out that this is a specialization bug. Here is a minimized test case which (incorrectly) compiles: #![feature(specialization)]
use std::iter::Iterator;
trait IntoPyDictPointer { }
struct Foo { }
impl Iterator for Foo {
type Item = ();
fn next(&mut self) -> Option<()> {
None
}
}
impl IntoPyDictPointer for Foo { }
impl<I> IntoPyDictPointer for I
where
I: Iterator,
{
}
impl IntoPyDictPointer for ()
{
}
fn main() { } The problem is that -- when building the spec graph -- we somehow wind up such that the impl for |
OK, I think I see the bug. It's kind of subtle and has to do with the interaction with simplified type improvements. |
So the strategy of inserting into the tree is that it walks over a list of rust/src/librustc/traits/specialize/specialization_graph.rs Lines 113 to 116 in 5ba2184
If it finds that the current def-id D is broader than some child C, it replaces C with D: rust/src/librustc/traits/specialize/specialization_graph.rs Lines 167 to 173 in 5ba2184
and adds C as a child of D: rust/src/librustc/traits/specialize/specialization_graph.rs Lines 262 to 268 in 5ba2184
The flaw here is that there is not a single list of children. Rather, there are many lists, sorted by the simplified types. If the simplied type of C is not equal to the simplified type of D, then D ends up in the wrong list. Probably the fix is to not try to be so clever. We can just remove C from the appropriate list and then (separately) add D -- or, if we want to micro-optimize, we could replace C with D if they share a simplified type, but that feels a bit overkill to me. |
Fix pending in #52546 -- needs review. |
do not overwrite child def-id in place but rather remove/insert When inserting a node N into the tree of impls, we sometimes find than an existing node C should be replaced with N. We used to overwrite C in place with the new def-id N -- but since the lists of def-ids are separated by simplified type, that could lead to N being inserted in the wrong place. This meant we might miss conflicts. We are now not trying to be so smart -- we remove C and then add N later. Fixes #52050 r? @aturon -- do you still remember this code at all? :)
As reported by @konstin on the rustfmt repo in rust-lang/rustfmt#2824, apparently the pyo3 project coherence check is affected by module ordering:
rusfmt breaks pyo3 in the sense that it doesn't build after running
cargo fmt
.Reproducing:
The last command results in a conflicting implementations error, even though only the formatting should have changed:
Versions:
cargo fmt --version
: rustfmt 0.8.2-nightly (87edd75 2018-06-22)rustc --version
: rustc 1.28.0-nightly (e3bf634 2018-06-28)The text was updated successfully, but these errors were encountered: