I am encountering a puzzling error when creating a tuple-like struct somewhere in my Rust project.
The error
I boiled my issue down to the following snippet:
mod parent {
pub struct X(u32);
mod child {
use crate::X;
fn f() {
let x = X(42);
}
}
}
use parent::X;
In my head, this snippet should compile just fine. X
is public, and its field is visibile within parent
, so all its children (including child::f
) should be able to access it. However, when I go and compile that snippet, I get
error[E0423]: expected function, tuple struct or tuple variant, found struct `X`
--> src/main.rs:8:21
|
8 | let x = X(42);
| ^
For more information about this error, try `rustc --explain E0423`.
error: could not compile `playground` (bin "playground" test) due to 1 previous error
Weirdly enough, the error message mentions the compiler expecting a "tuple variant", but finding X
instead. But, X
is a tuple variant!
Path dependence
The problem disappears when I use
super::X
instead of crate::X
.
mod parent {
pub struct X(u32);
mod child {
use super::X;
fn f() {
let x = X(42);
}
}
}
use parent::X;
This is even more puzzling to me. Why would the correctness of my snippet depend on the specific path I use to use
X
? In my mind, X
is X
, wherever I import it from.
With non-tuple structs
The problem also disappears when I give X
named fields:
mod parent {
pub struct X {
x: u32,
}
mod child {
use crate::X;
fn f() {
let x = X { x: 42 };
}
}
}
use parent::X;
Note that I am using use crate::X
in this snippet, just as in the first one! Why would this error appear only with tuple-like structs? I am very confused. I am usually not one to ever doubt the correctness of the Rust compiler, but I have to admit that today my faith is being tested.
Any insight on what I might be missing?
pub struct X(pub u32);
the first example compiles, so the issue is the visibility of the field. Though I don't understand the inconsistency between fields of a tuple struct and named fields. – Lemcke