Auto merge of #124040 - GuillaumeGomez:rollup-hrrvsgh, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #123673 (Don't ICE for kind mismatches during error rendering) - #123675 (Taint const qualifs if a static is referenced that didn't pass wfcheck) - #123975 (Port the 2 `rust-lld` run-make tests to `rmake`) - #124000 (Use `/* value */` as a placeholder) - #124013 (Box::into_raw: make Miri understand that this is a box-to-raw cast) - #124027 (Prefer identity equality over equating types during coercion.) - #124036 (Remove `default_hidden_visibility: false` from wasm targets) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7e3ba5b8b7
@ -3342,6 +3342,7 @@ name = "run_make_support"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"object 0.34.0",
|
||||
"regex",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
|
@ -331,6 +331,11 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
if self.tcx.is_thread_local_static(def_id) {
|
||||
self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
|
||||
}
|
||||
if let Some(def_id) = def_id.as_local()
|
||||
&& let Err(guar) = self.tcx.at(span).check_well_formed(hir::OwnerId { def_id })
|
||||
{
|
||||
self.error_emitted = Some(guar);
|
||||
}
|
||||
self.check_op_spanned(ops::StaticAccess, span)
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::ItemKind;
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::{self, RegionResolutionError};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
@ -189,10 +189,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||
// even if they do not carry that attribute.
|
||||
use rustc_type_ir::TyKind::*;
|
||||
match (source.kind(), target.kind()) {
|
||||
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
|
||||
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
|
||||
&& mutbl_a == *mutbl_b =>
|
||||
{
|
||||
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if r_a == *r_b && mutbl_a == *mutbl_b => {
|
||||
Ok(())
|
||||
}
|
||||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||
@ -230,18 +227,14 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(ok) =
|
||||
infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b)
|
||||
{
|
||||
if ok.obligations.is_empty() {
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
||||
span,
|
||||
name: field.name,
|
||||
ty: ty_a,
|
||||
}));
|
||||
if ty_a == ty_b {
|
||||
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
||||
span,
|
||||
name: field.name,
|
||||
ty: ty_a,
|
||||
}));
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -433,14 +426,12 @@ pub fn coerce_unsized_info<'tcx>(
|
||||
// something more accepting, but we use
|
||||
// equality because we want to be able to
|
||||
// perform this check without computing
|
||||
// variance where possible. (This is because
|
||||
// we may have to evaluate constraint
|
||||
// variance or constraining opaque types' hidden types.
|
||||
// (This is because we may have to evaluate constraint
|
||||
// expressions in the course of execution.)
|
||||
// See e.g., #41936.
|
||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) {
|
||||
if ok.obligations.is_empty() {
|
||||
return None;
|
||||
}
|
||||
if a == b {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Collect up all fields that were significantly changed
|
||||
|
@ -80,9 +80,6 @@ pub fn options() -> TargetOptions {
|
||||
// threaded model which will legalize atomics to normal operations.
|
||||
singlethread: true,
|
||||
|
||||
// no dynamic linking, no need for default visibility!
|
||||
default_hidden_visibility: true,
|
||||
|
||||
// Symbol visibility takes care of this for the WebAssembly.
|
||||
// Additionally the only known linker, LLD, doesn't support the script
|
||||
// arguments just yet
|
||||
|
@ -4545,7 +4545,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
self.type_implements_trait(default_trait, [ty], param_env).must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
Some(match ty.kind() {
|
||||
Some(match *ty.kind() {
|
||||
ty::Never | ty::Error(_) => return None,
|
||||
ty::Bool => "false".to_string(),
|
||||
ty::Char => "\'x\'".to_string(),
|
||||
@ -4572,12 +4572,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
|
||||
"\"\"".to_string()
|
||||
} else {
|
||||
let ty = self.ty_kind_suggestion(param_env, *ty)?;
|
||||
let ty = self.ty_kind_suggestion(param_env, ty)?;
|
||||
format!("&{}{ty}", mutability.prefix_str())
|
||||
}
|
||||
}
|
||||
ty::Array(ty, len) if let Some(len) = len.try_eval_target_usize(tcx, param_env) => {
|
||||
format!("[{}; {}]", self.ty_kind_suggestion(param_env, *ty)?, len)
|
||||
if len == 0 {
|
||||
"[]".to_string()
|
||||
} else if self.type_is_copy_modulo_regions(param_env, ty) || len == 1 {
|
||||
// Can only suggest `[ty; 0]` if sz == 1 or copy
|
||||
format!("[{}; {}]", self.ty_kind_suggestion(param_env, ty)?, len)
|
||||
} else {
|
||||
"/* value */".to_string()
|
||||
}
|
||||
}
|
||||
ty::Tuple(tys) => format!(
|
||||
"({}{})",
|
||||
@ -4587,7 +4594,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
.join(", "),
|
||||
if tys.len() == 1 { "," } else { "" }
|
||||
),
|
||||
_ => "value".to_string(),
|
||||
_ => "/* value */".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1977,6 +1977,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
for (obligation_arg, impl_arg) in
|
||||
std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
|
||||
{
|
||||
if (obligation_arg, impl_arg).references_error() {
|
||||
return false;
|
||||
}
|
||||
if let Err(terr) =
|
||||
ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
|
||||
{
|
||||
|
@ -1058,7 +1058,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
||||
#[stable(feature = "box_raw", since = "1.4.0")]
|
||||
#[inline]
|
||||
pub fn into_raw(b: Self) -> *mut T {
|
||||
Self::into_raw_with_allocator(b).0
|
||||
// Make sure Miri realizes that we transition from a noalias pointer to a raw pointer here.
|
||||
unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) }
|
||||
}
|
||||
|
||||
/// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
|
||||
@ -1112,7 +1113,10 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
||||
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
|
||||
let mut b = mem::ManuallyDrop::new(b);
|
||||
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
|
||||
// is happening: using the primitive "deref" of `Box`.
|
||||
// is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we
|
||||
// want *no* aliasing requirements here!
|
||||
// In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw`
|
||||
// works around that.
|
||||
let ptr = addr_of_mut!(**b);
|
||||
let alloc = unsafe { ptr::read(&b.1) };
|
||||
(ptr, alloc)
|
||||
|
@ -265,7 +265,10 @@ impl TestProps {
|
||||
aux_bins: vec![],
|
||||
aux_crates: vec![],
|
||||
revisions: vec![],
|
||||
rustc_env: vec![("RUSTC_ICE".to_string(), "0".to_string())],
|
||||
rustc_env: vec![
|
||||
("RUSTC_ICE".to_string(), "0".to_string()),
|
||||
("RUST_BACKTRACE".to_string(), "short".to_string()),
|
||||
],
|
||||
unset_rustc_env: vec![("RUSTC_LOG_COLOR".to_string())],
|
||||
exec_env: vec![],
|
||||
unset_exec_env: vec![],
|
||||
@ -839,6 +842,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"needs-profiler-support",
|
||||
"needs-relocation-model-pic",
|
||||
"needs-run-enabled",
|
||||
"needs-rust-lld",
|
||||
"needs-rust-lldb",
|
||||
"needs-sanitizer-address",
|
||||
"needs-sanitizer-cfi",
|
||||
|
@ -2173,8 +2173,8 @@ impl<'test> TestCx<'test> {
|
||||
let aux_dir = self.aux_output_dir();
|
||||
self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc);
|
||||
|
||||
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
|
||||
rustc.envs(self.props.rustc_env.clone());
|
||||
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
|
||||
self.compose_and_run(
|
||||
rustc,
|
||||
self.config.compile_lib_path.to_str().unwrap(),
|
||||
@ -2220,10 +2220,10 @@ impl<'test> TestCx<'test> {
|
||||
);
|
||||
aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc);
|
||||
|
||||
aux_rustc.envs(aux_props.rustc_env.clone());
|
||||
for key in &aux_props.unset_rustc_env {
|
||||
aux_rustc.env_remove(key);
|
||||
}
|
||||
aux_rustc.envs(aux_props.rustc_env.clone());
|
||||
|
||||
let (aux_type, crate_type) = if is_bin {
|
||||
(AuxType::Bin, Some("bin"))
|
||||
|
@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
--> $DIR/newtype_pair_retagging.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
||||
|
@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
--> $DIR/newtype_retagging.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
||||
|
28
src/tools/miri/tests/pass/issues/issue-miri-3473.rs
Normal file
28
src/tools/miri/tests/pass/issues/issue-miri-3473.rs
Normal file
@ -0,0 +1,28 @@
|
||||
//@revisions: stack tree
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
struct Node {
|
||||
_meta: UnsafeCell<usize>,
|
||||
value: usize,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn value(&self) -> &usize {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
/// This used to cause Stacked Borrows errors because of trouble around conversion
|
||||
/// from Box to raw pointer.
|
||||
fn main() {
|
||||
unsafe {
|
||||
let a = Box::into_raw(Box::new(Node::default()));
|
||||
let ptr = &*a;
|
||||
*UnsafeCell::raw_get(a.cast::<UnsafeCell<usize>>()) = 2;
|
||||
assert_eq!(*ptr.value(), 0);
|
||||
drop(Box::from_raw(a));
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ fn main() {
|
||||
wide_raw_ptr_in_tuple();
|
||||
not_unpin_not_protected();
|
||||
write_does_not_invalidate_all_aliases();
|
||||
box_into_raw_allows_interior_mutable_alias();
|
||||
}
|
||||
|
||||
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
|
||||
@ -263,3 +264,14 @@ fn write_does_not_invalidate_all_aliases() {
|
||||
other::lib2();
|
||||
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
|
||||
}
|
||||
|
||||
fn box_into_raw_allows_interior_mutable_alias() { unsafe {
|
||||
let b = Box::new(std::cell::Cell::new(42));
|
||||
let raw = Box::into_raw(b);
|
||||
let c = &*raw;
|
||||
let d = raw.cast::<i32>(); // bypassing `Cell` -- only okay in Miri tests
|
||||
// `c` and `d` should permit arbitrary aliasing with each other now.
|
||||
*d = 1;
|
||||
c.set(2);
|
||||
drop(Box::from_raw(raw));
|
||||
} }
|
||||
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
object = "0.34.0"
|
||||
wasmparser = "0.118.2"
|
||||
regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
|
||||
|
@ -13,6 +13,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Output};
|
||||
|
||||
pub use object;
|
||||
pub use regex;
|
||||
pub use wasmparser;
|
||||
|
||||
pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
|
||||
|
@ -128,9 +128,8 @@ impl Rustc {
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify target triple.
|
||||
/// Specify the target triple, or a path to a custom target json spec file.
|
||||
pub fn target(&mut self, target: &str) -> &mut Self {
|
||||
assert!(!target.contains(char::is_whitespace), "target triple cannot contain spaces");
|
||||
self.cmd.arg(format!("--target={target}"));
|
||||
self
|
||||
}
|
||||
@ -149,6 +148,12 @@ impl Rustc {
|
||||
self
|
||||
}
|
||||
|
||||
/// Add an extra argument to the linker invocation, via `-Clink-arg`.
|
||||
pub fn link_arg(&mut self, link_arg: &str) -> &mut Self {
|
||||
self.cmd.arg(format!("-Clink-arg={link_arg}"));
|
||||
self
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
|
||||
let caller_location = std::panic::Location::caller();
|
||||
|
@ -249,8 +249,6 @@ run-make/rlib-format-packed-bundled-libs-2/Makefile
|
||||
run-make/rlib-format-packed-bundled-libs-3/Makefile
|
||||
run-make/rlib-format-packed-bundled-libs/Makefile
|
||||
run-make/rmeta-preferred/Makefile
|
||||
run-make/rust-lld-custom-target/Makefile
|
||||
run-make/rust-lld/Makefile
|
||||
run-make/rustc-macro-dep-files/Makefile
|
||||
run-make/rustdoc-determinism/Makefile
|
||||
run-make/rustdoc-error-lines/Makefile
|
||||
|
@ -1,17 +0,0 @@
|
||||
//@ known-bug: #123153
|
||||
pub struct wl_interface {
|
||||
pub version: str,
|
||||
}
|
||||
|
||||
pub struct Interface {
|
||||
pub other_interfaces: &'static [&'static Interface],
|
||||
pub c_ptr: Option<&'static wl_interface>,
|
||||
}
|
||||
|
||||
pub static mut wl_callback_interface: wl_interface = wl_interface { version: 0 };
|
||||
|
||||
pub static WL_CALLBACK_INTERFACE: Interface =
|
||||
Interface { other_interfaces: &[], c_ptr: Some(unsafe { &wl_callback_interface }) };
|
||||
|
||||
|
||||
fn main() {}
|
@ -1,7 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# needs-rust-lld
|
||||
# only-x86_64-unknown-linux-gnu
|
||||
all:
|
||||
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) --crate-type cdylib --target custom-target.json -Clink-args=-Wl,-v lib.rs 2> $(TMPDIR)/output.txt
|
||||
$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
|
51
tests/run-make/rust-lld-custom-target/rmake.rs
Normal file
51
tests/run-make/rust-lld-custom-target/rmake.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// Test linking using `cc` with `rust-lld`, using a custom target with features described in MCP 510
|
||||
// see https://github.com/rust-lang/compiler-team/issues/510 for more info:
|
||||
//
|
||||
// Starting from the `x86_64-unknown-linux-gnu` target spec, we add the following options:
|
||||
// - a linker-flavor using lld via a C compiler
|
||||
// - the self-contained linker component is enabled
|
||||
|
||||
//@ needs-rust-lld
|
||||
//@ only-x86_64-unknown-linux-gnu
|
||||
|
||||
extern crate run_make_support;
|
||||
|
||||
use run_make_support::regex::Regex;
|
||||
use run_make_support::rustc;
|
||||
use std::process::Output;
|
||||
|
||||
fn main() {
|
||||
// Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking
|
||||
// the linker to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.crate_type("cdylib")
|
||||
.target("custom-target.json")
|
||||
.link_arg("-Wl,-v")
|
||||
.input("lib.rs")
|
||||
.run();
|
||||
assert!(
|
||||
find_lld_version_in_logs(output),
|
||||
"the LLD version string should be present in the output logs"
|
||||
);
|
||||
|
||||
// But it can also be disabled via linker features.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.crate_type("cdylib")
|
||||
.target("custom-target.json")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
.link_arg("-Wl,-v")
|
||||
.input("lib.rs")
|
||||
.run();
|
||||
assert!(
|
||||
!find_lld_version_in_logs(output),
|
||||
"the LLD version string should not be present in the output logs"
|
||||
);
|
||||
}
|
||||
|
||||
fn find_lld_version_in_logs(output: Output) -> bool {
|
||||
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.lines().any(|line| lld_version_re.is_match(line))
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
# ignore-msvc
|
||||
# needs-rust-lld
|
||||
# ignore-s390x lld does not yet support s390x as target
|
||||
all:
|
||||
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
|
||||
$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
|
||||
|
||||
# while we're here, also check that the last linker feature flag "wins"
|
||||
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=-lld -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
|
||||
$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
|
64
tests/run-make/rust-lld/rmake.rs
Normal file
64
tests/run-make/rust-lld/rmake.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510
|
||||
// see https://github.com/rust-lang/compiler-team/issues/510 for more info
|
||||
|
||||
//@ needs-rust-lld
|
||||
//@ ignore-msvc
|
||||
//@ ignore-s390x lld does not yet support s390x as target
|
||||
|
||||
extern crate run_make_support;
|
||||
|
||||
use run_make_support::regex::Regex;
|
||||
use run_make_support::rustc;
|
||||
use std::process::Output;
|
||||
|
||||
fn main() {
|
||||
// Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by
|
||||
// asking the linker to display its version number with a link-arg.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.arg("-Zlinker-features=+lld")
|
||||
.arg("-Clink-self-contained=+linker")
|
||||
.arg("-Zunstable-options")
|
||||
.link_arg("-Wl,-v")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
assert!(
|
||||
find_lld_version_in_logs(output),
|
||||
"the LLD version string should be present in the output logs"
|
||||
);
|
||||
|
||||
// It should not be used when we explictly opt-out of lld.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg("-Wl,-v")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
assert!(
|
||||
!find_lld_version_in_logs(output),
|
||||
"the LLD version string should not be present in the output logs"
|
||||
);
|
||||
|
||||
// While we're here, also check that the last linker feature flag "wins" when passed multiple
|
||||
// times to rustc.
|
||||
let output = rustc()
|
||||
.env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
|
||||
.link_arg("-Wl,-v")
|
||||
.arg("-Clink-self-contained=+linker")
|
||||
.arg("-Zunstable-options")
|
||||
.arg("-Zlinker-features=-lld")
|
||||
.arg("-Zlinker-features=+lld")
|
||||
.arg("-Zlinker-features=-lld,+lld")
|
||||
.input("main.rs")
|
||||
.run();
|
||||
assert!(
|
||||
find_lld_version_in_logs(output),
|
||||
"the LLD version string should be present in the output logs"
|
||||
);
|
||||
}
|
||||
|
||||
fn find_lld_version_in_logs(output: Output) -> bool {
|
||||
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
stderr.lines().any(|line| lld_version_re.is_match(line))
|
||||
}
|
@ -8,8 +8,8 @@ LL | origin = Point { x: 10, ..origin };
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let mut origin: Point = value;
|
||||
| +++++++
|
||||
LL | let mut origin: Point = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -21,8 +21,8 @@ LL | let _y = &**x;
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let x: &&S<i32, i32> = &&value;
|
||||
| +++++++++
|
||||
LL | let x: &&S<i32, i32> = &&/* value */;
|
||||
| +++++++++++++++
|
||||
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/borrowck-uninit-ref-chain.rs:14:14
|
||||
|
@ -9,8 +9,8 @@ LL | Err(last_error)
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let mut last_error: Box<dyn std::error::Error> = Box::new(value);
|
||||
| +++++++++++++++++
|
||||
LL | let mut last_error: Box<dyn std::error::Error> = Box::new(/* value */);
|
||||
| +++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -50,8 +50,8 @@ LL | println!("demo_no: {:?}", demo_no);
|
||||
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let demo_no: DemoNoDef = value;
|
||||
| +++++++
|
||||
LL | let demo_no: DemoNoDef = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error[E0381]: used binding `arr` isn't initialized
|
||||
--> $DIR/suggest-assign-rvalue.rs:34:27
|
||||
|
24
tests/ui/const-generics/kind_mismatch.rs
Normal file
24
tests/ui/const-generics/kind_mismatch.rs
Normal file
@ -0,0 +1,24 @@
|
||||
//! This test used to ICE in typeck because of the type/const mismatch,
|
||||
//! even though wfcheck already errored.
|
||||
//! issue: rust-lang/rust#123457
|
||||
|
||||
pub struct KeyHolder<const K: u8> {}
|
||||
|
||||
pub trait ContainsKey<const K: u8> {}
|
||||
|
||||
pub trait SubsetExcept<P> {}
|
||||
|
||||
impl<K> ContainsKey<K> for KeyHolder<K> {}
|
||||
//~^ ERROR: type provided when a constant was expected
|
||||
//~| ERROR: type provided when a constant was expected
|
||||
|
||||
impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {}
|
||||
|
||||
pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let map: KeyHolder<0> = remove_key::<_, _>();
|
||||
//~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
|
||||
}
|
39
tests/ui/const-generics/kind_mismatch.stderr
Normal file
39
tests/ui/const-generics/kind_mismatch.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error[E0747]: type provided when a constant was expected
|
||||
--> $DIR/kind_mismatch.rs:11:38
|
||||
|
|
||||
LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
|
||||
| - ^
|
||||
| |
|
||||
| help: consider changing this type parameter to a const parameter: `const K: u8`
|
||||
|
||||
error[E0747]: type provided when a constant was expected
|
||||
--> $DIR/kind_mismatch.rs:11:21
|
||||
|
|
||||
LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
|
||||
| - ^
|
||||
| |
|
||||
| help: consider changing this type parameter to a const parameter: `const K: u8`
|
||||
|
||||
error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
|
||||
--> $DIR/kind_mismatch.rs:22:45
|
||||
|
|
||||
LL | let map: KeyHolder<0> = remove_key::<_, _>();
|
||||
| ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>`, which is required by `KeyHolder<0>: SubsetExcept<_>`
|
||||
|
|
||||
note: required for `KeyHolder<0>` to implement `SubsetExcept<_>`
|
||||
--> $DIR/kind_mismatch.rs:15:28
|
||||
|
|
||||
LL | impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {}
|
||||
| -------------- ^^^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required by a bound in `remove_key`
|
||||
--> $DIR/kind_mismatch.rs:17:25
|
||||
|
|
||||
LL | pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `remove_key`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0747.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
@ -10,8 +10,8 @@ LL | break;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break value;
|
||||
| +++++
|
||||
LL | break /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -246,8 +246,8 @@ LL | break;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break value;
|
||||
| +++++
|
||||
LL | break /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/loop-break-value.rs:112:9
|
||||
@ -260,8 +260,8 @@ LL | break;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break value;
|
||||
| +++++
|
||||
LL | break /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/loop-break-value.rs:124:9
|
||||
@ -274,8 +274,8 @@ LL | break 'a;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break 'a value;
|
||||
| +++++
|
||||
LL | break 'a /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/loop-break-value.rs:135:15
|
||||
@ -297,8 +297,8 @@ LL | break 'a;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break 'a value;
|
||||
| +++++
|
||||
LL | break 'a /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/loop-break-value.rs:147:15
|
||||
@ -320,8 +320,8 @@ LL | break 'a;
|
||||
|
|
||||
help: give the `break` a value of the expected type
|
||||
|
|
||||
LL | break 'a value;
|
||||
| +++++
|
||||
LL | break 'a /* value */;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/loop-break-value.rs:159:15
|
||||
|
@ -80,8 +80,8 @@ LL | let _used = value;
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let value: NonCopy = value;
|
||||
| +++++++
|
||||
LL | let value: NonCopy = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error[E0381]: used binding `value` isn't initialized
|
||||
--> $DIR/issue-72649-uninit-in-loop.rs:73:21
|
||||
@ -94,8 +94,8 @@ LL | let _used = value;
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let mut value: NonCopy = value;
|
||||
| +++++++
|
||||
LL | let mut value: NonCopy = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -8,8 +8,8 @@ LL | a[i] = d();
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let mut a: [D; 4] = [value; 4];
|
||||
| ++++++++++++
|
||||
LL | let mut a: [D; 4] = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -9,8 +9,8 @@ LL | std::ptr::addr_of_mut!(x);
|
||||
= note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let mut x: S = value;
|
||||
| +++++++
|
||||
LL | let mut x: S = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -43,8 +43,8 @@ LL | match n {}
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let n: Never = value;
|
||||
| +++++++
|
||||
LL | let n: Never = /* value */;
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
21
tests/ui/statics/unsized_type2.rs
Normal file
21
tests/ui/statics/unsized_type2.rs
Normal file
@ -0,0 +1,21 @@
|
||||
//! This test used to actually start evaluating the static even though
|
||||
//! there were errors in typeck.
|
||||
//! issue: rust-lang/rust#123153
|
||||
|
||||
pub struct Foo {
|
||||
pub version: str,
|
||||
}
|
||||
|
||||
pub struct Bar {
|
||||
pub ok: &'static [&'static Bar],
|
||||
pub bad: &'static Foo,
|
||||
}
|
||||
|
||||
pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||
//~^ ERROR the size for values of type `str` cannot be known at compilation time
|
||||
//~| ERROR the size for values of type `str` cannot be known at compilation time
|
||||
//~| ERROR mismatched types
|
||||
|
||||
pub static USE_WITH_ERROR: Bar = Bar { ok: &[], bad: &WITH_ERROR };
|
||||
|
||||
fn main() {}
|
37
tests/ui/statics/unsized_type2.stderr
Normal file
37
tests/ui/statics/unsized_type2.stderr
Normal file
@ -0,0 +1,37 @@
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/unsized_type2.rs:14:24
|
||||
|
|
||||
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized`
|
||||
note: required because it appears within the type `Foo`
|
||||
--> $DIR/unsized_type2.rs:5:12
|
||||
|
|
||||
LL | pub struct Foo {
|
||||
| ^^^
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/unsized_type2.rs:14:30
|
||||
|
|
||||
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized`
|
||||
note: required because it appears within the type `Foo`
|
||||
--> $DIR/unsized_type2.rs:5:12
|
||||
|
|
||||
LL | pub struct Foo {
|
||||
| ^^^
|
||||
= note: constant expressions must have a statically known size
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_type2.rs:14:45
|
||||
|
|
||||
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||
| ^ expected `str`, found integer
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user