Skip to content

Commit 9baff8a

Browse files
committed
---
yaml --- r: 235803 b: refs/heads/stable c: 74768e9 h: refs/heads/master i: 235801: c117a17 235799: 557f71c v: v3
1 parent 1cf9f04 commit 9baff8a

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 3080df36e27ed74399f9fe22e4796e209abd2b69
32+
refs/heads/stable: 74768e9a6ccac85f813e4125c76f9cb52a2ac618
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc/diagnostics.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,70 @@ This error indicates that the compiler found multiple functions with the
821821
point into a Rust program.
822822
"##,
823823

824+
// FIXME link this to the relevant turpl chapters for instilling fear of the
825+
// transmute gods in the user
826+
E0139: r##"
827+
There are various restrictions on transmuting between types in Rust; for example
828+
types being transmuted must have the same size. To apply all these restrictions,
829+
the compiler must know the exact types that may be transmuted. When type
830+
parameters are involved, this cannot always be done.
831+
832+
So, for example, the following is not allowed:
833+
834+
```
835+
struct Foo<T>(Vec<T>)
836+
837+
fn foo<T>(x: Vec<T>) {
838+
// we are transmuting between Vec<T> and Foo<T> here
839+
let y: Foo<T> = unsafe { transmute(x) };
840+
// do something with y
841+
}
842+
```
843+
844+
In this specific case there's a good chance that the transmute is harmless (but
845+
this is not guaranteed by Rust). However, when alignment and enum optimizations
846+
come into the picture, it's quite likely that the sizes may or may not match
847+
with different type parameter substitutions. It's not possible to check this for
848+
_all_ possible types, so `transmute()` simply only accepts types without any
849+
unsubstituted type parameters.
850+
851+
If you need this, there's a good chance you're doing something wrong. Keep in
852+
mind that Rust doesn't guarantee much about the layout of different structs
853+
(even two structs with identical declarations may have different layouts). If
854+
there is a solution that avoids the transmute entirely, try it instead.
855+
856+
If it's possible, hand-monomorphize the code by writing the function for each
857+
possible type substitution. It's possible to use traits to do this cleanly,
858+
for example:
859+
860+
```
861+
trait MyTransmutableType {
862+
fn transmute(Vec<Self>) -> Foo<Self>
863+
}
864+
865+
impl MyTransmutableType for u8 {
866+
fn transmute(x: Foo<u8>) -> Vec<u8> {
867+
transmute(x)
868+
}
869+
}
870+
impl MyTransmutableType for String {
871+
fn transmute(x: Foo<String>) -> Vec<String> {
872+
transmute(x)
873+
}
874+
}
875+
// ... more impls for the types you intend to transmute
876+
877+
fn foo<T: MyTransmutableType>(x: Vec<T>) {
878+
let y: Foo<T> = <T as MyTransmutableType>::transmute(x);
879+
// do something with y
880+
}
881+
```
882+
883+
Each impl will be checked for a size match in the transmute as usual, and since
884+
there are no unbound type parameters involved, this should compile unless there
885+
is a size mismatch in one of the impls.
886+
"##,
887+
824888
E0152: r##"
825889
Lang items are already implemented in the standard library. Unless you are
826890
writing a free-standing application (e.g. a kernel), you do not need to provide
@@ -1608,7 +1672,6 @@ register_diagnostics! {
16081672
// E0006 // merged with E0005
16091673
// E0134,
16101674
// E0135,
1611-
E0139,
16121675
E0264, // unknown external lang item
16131676
E0269, // not all control paths return a value
16141677
E0270, // computation may converge in a function marked as diverging

0 commit comments

Comments
 (0)