Skip to content

Commit cfb424a

Browse files
authored
Rollup merge of #103281 - thomcc:long-overdue, r=jyn514
Adjust `transmute{,_copy}` to be clearer about which of `T` and `U` is input vs output This is essentially a documentation-only change (although it does touch code in an irrelevant way).
2 parents be4816f + afd0817 commit cfb424a

File tree

4 files changed

+31
-24
lines changed

4 files changed

+31
-24
lines changed

library/core/src/intrinsics.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,14 @@ extern "rust-intrinsic" {
994994
/// `transmute` is semantically equivalent to a bitwise move of one type
995995
/// into another. It copies the bits from the source value into the
996996
/// destination value, then forgets the original. Note that source and destination
997-
/// are passed by-value, which means if `T` or `U` contain padding, that padding
997+
/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
998998
/// is *not* guaranteed to be preserved by `transmute`.
999999
///
10001000
/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
10011001
/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
10021002
/// will generate code *assuming that you, the programmer, ensure that there will never be
10031003
/// undefined behavior*. It is therefore your responsibility to guarantee that every value
1004-
/// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition
1004+
/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
10051005
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
10061006
/// unsafe**. `transmute` should be the absolute last resort.
10071007
///
@@ -1012,7 +1012,7 @@ extern "rust-intrinsic" {
10121012
///
10131013
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
10141014
/// themselves* is not a concern. As with any other function, the compiler already ensures
1015-
/// both `T` and `U` are properly aligned. However, when transmuting values that *point
1015+
/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
10161016
/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
10171017
/// alignment of the pointed-to values.
10181018
///
@@ -1248,7 +1248,7 @@ extern "rust-intrinsic" {
12481248
#[rustc_allowed_through_unstable_modules]
12491249
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
12501250
#[rustc_diagnostic_item = "transmute"]
1251-
pub fn transmute<T, U>(e: T) -> U;
1251+
pub fn transmute<Src, Dst>(src: Src) -> Dst;
12521252

12531253
/// Returns `true` if the actual type given as `T` requires drop
12541254
/// glue; returns `false` if the actual type provided for `T`

library/core/src/mem/mod.rs

+19-16
Original file line numberDiff line numberDiff line change
@@ -1008,18 +1008,18 @@ pub fn copy<T: Copy>(x: &T) -> T {
10081008
*x
10091009
}
10101010

1011-
/// Interprets `src` as having type `&U`, and then reads `src` without moving
1011+
/// Interprets `src` as having type `&Dst`, and then reads `src` without moving
10121012
/// the contained value.
10131013
///
1014-
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<U>`][size_of]
1015-
/// bytes by transmuting `&T` to `&U` and then reading the `&U` (except that this is done in a way
1016-
/// that is correct even when `&U` has stricter alignment requirements than `&T`). It will also
1017-
/// unsafely create a copy of the contained value instead of moving out of `src`.
1014+
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<Dst>`][size_of]
1015+
/// bytes by transmuting `&Src` to `&Dst` and then reading the `&Dst` (except that this is done
1016+
/// in a way that is correct even when `&Dst` has stricter alignment requirements than `&Src`).
1017+
/// It will also unsafely create a copy of the contained value instead of moving out of `src`.
10181018
///
1019-
/// It is not a compile-time error if `T` and `U` have different sizes, but it
1020-
/// is highly encouraged to only invoke this function where `T` and `U` have the
1021-
/// same size. This function triggers [undefined behavior][ub] if `U` is larger than
1022-
/// `T`.
1019+
/// It is not a compile-time error if `Src` and `Dst` have different sizes, but it
1020+
/// is highly encouraged to only invoke this function where `Src` and `Dst` have the
1021+
/// same size. This function triggers [undefined behavior][ub] if `Dst` is larger than
1022+
/// `Src`.
10231023
///
10241024
/// [ub]: ../../reference/behavior-considered-undefined.html
10251025
///
@@ -1052,19 +1052,22 @@ pub fn copy<T: Copy>(x: &T) -> T {
10521052
#[must_use]
10531053
#[stable(feature = "rust1", since = "1.0.0")]
10541054
#[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")]
1055-
pub const unsafe fn transmute_copy<T, U>(src: &T) -> U {
1056-
assert!(size_of::<T>() >= size_of::<U>(), "cannot transmute_copy if U is larger than T");
1055+
pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst {
1056+
assert!(
1057+
size_of::<Src>() >= size_of::<Dst>(),
1058+
"cannot transmute_copy if Dst is larger than Src"
1059+
);
10571060

1058-
// If U has a higher alignment requirement, src might not be suitably aligned.
1059-
if align_of::<U>() > align_of::<T>() {
1061+
// If Dst has a higher alignment requirement, src might not be suitably aligned.
1062+
if align_of::<Dst>() > align_of::<Src>() {
10601063
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
10611064
// The caller must guarantee that the actual transmutation is safe.
1062-
unsafe { ptr::read_unaligned(src as *const T as *const U) }
1065+
unsafe { ptr::read_unaligned(src as *const Src as *const Dst) }
10631066
} else {
10641067
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
1065-
// We just checked that `src as *const U` was properly aligned.
1068+
// We just checked that `src as *const Dst` was properly aligned.
10661069
// The caller must guarantee that the actual transmutation is safe.
1067-
unsafe { ptr::read(src as *const T as *const U) }
1070+
unsafe { ptr::read(src as *const Src as *const Dst) }
10681071
}
10691072
}
10701073

library/core/tests/mem.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ fn test_transmute_copy_grow_panics() {
130130
payload
131131
.downcast::<&'static str>()
132132
.and_then(|s| {
133-
if *s == "cannot transmute_copy if U is larger than T" { Ok(s) } else { Err(s) }
133+
if *s == "cannot transmute_copy if Dst is larger than Src" {
134+
Ok(s)
135+
} else {
136+
Err(s)
137+
}
134138
})
135139
.unwrap_or_else(|p| panic::resume_unwind(p));
136140
}

src/test/ui/issues/issue-6458-3.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-6458-3.rs:4:5
33
|
44
LL | mem::transmute(0);
5-
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `transmute`
5+
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute`
66
|
77
help: consider specifying the generic arguments
88
|
9-
LL | mem::transmute::<i32, U>(0);
10-
| ++++++++++
9+
LL | mem::transmute::<i32, Dst>(0);
10+
| ++++++++++++
1111

1212
error: aborting due to previous error
1313

0 commit comments

Comments
 (0)