From 658ea389fd753049bd8ef3f100ee4edb9c9f2a44 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 26 Nov 2017 12:09:35 -0500 Subject: [PATCH 1/4] rustc_llvm: remove stale references ...that were removed in 77c3bfa7429abf87b76ba84108df018d9e9d90e2. --- .gitignore | 1 - src/librustc_llvm/ffi.rs | 18 +++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 309fbd95345a4..57407a2399a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -95,7 +95,6 @@ config.stamp keywords.md lexer.ml src/etc/dl -src/librustc_llvm/llvmdeps.rs tmp.*.rs version.md version.ml diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index dd64d76bc0c51..1c2fa1bbb4848 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -505,17 +505,13 @@ pub mod debuginfo { pub enum ModuleBuffer {} -// Link to our native llvm bindings (things that we need to use the C++ api -// for) and because llvm is written in C++ we need to link against libstdc++ -// -// You'll probably notice that there is an omission of all LLVM libraries -// from this location. This is because the set of LLVM libraries that we -// link to is mostly defined by LLVM, and the `llvm-config` tool is used to -// figure out the exact set of libraries. To do this, the build system -// generates an llvmdeps.rs file next to this one which will be -// automatically updated whenever LLVM is updated to include an up-to-date -// set of the libraries we need to link to LLVM for. -#[link(name = "rustllvm", kind = "static")] // not quite true but good enough +// This annotation is primarily needed for MSVC where attributes like +// dllimport/dllexport are applied and need to be correct for everything to +// link successfully. The #[link] annotation here says "these symbols are +// included statically" which means that they're all exported with dllexport +// and from the rustc_llvm dynamic library. Otherwise the rustc_trans dynamic +// library would not be able to access these symbols. +#[link(name = "rustllvm", kind = "static")] extern "C" { // Create and destroy contexts. pub fn LLVMContextCreate() -> ContextRef; From 9067d9735a9ef96f64c32ed41c120faa0976c772 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 26 Nov 2017 16:25:49 -0500 Subject: [PATCH 2/4] rustc_llvm: use cc::Build::define --- src/librustc_llvm/build.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 141a9a8d704d2..d860c6c44f024 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -154,13 +154,13 @@ fn main() { } for component in &components { - let mut flag = String::from("-DLLVM_COMPONENT_"); + let mut flag = String::from("LLVM_COMPONENT_"); flag.push_str(&component.to_uppercase()); - cfg.flag(&flag); + cfg.define(&flag, None); } if env::var_os("LLVM_RUSTLLVM").is_some() { - cfg.flag("-DLLVM_RUSTLLVM"); + cfg.define("LLVM_RUSTLLVM", None); } build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); From 94d02b896c3feb5e997b95a660e850c7ad8cbe74 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 26 Nov 2017 16:43:24 -0500 Subject: [PATCH 3/4] *: strip calls to cc::Build::compile The documentation states: "The name output should be the name of the library." and this is already done in more recently-added callers. --- src/bootstrap/native.rs | 2 +- src/liballoc_jemalloc/build.rs | 2 +- src/libprofiler_builtins/build.rs | 2 +- src/librustc_llvm/build.rs | 2 +- src/librustdoc/build.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index ac068ebe65178..a5408ee381bbb 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -316,7 +316,7 @@ impl Step for TestHelpers { .warnings(false) .debug(false) .file(build.src.join("src/rt/rust_test_helpers.c")) - .compile("librust_test_helpers.a"); + .compile("rust_test_helpers"); } } diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index a41a04d7cd4f6..de5006ad3960a 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -140,6 +140,6 @@ fn main() { cc::Build::new() .flag("-fvisibility=hidden") .file("pthread_atfork_dummy.c") - .compile("libpthread_atfork_dummy.a"); + .compile("pthread_atfork_dummy"); } } diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 8508b2dae2c56..dd88dd933f691 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -56,5 +56,5 @@ fn main() { cfg.file(Path::new("../libcompiler_builtins/compiler-rt/lib/profile").join(src)); } - cfg.compile("libprofiler-rt.a"); + cfg.compile("profiler-rt"); } diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index d860c6c44f024..f294ceb3f3832 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -169,7 +169,7 @@ fn main() { .file("../rustllvm/ArchiveWrapper.cpp") .cpp(true) .cpp_link_stdlib(None) // we handle this below - .compile("librustllvm.a"); + .compile("rustllvm"); let (llvm_kind, llvm_link_arg) = detect_llvm_link(major, minor, &llvm_config); diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index 97c9ca1e2d27c..276825bd31a75 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -27,6 +27,6 @@ fn main() { .warnings(false) .include(src_dir) .warnings(false) - .compile("libhoedown.a"); + .compile("hoedown"); } From 5a00b7cb74ba1511c012c0163a29cd6972d64135 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 9 Nov 2017 00:46:15 +0200 Subject: [PATCH 4/4] make coercions to `!` in unreachable code a hard error This was added to cover up a lazy extra semicolon in #35849, but does not actually make sense. This is removed as a part of the stabilization of `never_type`. --- src/librustc/lint/builtin.rs | 9 ++++++- src/librustc_lint/lib.rs | 4 ++++ src/librustc_typeck/check/coercion.rs | 11 ++++++++- src/test/compile-fail/coerce-to-bang-cast.rs | 3 +++ src/test/compile-fail/coerce-to-bang.rs | 7 ++++++ .../compile-fail/diverging-fn-tail-35849.rs | 10 +++++--- src/test/run-pass/diverging-fn-tail-35849.rs | 2 +- src/test/ui/reachable/expr_unary.rs | 5 +++- src/test/ui/reachable/expr_unary.stderr | 24 +++++++++++++++---- 9 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index ef4a1c8c39949..1008da1e937a5 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -222,6 +222,12 @@ declare_lint! { "detect mut variables which don't need to be mutable" } +declare_lint! { + pub COERCE_NEVER, + Deny, + "detect coercion to !" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -263,7 +269,8 @@ impl LintPass for HardwiredLints { LATE_BOUND_LIFETIME_ARGUMENTS, DEPRECATED, UNUSED_UNSAFE, - UNUSED_MUT + UNUSED_MUT, + COERCE_NEVER ) } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index b4d439f0ba809..fc05f8f0dc245 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -247,6 +247,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(SAFE_PACKED_BORROWS), reference: "issue #46043 ", }, + FutureIncompatibleInfo { + id: LintId::of(COERCE_NEVER), + reference: "issue #46325 ", + }, ]); diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 94422f93e5922..3e725d7ef415c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -66,6 +66,7 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer::{Coercion, InferResult, InferOk}; use rustc::infer::type_variable::TypeVariableOrigin; +use rustc::lint; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use rustc::ty::{self, LvaluePreference, TypeAndMut, @@ -754,7 +755,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // type, but only if the source expression diverges. if target.is_never() && expr_diverges.always() { debug!("permit coercion to `!` because expr diverges"); - return Ok(target); + if self.can_eq(self.param_env, source, target).is_err() { + self.tcx.lint_node( + lint::builtin::COERCE_NEVER, + expr.id, + expr.span, + &format!("cannot coerce `{}` to !", source) + ); + return Ok(target); + } } let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable); diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs index 0479f5cce6537..0d5bf6cd68cb8 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -12,8 +12,11 @@ fn foo(x: usize, y: !, z: usize) { } +#[deny(coerce_never)] fn cast_a() { let y = {return; 22} as !; + //~^ ERROR cannot coerce `i32` to ! + //~| hard error } fn cast_b() { diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index 870665bb49ee6..2cf568777d475 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(never_type)] +#![deny(coerce_never)] fn foo(x: usize, y: !, z: usize) { } @@ -17,6 +18,8 @@ fn call_foo_a() { // the coercion to `!`, but within same expression. Not clear that // these are the rules we want. foo(return, 22, 44); + //~^ ERROR cannot coerce `{integer}` to ! + //~| hard error } fn call_foo_b() { @@ -36,6 +39,8 @@ fn call_foo_d() { let b = 22; let c = 44; foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. + //~^ ERROR cannot coerce `{integer}` to ! + //~| hard error } fn call_foo_e() { @@ -75,6 +80,8 @@ fn tuple_a() { fn tuple_b() { // Divergence happens before coercion: OK let x: (usize, !, usize) = (return, 44, 66); + //~^ ERROR cannot coerce `{integer}` to ! + //~| hard error } fn tuple_c() { diff --git a/src/test/compile-fail/diverging-fn-tail-35849.rs b/src/test/compile-fail/diverging-fn-tail-35849.rs index 3a27c08413328..a91c000bbf712 100644 --- a/src/test/compile-fail/diverging-fn-tail-35849.rs +++ b/src/test/compile-fail/diverging-fn-tail-35849.rs @@ -8,9 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn _converge() -> ! { - 42 //~ ERROR mismatched types +#[deny(coerce_never)] +fn assert_sizeof() -> ! { + unsafe { + ::std::mem::transmute::(panic!()) + //~^ ERROR cannot coerce `[u8; 8]` to ! + //~| hard error + } } fn main() { } - diff --git a/src/test/run-pass/diverging-fn-tail-35849.rs b/src/test/run-pass/diverging-fn-tail-35849.rs index 6c05a02e7183c..dfd99bcc9fb47 100644 --- a/src/test/run-pass/diverging-fn-tail-35849.rs +++ b/src/test/run-pass/diverging-fn-tail-35849.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(coerce_never)] fn assert_sizeof() -> ! { unsafe { ::std::mem::transmute::(panic!()) @@ -15,4 +16,3 @@ fn assert_sizeof() -> ! { } fn main() { } - diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index 6cff3ff964439..ad12cb876fe9b 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -12,11 +12,14 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] +#![deny(coerce_never)] #![feature(never_type)] fn foo() { let x: ! = ! { return; 22 }; //~ ERROR unreachable - //~^ ERROR cannot apply unary operator `!` to type `!` + //~^ ERROR cannot coerce + //~| hard error + //~| ERROR cannot apply unary operator `!` to type `!` } fn main() { } diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index f14824728a70c..39120f0bdf980 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,7 +1,7 @@ error: unreachable expression - --> $DIR/expr_unary.rs:18:28 + --> $DIR/expr_unary.rs:19:28 | -18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable +19 | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ | note: lint level defined here @@ -10,11 +10,25 @@ note: lint level defined here 14 | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ +error: cannot coerce `{integer}` to ! + --> $DIR/expr_unary.rs:19:28 + | +19 | let x: ! = ! { return; 22 }; //~ ERROR unreachable + | ^^ + | +note: lint level defined here + --> $DIR/expr_unary.rs:15:9 + | +15 | #![deny(coerce_never)] + | ^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #46325 + error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:18:16 + --> $DIR/expr_unary.rs:19:16 | -18 | let x: ! = ! { return; 22 }; //~ ERROR unreachable +19 | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors