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
36 changed files with 363 additions and 106 deletions
|
@ -3342,6 +3342,7 @@ name = "run_make_support"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"object 0.34.0",
|
"object 0.34.0",
|
||||||
|
"regex",
|
||||||
"wasmparser",
|
"wasmparser",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -331,6 +331,11 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||||
if self.tcx.is_thread_local_static(def_id) {
|
if self.tcx.is_thread_local_static(def_id) {
|
||||||
self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`");
|
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)
|
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::lang_items::LangItem;
|
||||||
use rustc_hir::ItemKind;
|
use rustc_hir::ItemKind;
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::infer::{self, RegionResolutionError};
|
use rustc_infer::infer::{self, RegionResolutionError};
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
|
|
||||||
use rustc_infer::traits::Obligation;
|
use rustc_infer::traits::Obligation;
|
||||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
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.
|
// even if they do not carry that attribute.
|
||||||
use rustc_type_ir::TyKind::*;
|
use rustc_type_ir::TyKind::*;
|
||||||
match (source.kind(), target.kind()) {
|
match (source.kind(), target.kind()) {
|
||||||
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
|
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if r_a == *r_b && mutbl_a == *mutbl_b => {
|
||||||
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
|
|
||||||
&& mutbl_a == *mutbl_b =>
|
|
||||||
{
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
(&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()),
|
||||||
|
@ -230,10 +227,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(ok) =
|
if ty_a == ty_b {
|
||||||
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 {
|
res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
|
||||||
span,
|
span,
|
||||||
name: field.name,
|
name: field.name,
|
||||||
|
@ -242,7 +236,6 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
@ -433,15 +426,13 @@ pub fn coerce_unsized_info<'tcx>(
|
||||||
// something more accepting, but we use
|
// something more accepting, but we use
|
||||||
// equality because we want to be able to
|
// equality because we want to be able to
|
||||||
// perform this check without computing
|
// perform this check without computing
|
||||||
// variance where possible. (This is because
|
// variance or constraining opaque types' hidden types.
|
||||||
// we may have to evaluate constraint
|
// (This is because we may have to evaluate constraint
|
||||||
// expressions in the course of execution.)
|
// expressions in the course of execution.)
|
||||||
// See e.g., #41936.
|
// See e.g., #41936.
|
||||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) {
|
if a == b {
|
||||||
if ok.obligations.is_empty() {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Collect up all fields that were significantly changed
|
// Collect up all fields that were significantly changed
|
||||||
// i.e., those that contain T in coerce_unsized T -> U
|
// i.e., those that contain T in coerce_unsized T -> U
|
||||||
|
|
|
@ -80,9 +80,6 @@ pub fn options() -> TargetOptions {
|
||||||
// threaded model which will legalize atomics to normal operations.
|
// threaded model which will legalize atomics to normal operations.
|
||||||
singlethread: true,
|
singlethread: true,
|
||||||
|
|
||||||
// no dynamic linking, no need for default visibility!
|
|
||||||
default_hidden_visibility: true,
|
|
||||||
|
|
||||||
// Symbol visibility takes care of this for the WebAssembly.
|
// Symbol visibility takes care of this for the WebAssembly.
|
||||||
// Additionally the only known linker, LLD, doesn't support the script
|
// Additionally the only known linker, LLD, doesn't support the script
|
||||||
// arguments just yet
|
// arguments just yet
|
||||||
|
|
|
@ -4545,7 +4545,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
self.type_implements_trait(default_trait, [ty], param_env).must_apply_modulo_regions()
|
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::Never | ty::Error(_) => return None,
|
||||||
ty::Bool => "false".to_string(),
|
ty::Bool => "false".to_string(),
|
||||||
ty::Char => "\'x\'".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) {
|
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
|
||||||
"\"\"".to_string()
|
"\"\"".to_string()
|
||||||
} else {
|
} else {
|
||||||
let ty = self.ty_kind_suggestion(param_env, *ty)?;
|
let ty = self.ty_kind_suggestion(param_env, ty)?;
|
||||||
format!("&{}{ty}", mutability.prefix_str())
|
format!("&{}{ty}", mutability.prefix_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Array(ty, len) if let Some(len) = len.try_eval_target_usize(tcx, param_env) => {
|
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!(
|
ty::Tuple(tys) => format!(
|
||||||
"({}{})",
|
"({}{})",
|
||||||
|
@ -4587,7 +4594,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
.join(", "),
|
.join(", "),
|
||||||
if tys.len() == 1 { "," } else { "" }
|
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
|
for (obligation_arg, impl_arg) in
|
||||||
std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
|
std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
|
||||||
{
|
{
|
||||||
|
if (obligation_arg, impl_arg).references_error() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if let Err(terr) =
|
if let Err(terr) =
|
||||||
ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
|
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")]
|
#[stable(feature = "box_raw", since = "1.4.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_raw(b: Self) -> *mut T {
|
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.
|
/// 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) {
|
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
|
||||||
let mut b = mem::ManuallyDrop::new(b);
|
let mut b = mem::ManuallyDrop::new(b);
|
||||||
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
|
// 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 ptr = addr_of_mut!(**b);
|
||||||
let alloc = unsafe { ptr::read(&b.1) };
|
let alloc = unsafe { ptr::read(&b.1) };
|
||||||
(ptr, alloc)
|
(ptr, alloc)
|
||||||
|
|
|
@ -265,7 +265,10 @@ impl TestProps {
|
||||||
aux_bins: vec![],
|
aux_bins: vec![],
|
||||||
aux_crates: vec![],
|
aux_crates: vec![],
|
||||||
revisions: 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())],
|
unset_rustc_env: vec![("RUSTC_LOG_COLOR".to_string())],
|
||||||
exec_env: vec![],
|
exec_env: vec![],
|
||||||
unset_exec_env: vec![],
|
unset_exec_env: vec![],
|
||||||
|
@ -839,6 +842,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
||||||
"needs-profiler-support",
|
"needs-profiler-support",
|
||||||
"needs-relocation-model-pic",
|
"needs-relocation-model-pic",
|
||||||
"needs-run-enabled",
|
"needs-run-enabled",
|
||||||
|
"needs-rust-lld",
|
||||||
"needs-rust-lldb",
|
"needs-rust-lldb",
|
||||||
"needs-sanitizer-address",
|
"needs-sanitizer-address",
|
||||||
"needs-sanitizer-cfi",
|
"needs-sanitizer-cfi",
|
||||||
|
|
|
@ -2173,8 +2173,8 @@ impl<'test> TestCx<'test> {
|
||||||
let aux_dir = self.aux_output_dir();
|
let aux_dir = self.aux_output_dir();
|
||||||
self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc);
|
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());
|
rustc.envs(self.props.rustc_env.clone());
|
||||||
|
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
|
||||||
self.compose_and_run(
|
self.compose_and_run(
|
||||||
rustc,
|
rustc,
|
||||||
self.config.compile_lib_path.to_str().unwrap(),
|
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_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 {
|
for key in &aux_props.unset_rustc_env {
|
||||||
aux_rustc.env_remove(key);
|
aux_rustc.env_remove(key);
|
||||||
}
|
}
|
||||||
aux_rustc.envs(aux_props.rustc_env.clone());
|
|
||||||
|
|
||||||
let (aux_type, crate_type) = if is_bin {
|
let (aux_type, crate_type) = if is_bin {
|
||||||
(AuxType::Bin, Some("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: 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: 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
|
--> $DIR/newtype_pair_retagging.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
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: 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: 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
|
--> $DIR/newtype_retagging.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let ptr = Box::into_raw(Box::new(0i32));
|
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();
|
wide_raw_ptr_in_tuple();
|
||||||
not_unpin_not_protected();
|
not_unpin_not_protected();
|
||||||
write_does_not_invalidate_all_aliases();
|
write_does_not_invalidate_all_aliases();
|
||||||
|
box_into_raw_allows_interior_mutable_alias();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
|
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
|
||||||
|
@ -263,3 +264,14 @@ fn write_does_not_invalidate_all_aliases() {
|
||||||
other::lib2();
|
other::lib2();
|
||||||
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
|
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]
|
[dependencies]
|
||||||
object = "0.34.0"
|
object = "0.34.0"
|
||||||
wasmparser = "0.118.2"
|
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};
|
use std::process::{Command, Output};
|
||||||
|
|
||||||
pub use object;
|
pub use object;
|
||||||
|
pub use regex;
|
||||||
pub use wasmparser;
|
pub use wasmparser;
|
||||||
|
|
||||||
pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
|
pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
|
||||||
|
|
|
@ -128,9 +128,8 @@ impl Rustc {
|
||||||
self
|
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 {
|
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.cmd.arg(format!("--target={target}"));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -149,6 +148,12 @@ impl Rustc {
|
||||||
self
|
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]
|
#[track_caller]
|
||||||
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
|
pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output {
|
||||||
let caller_location = std::panic::Location::caller();
|
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-3/Makefile
|
||||||
run-make/rlib-format-packed-bundled-libs/Makefile
|
run-make/rlib-format-packed-bundled-libs/Makefile
|
||||||
run-make/rmeta-preferred/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/rustc-macro-dep-files/Makefile
|
||||||
run-make/rustdoc-determinism/Makefile
|
run-make/rustdoc-determinism/Makefile
|
||||||
run-make/rustdoc-error-lines/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
|
help: consider assigning a value
|
||||||
|
|
|
|
||||||
LL | let mut origin: Point = value;
|
LL | let mut origin: Point = /* value */;
|
||||||
| +++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ LL | let _y = &**x;
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
error[E0381]: used binding `x` isn't initialized
|
||||||
--> $DIR/borrowck-uninit-ref-chain.rs:14:14
|
--> $DIR/borrowck-uninit-ref-chain.rs:14:14
|
||||||
|
|
|
@ -9,8 +9,8 @@ LL | Err(last_error)
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
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)
|
= 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
|
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
|
error[E0381]: used binding `arr` isn't initialized
|
||||||
--> $DIR/suggest-assign-rvalue.rs:34:27
|
--> $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
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break value;
|
LL | break /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -246,8 +246,8 @@ LL | break;
|
||||||
|
|
|
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break value;
|
LL | break /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:112:9
|
--> $DIR/loop-break-value.rs:112:9
|
||||||
|
@ -260,8 +260,8 @@ LL | break;
|
||||||
|
|
|
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break value;
|
LL | break /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:124:9
|
--> $DIR/loop-break-value.rs:124:9
|
||||||
|
@ -274,8 +274,8 @@ LL | break 'a;
|
||||||
|
|
|
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break 'a value;
|
LL | break 'a /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:135:15
|
--> $DIR/loop-break-value.rs:135:15
|
||||||
|
@ -297,8 +297,8 @@ LL | break 'a;
|
||||||
|
|
|
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break 'a value;
|
LL | break 'a /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:147:15
|
--> $DIR/loop-break-value.rs:147:15
|
||||||
|
@ -320,8 +320,8 @@ LL | break 'a;
|
||||||
|
|
|
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break 'a value;
|
LL | break 'a /* value */;
|
||||||
| +++++
|
| +++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:159:15
|
--> $DIR/loop-break-value.rs:159:15
|
||||||
|
|
|
@ -80,8 +80,8 @@ LL | let _used = value;
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
help: consider assigning a value
|
||||||
|
|
|
|
||||||
LL | let value: NonCopy = value;
|
LL | let value: NonCopy = /* value */;
|
||||||
| +++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error[E0381]: used binding `value` isn't initialized
|
error[E0381]: used binding `value` isn't initialized
|
||||||
--> $DIR/issue-72649-uninit-in-loop.rs:73:21
|
--> $DIR/issue-72649-uninit-in-loop.rs:73:21
|
||||||
|
@ -94,8 +94,8 @@ LL | let _used = value;
|
||||||
|
|
|
|
||||||
help: consider assigning a 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
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ LL | a[i] = d();
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
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)
|
= 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
|
help: consider assigning a value
|
||||||
|
|
|
|
||||||
LL | let mut x: S = value;
|
LL | let mut x: S = /* value */;
|
||||||
| +++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ LL | match n {}
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
help: consider assigning a value
|
||||||
|
|
|
|
||||||
LL | let n: Never = value;
|
LL | let n: Never = /* value */;
|
||||||
| +++++++
|
| +++++++++++++
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
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…
Add table
Add a link
Reference in a new issue