-
Notifications
You must be signed in to change notification settings - Fork 58
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
"_" patterns and validity invariants #261
Comments
@Nadrieril points out that
|
The corresponding case for partial initialization can currently not be probed since rustc no longer permits writing to individual fields of a not-yet-initialized struct: fn main() {
let x: (i32, bool);
x.0 = 5; // this already errors here...
let (y, _) = x; // ... so we cannot test if this would be accepted
} If this code was accepted, that would be further evidence for |
Like this? fn main() {
let x = (0, String::new());
drop(x.1);
let (x, _) = x;
// let (x, y) = x; // doesn't compile
} |
|
It was |
The MIR for |
This is IMHO even more confusing because |
Well, it drops fn mark() {}
fn test1(x: Vec<i32>) {
let _ = x; // nothing happens here
mark();
}
fn test2(x: Vec<i32>) {
let _ = vec![1]; // this is dropped here
mark();
} |
In |
Well, but the One could just as well argue that |
Currently, it does not. But it does in this very similar test using |
Yeah, it doesn't, but by analogy with The current situation seems mostly consistent (except for rust-lang/rust#79735), but it's strange because behavior heavily depends on whether the expression on the right evaluate to a temporary or an existing place. |
I guess it's for consistency with the fact that |
@scottmcm also points out that there seems to be a difference between the statements |
@RalfJung I think you mean |
Ah, yes... I am switching too often between languages that index tuples starting at 0 vs 1. ;) |
@pnkfelix points out that adding a type annotations make a difference for the operational behavior of |
As I understand things, Rust issue 10488 set the current semantics of |
Also Cc rust-lang/miri#2360, we probably want to consider some of the code around |
With rust-lang/rust#104844 and rust-lang/rust#103208 having landed, the issue is mostly resolved now: There's a bug where this is not quite true for the Do we have official docs anywhere on the semantics of |
The following code is not even unsafe, so it certainly cannot be UB:
This indicates that the pointer does not really get dereferenced, so the pointed-to data is never interpreted at type
bool
and thus must not be valid. I am not sure I like this;*ptr
(as a value expression!) to me seems like it should conceptually perform the load even if the result is later discarded.Something similar happens here:
This compiles effectively to
let x = (*ptr).0
, so again whatever data is in the second field does not matter. (Note that*ptr
here occurs only as a place expression, not as a value expression, so it makes sense that in(*ptr).0
we do not require the second field to be valid.)I think this behavior of "_" can be explained by saying that it suppresses the place-to-value coercion, and it is smart enough to even do this in cases like
(x, _)
where the coercion is partially suppressed. But I am not sure I like this semantics, it seems rather counter-intuitive to me. It also makes patterns much harder to explain. And it leads to strange special cases such as rust-lang/rust#79735 (I cannot tell if this is some compiler author also being confused by "_", or if the intention is that!
is special in that even creating the place is already UB, or something else).The text was updated successfully, but these errors were encountered: