-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
PhantomData behavior is very surprising w.r.t. lack of Drop implications #102810
Comments
It isn't clear to me though. I don't see how this could ever be exploited to create unsoundness. It seems the error happens because |
see also https://docs.rs/selfref/0.2.4/selfref/ (maybe we should just ship it with the it's also worth noting that it fails to compile if you use a |
It's supposed to make a struct act as if it contains a |
why can't/shouldn't it act itself as a |
use core::cell::Cell;
//use core::marker::PhantomData as PDOrBox;
//use std::boxed::Box as PDOrBox;
type PDOrBox<T> = [T; 0];
struct Foo<'a> {
selfref: Cell<Option<&'a Foo<'a>>>,
}
impl<'a> Drop for Foo<'a> {
fn drop(&mut self) {
}
}
fn make_selfref<'a>(x: &'a PDOrBox<Foo<'a>>) {}
fn make_pdorbox<'a>() -> PDOrBox<Foo<'a>> {
unimplemented!()
}
fn main() {
let x = make_pdorbox();
make_selfref(&x);
} I haven't stared at this long enough to decide whether this is correct behavior for |
it's unsound as in "if you use this with unsafe, you'll have soundness issues". and the worst part is that there's no appropriate alternative that can be used on stable. there's no "PhantomDrop", no "PhantomBox", no anything like that. |
AFAIK,
So for this, I really don't get the point. For the first sentence, are you saying that using |
a acts like a |
Anything related to such Although this itself is slightly off-topic to the original question. Regarding it, I think you are trying to give |
The difference is solely because |
@Lee-Janggun the actual receiver is @nbdd0121 it needs the |
Anyway, I think it'll be a breaking change to modify the behaviour of Probably we should take this an opportunity to stablise |
Note that
Does this issue also affect |
Ok I think I get your point, in that it should act like a struct with a T field, but be zero sized at runtime. Still, is that intended for PhantomData? IDK about the full technical details but my understanding has been that PhantomData is just a marker to properly able certain compiler analysis for certain types, and nothing really more. |
Maybe we should change the doc to say that |
and so anyone who inadvertently (without testing it) relied on the as-documented behaviour is left with no usable alternative and an unsound crate. why not... fix |
I’m going to nominate this for a look by T-lang. The lang team seems like the best candidate to make a call here as to how the |
This changed between 1.35 and 1.36 in the 2015 edition: https://rust.godbolt.org/z/bYvjeGvM5 |
We discussed this in the 2022-10-11 meeting. Some things we realized:
If you modify the example that that the So the more correct summary seems to be:
As @nbdd0121 pointed out, this is more like saying "it is similar to That is the current behavior, at least. The question @SoniEx2 is whether you can adjust your code to be sound given those semantics? |
I think the answer to the last question is yes. For the selfref crate, the pub struct UBCheck<T: ?Sized>(PhantomData<T>);
unsafe impl<#[may_dangle] T: ?Sized> Drop for UBCheck<T> {
fn drop(&mut self) {}
} can be implemented as struct NopDrop;
impl Drop for NopDrop {
fn drop(&mut self) {}
}
pub struct UBCheck<T: ?Sized>(NopDrop, PhantomData<T>); |
@nikomatsakis honestly we'd lean towards considering this behaviour of NLL incorrect in the presence of PhantomData, because PhantomData is just that special. but if we were to do that, then how do you even fix that? we mean, what would dropck for Copy types even translate to in NLL terms? maybe it creates more problems than it solves... @nbdd0121 huh. interesting. edit: tho the meeting notes seem a bit inconsistent. specifically:
wouldn't that be "the drop glue"? which is really weird/surprising btw! if this is gonna be a thing then there should definitely be tests for it. (that is to say: can we rely on it?) |
also it's not similar to ManuallyDrop: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ef62faa188b41fd69f1561da05605db6 |
even more surprising is the behaviour of 0-length arrays: with drop sibling: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a2e6095c7257fe95f3d07abc33b6417f note that 0-length arrays are not copy: #94313 |
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
PhantomData: fix documentation wrt interaction with dropck As far as I could find out, the `PhantomData`-dropck interaction *only* affects code using `may_dangle`. The documentation in the standard library has not been updated for 8 years and thus stems from a time when Rust still used "parametric dropck", before [RFC 1238](https://rust-lang.github.io/rfcs/1238-nonparametric-dropck.html). Back then what the docs said was correct, but with `may_dangle` dropck it stopped being entirely accurate and these days, with NLL, it is actively misleading. Fixes rust-lang/rust#102810 Fixes rust-lang/rust#70841 Cc `@nikomatsakis` I hope what I am saying here is right.^^
I tried this code:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=14dee41511095d6e940069db08cdc23f
I expected to see this happen: since a
PhantomData
claims to act like aT
including for the purposes of borrowck/dropck then this should absolutely compile-fail. just as it does if you use aBox
, orT
directly!Instead, this happened: it doesn't!
this is clearly unsound.
Meta
rustc --version --verbose
:Backtrace
The text was updated successfully, but these errors were encountered: