-
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
Regression transmuting RwLockReadGuard<T: ?Sized>
.
#101081
Comments
This is not a regression, but not for the reason you say. Quoting the reference: https://doc.rust-lang.org/stable/reference/type-layout.html
|
Nominating to get sign-off on acceptable breakage from libs-api; I expect this is an obvious case. I think this is another case where we should consider making the compiler lint on transmutes of types that aren't marked with a repr, and maybe even hard error for std types. |
While I would be personally in favor of this, such a change will cause breakage in the ecosystem, which I suspect others would conclude is too much. |
Yeah, I think it's a difficult tradeoff. We obviously can't catch everything (e.g., pointer casting is probably too far), but I think a warning is going to do 90% of the work for us and is hopefully relatively obviously OK. |
One thought I had was having transmute Kinda do the job of randomize_layout, in the sense that it goes "Okay, you're transmuting from You need to not forbid things like I do think we've had enough issues where people are transmuting stdlib types (see: trying to change the layout of the std::net socket type) to justify being harsh here. Should I open a separate issue to try and hash out the details of how we do it there? |
this is like forbidding transmuting |
(This is mostly unrelated to this "regression", and is more just questions about
I agree that relying on a specific layout is not allowed, so I guess it makes sense that it's okay for (Although, the type layout page you linked does not mention lifetimes at all, so maybe I was misinterpreting something from somewhere else.) Although also, the docs for // from https://doc.rust-lang.org/std/mem/fn.transmute.html
// implicitly repr(Rust)
struct R<'a>(&'a i32);
unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
std::mem::transmute::<R<'b>, R<'static>>(r)
}
// ... Even if "transmuting away lifetimes" is not allowed, presumably it should always be valid to transmute a type to itself regardless of layout? (or using use std::sync::RwLockReadGuard;
fn test1<'a, T: ?Sized>(guard: RwLockReadGuard<'a, T>) -> RwLockReadGuard<'a, T> {
// unsafe { std::mem::transmute(guard) } // this has the same problem as in my original comment
// But. would transmute_copy (and forget) be unsound here?
unsafe {
let guard = std::mem::ManuallyDrop(guard);
std::mem::transmute_copy(&from)
}
}
This would probably be good, but I think it would [need to be/benefit from being] somewhat recursive (since e.g. |
Whether transmuting between types that only differ in lifetimes should work or not is not really a library issue, but more a question for the language team. One could argue it's a bug if |
So to clarify, the question for the language team:
|
Per discussion in rust-lang/lang meeting today, we are re-nominating this for @rust-lang/types consideration. |
searched nightlies: from nightly-2022-06-01 to nightly-2022-09-06 bisected with cargo-bisect-rustc v0.6.3Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc --start 2022-06-01 |
…piler-errors Allow transmutes between the same types after erasing lifetimes r? `@compiler-errors` on the impl fixes rust-lang#101081 See discussion in the issue and at https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/.23101081.3A.20Regression.20transmuting.20.60RwLockReadGuard.3CT.3A.20.3FSized.3E.E2.80.A6 I think this may need lang team signoff as its implications may go beyond the jurisdiction of T-types I'll write up a proper summary later
…piler-errors Allow transmutes between the same types after erasing lifetimes r? ``@compiler-errors`` on the impl fixes rust-lang#101081 See discussion in the issue and at https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/.23101081.3A.20Regression.20transmuting.20.60RwLockReadGuard.3CT.3A.20.3FSized.3E.E2.80.A6 I think this may need lang team signoff as its implications may go beyond the jurisdiction of T-types I'll write up a proper summary later
…piler-errors Allow transmutes between the same types after erasing lifetimes r? ```@compiler-errors``` on the impl fixes rust-lang#101081 See discussion in the issue and at https://rust-lang.zulipchat.com/#narrow/stream/326866-t-types.2Fnominated/topic/.23101081.3A.20Regression.20transmuting.20.60RwLockReadGuard.3CT.3A.20.3FSized.3E.E2.80.A6 I think this may need lang team signoff as its implications may go beyond the jurisdiction of T-types I'll write up a proper summary later
RwLockReadGuard<T>
is now not transmutable whenT
is (dependent on) a generic parameter and?Sized
, when it was previously(I don't necessarily think this is a significant enough problem to be worth "fixing", but I guess it is technically a regression).
Code
I tried this code:
I expected to see this happen: compilation success
Instead, this happened: compilation error
Version it worked on
It most recently worked on: Rust 1.63.0
Version with regression
rustc --version --verbose
:Backtrace
(no backtrace, compiler didn't crash)
Why
This commit changed the definition of
RwLockReadGuard
fromto
(The following is (AFAICT) why this change caused this regression; It is not itself a regression, and it applies to all (recent) versions of rustc (i.e. since at least 1.41.0))
AFICT, rustc currently only supports transmuting a subset of
Sized
types that it conservatively can guarantee are the same size. For generic struct types with?Sized
parameters, i think rustc can only guarantee the size if the whole struct's size does not depend on the parameters, or if the struct's only non-zst field is a (transitive transparent wrapper of a) pointer type depending on a generic parameter (rustc_middle::ty::layout::SizeSkeleton
only hasKnown(usize)
andPointer { .. }
variants, so can only express completely known and only-a-pointer sizes), e.g.(See also: #101084 )
Moved to #101084
(See also: #101084) Unrelated note: I think this size-calculation ignoring all ZSTs (not just 1-ZSTs) when there is a pointer field can cause `transmute` to (incorrectly?) allow transmuting between differently-sized types, e.g. this compiles and runs normally, but ICEs under miri:
@rustbot modify labels: +regression-from-stable-to-beta -regression-untriaged
The text was updated successfully, but these errors were encountered: