Skip to content
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

Rollup of 4 pull requests #42445

Closed
wants to merge 9 commits into from
4 changes: 4 additions & 0 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
if build.is_rust_llvm(target) {
cargo.env("LLVM_RUSTLLVM", "1");
}
if let Some(ref cfg_file) = build.flags.config {
let cfg_path = t!(PathBuf::from(cfg_file).canonicalize());
cargo.env("CFG_LLVM_TOML", cfg_path.into_os_string());
}
cargo.env("LLVM_CONFIG", build.llvm_config(target));
let target_config = build.config.target_config.get(target);
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ pub trait Unsize<T: ?Sized> {
/// but not `Copy`.
///
/// [`Clone`] is a supertrait of `Copy`, so everything which is `Copy` must also implement
/// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation need only return `*self`
/// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation only needs to return `*self`
/// (see the example above).
///
/// ## When can my type be `Copy`?
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ fn takes_u8(_: u8) {}

fn main() {
unsafe { takes_u8(::std::mem::transmute(0u16)); }
// error: transmute called with differently sized types
// error: transmute called with types of different sizes
}
```

Expand Down
26 changes: 10 additions & 16 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,16 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
// Special-case transmutting from `typeof(function)` and
// `Option<typeof(function)>` to present a clearer error.
let from = unpack_option_like(self.tcx.global_tcx(), from);
match (&from.sty, sk_to) {
(&ty::TyFnDef(..), SizeSkeleton::Known(size_to))
if size_to == Pointer.size(self.tcx) => {
if let (&ty::TyFnDef(..), SizeSkeleton::Known(size_to)) = (&from.sty, sk_to) {
if size_to == Pointer.size(self.tcx) {
struct_span_err!(self.tcx.sess, span, E0591,
"`{}` is zero-sized and can't be transmuted to `{}`",
from, to)
.span_note(span, "cast with `as` to a pointer instead")
"can't transmute zero-sized type")
.note(&format!("source type: {}", from))
.note(&format!("target type: {}", to))
.help("cast with `as` to a pointer instead")
.emit();
return;
}
_ => {}
}
}

Expand All @@ -111,7 +110,7 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
}
Err(LayoutError::Unknown(bad)) => {
if bad == ty {
format!("size can vary")
format!("this type's size can vary")
} else {
format!("size can vary because of {}", bad)
}
Expand All @@ -121,14 +120,9 @@ impl<'a, 'tcx> ExprVisitor<'a, 'tcx> {
};

struct_span_err!(self.tcx.sess, span, E0512,
"transmute called with differently sized types: \
{} ({}) to {} ({})",
from, skeleton_string(from, sk_from),
to, skeleton_string(to, sk_to))
.span_label(span,
format!("transmuting between {} and {}",
skeleton_string(from, sk_from),
skeleton_string(to, sk_to)))
"transmute called with types of different sizes")
.note(&format!("source type: {} ({})", from, skeleton_string(from, sk_from)))
.note(&format!("target type: {} ({})", to, skeleton_string(to, sk_to)))
.emit();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
m.push_str(&(if n == 1 {
help_name
} else {
format!("one of {}'s {} elided {}lifetimes", help_name, n,
format!("one of {}'s {} {}lifetimes", help_name, n,
if have_bound_regions { "free " } else { "" } )
})[..]);

Expand Down
5 changes: 5 additions & 0 deletions src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ fn main() {

println!("cargo:rerun-if-changed={}", llvm_config.display());

if let Some(cfg_toml) = env::var_os("CFG_LLVM_TOML") {
let cfg_path = PathBuf::from(cfg_toml);
println!("cargo:rerun-if-changed={}", cfg_path.display());
}

// Test whether we're cross-compiling LLVM. This is a pretty rare case
// currently where we're producing an LLVM for a different platform than
// what this build script is currently running on.
Expand Down
1 change: 0 additions & 1 deletion src/test/compile-fail/E0512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ fn takes_u8(_: u8) {}

fn main() {
unsafe { takes_u8(::std::mem::transmute(0u16)); } //~ ERROR E0512
//~| transmuting between 16 bits and 8 bits
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-21174.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ trait Trait<'a> {

fn foo<'a, T: Trait<'a>>(value: T::A) {
let new: T::B = unsafe { std::mem::transmute(value) };
//~^ ERROR: transmute called with differently sized types
//~^ ERROR: transmute called with types of different sizes
}

fn main() { }
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-26638.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

fn parse_type(iter: Box<Iterator<Item=&str>+'static>) -> &str { iter.next() }
//~^ ERROR missing lifetime specifier [E0106]
//~^^ HELP 2 elided lifetimes
//~^^ HELP 2 lifetimes

fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
//~^ ERROR missing lifetime specifier [E0106]
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-28625.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct ArrayPeano<T: Bar> {
}

fn foo<T>(a: &ArrayPeano<T>) -> &[T] where T: Bar {
unsafe { std::mem::transmute(a) } //~ ERROR transmute called with differently sized types
unsafe { std::mem::transmute(a) } //~ ERROR transmute called with types of different sizes
}

impl Bar for () {
Expand Down
6 changes: 3 additions & 3 deletions src/test/compile-fail/issue-30255.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ struct S<'a> {

fn f(a: &S, b: i32) -> &i32 {
//~^ ERROR missing lifetime specifier [E0106]
//~^^ HELP does not say which one of `a`'s 2 elided lifetimes it is borrowed from
//~^^ HELP does not say which one of `a`'s 2 lifetimes it is borrowed from
panic!();
}

fn g(a: &S, b: bool, c: &i32) -> &i32 {
//~^ ERROR missing lifetime specifier [E0106]
//~^^ HELP does not say whether it is borrowed from one of `a`'s 2 elided lifetimes or `c`
//~^^ HELP does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c`
panic!();
}

fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
//~^ ERROR missing lifetime specifier [E0106]
//~^^ HELP does not say whether it is borrowed from `a`, one of `c`'s 2 elided lifetimes, or `d`
//~^^ HELP does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d`
panic!();
}

2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-32377.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct Bar<U: Foo> {

fn foo<U: Foo>(x: [usize; 2]) -> Bar<U> {
unsafe { mem::transmute(x) }
//~^ ERROR transmute called with differently sized types
//~^ ERROR transmute called with types of different sizes
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct Foo<'a> {
// Lifetime annotation needed because we have two lifetimes: one as a parameter
// and one on the reference.
fn h(_x: &Foo) -> &isize { //~ ERROR missing lifetime specifier
//~^ HELP the signature does not say which one of `_x`'s 2 elided lifetimes it is borrowed from
//~^ HELP the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from
panic!()
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/packed-struct-generic-transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// the error points to the start of the file, not the line with the
// transmute

// error-pattern: transmute called with differently sized types
// error-pattern: transmute called with types of different sizes

use std::mem;

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/packed-struct-transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// the error points to the start of the file, not the line with the
// transmute

// error-pattern: transmute called with differently sized types
// error-pattern: transmute called with types of different sizes

use std::mem;

Expand Down
6 changes: 3 additions & 3 deletions src/test/compile-fail/transmute-different-sizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use std::mem::transmute;

unsafe fn f() {
let _: i8 = transmute(16i16);
//~^ ERROR transmute called with differently sized types
//~^ ERROR transmute called with types of different sizes
}

unsafe fn g<T>(x: &T) {
let _: i8 = transmute(x);
//~^ ERROR transmute called with differently sized types
//~^ ERROR transmute called with types of different sizes
}

trait Specializable { type Output; }
Expand All @@ -33,7 +33,7 @@ impl<T> Specializable for T {

unsafe fn specializable<T>(x: u16) -> <T as Specializable>::Output {
transmute(x)
//~^ ERROR transmute called with differently sized types
//~^ ERROR transmute called with types of different sizes
}

fn main() {}
8 changes: 4 additions & 4 deletions src/test/compile-fail/transmute-fat-pointers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
use std::mem::transmute;

fn a<T, U: ?Sized>(x: &[T]) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
}

fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
}

fn c<T, U>(x: &T) -> &U {
Expand All @@ -31,11 +31,11 @@ fn d<T, U>(x: &[T]) -> &[U] {
}

fn e<T: ?Sized, U>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
}

fn f<T, U: ?Sized>(x: &T) -> &U {
unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
}

fn main() { }
2 changes: 1 addition & 1 deletion src/test/compile-fail/transmute-impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<T: ?Sized> Foo<T> {

fn n(x: &T) -> &isize {
// Not OK here, because T : Sized is not in scope.
unsafe { transmute(x) } //~ ERROR transmute called with differently sized types
unsafe { transmute(x) } //~ ERROR transmute called with types of different sizes
}
}

Expand Down
36 changes: 36 additions & 0 deletions src/test/ui/transmute/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(untagged_unions)]
use std::mem::transmute;

pub trait TypeConstructor<'a> {
type T;
}

unsafe fn transmute_lifetime<'a, 'b, C>(x: <C as TypeConstructor<'a>>::T)
-> <C as TypeConstructor<'b>>::T
where for<'z> C: TypeConstructor<'z> {
transmute(x) //~ ERROR transmute called with types of different sizes
}

unsafe fn sizes() {
let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
}

unsafe fn ptrs() {
let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
}

union Foo { x: () }
unsafe fn vary() {
let x: Foo = transmute(10); //~ ERROR transmute called with types of different sizes
}

fn main() {}
38 changes: 38 additions & 0 deletions src/test/ui/transmute/main.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error[E0512]: transmute called with types of different sizes
--> $DIR/main.rs:20:5
|
20 | transmute(x) //~ ERROR transmute called with types of different sizes
| ^^^^^^^^^
|
= note: source type: <C as TypeConstructor<'a>>::T (size can vary because of <C as TypeConstructor>::T)
= note: target type: <C as TypeConstructor<'b>>::T (size can vary because of <C as TypeConstructor>::T)

error[E0512]: transmute called with types of different sizes
--> $DIR/main.rs:24:17
|
24 | let x: u8 = transmute(10u16); //~ ERROR transmute called with types of different sizes
| ^^^^^^^^^
|
= note: source type: u16 (16 bits)
= note: target type: u8 (8 bits)

error[E0512]: transmute called with types of different sizes
--> $DIR/main.rs:28:17
|
28 | let x: u8 = transmute("test"); //~ ERROR transmute called with types of different sizes
| ^^^^^^^^^
|
= note: source type: &str (128 bits)
= note: target type: u8 (8 bits)

error[E0512]: transmute called with types of different sizes
--> $DIR/main.rs:33:18
|
33 | let x: Foo = transmute(10); //~ ERROR transmute called with types of different sizes
| ^^^^^^^^^
|
= note: source type: i32 (32 bits)
= note: target type: Foo (0 bits)

error: aborting due to previous error(s)

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-x86 fn() has different sizes dependent on platform

use std::mem;

unsafe fn foo() -> (isize, *const (), Option<fn()>) {
unsafe fn foo() -> (i32, *const (), Option<fn()>) {
let i = mem::transmute(bar);
//~^ ERROR is zero-sized and can't be transmuted
//~^^ NOTE cast with `as` to a pointer instead
Expand All @@ -29,8 +31,8 @@ unsafe fn foo() -> (isize, *const (), Option<fn()>) {
unsafe fn bar() {
// Error as usual if the resulting type is not pointer-sized.
mem::transmute::<_, u8>(main);
//~^ ERROR transmute called with differently sized types
//~^^ NOTE transmuting between 0 bits and 8 bits
//~^ ERROR transmute called with types of different sizes
//~^^ NOTE transmuting between fn() {main} and u8

mem::transmute::<_, *mut ()>(foo);
//~^ ERROR is zero-sized and can't be transmuted
Expand All @@ -41,7 +43,7 @@ unsafe fn bar() {
//~^^ NOTE cast with `as` to a pointer instead

// No error if a coercion would otherwise occur.
mem::transmute::<fn(), usize>(main);
mem::transmute::<fn(), u32>(main);
}

unsafe fn baz() {
Expand All @@ -58,7 +60,7 @@ unsafe fn baz() {
//~^^ NOTE cast with `as` to a pointer instead

// No error if a coercion would otherwise occur.
mem::transmute::<Option<fn()>, usize>(Some(main));
mem::transmute::<Option<fn()>, u32>(Some(main));
}

fn main() {
Expand Down
Loading