Auto merge of #144528 - matthiaskrgr:rollup-felcjc1, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang/rust#144226 (Do not assert layout in KnownPanicsLint.) - rust-lang/rust#144385 (Optimize performance by inline in macro hygiene system) - rust-lang/rust#144454 (move uefi test to run-make) - rust-lang/rust#144455 (Unify LLVM ctlz/cttz intrinsic generation) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
eed187cfce
42 changed files with 275 additions and 399 deletions
|
|
@ -382,26 +382,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
let width = size.bits();
|
||||
let llty = self.type_ix(width);
|
||||
match name {
|
||||
sym::ctlz | sym::cttz => {
|
||||
let y = self.const_bool(false);
|
||||
let ret = self.call_intrinsic(
|
||||
format!("llvm.{name}"),
|
||||
&[llty],
|
||||
&[args[0].immediate(), y],
|
||||
);
|
||||
|
||||
self.intcast(ret, result.layout.llvm_type(self), false)
|
||||
}
|
||||
sym::ctlz_nonzero => {
|
||||
let y = self.const_bool(true);
|
||||
sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => {
|
||||
let y =
|
||||
self.const_bool(name == sym::ctlz_nonzero || name == sym::cttz_nonzero);
|
||||
let llvm_name = if name == sym::ctlz || name == sym::ctlz_nonzero {
|
||||
"llvm.ctlz"
|
||||
} else {
|
||||
"llvm.cttz"
|
||||
};
|
||||
let ret =
|
||||
self.call_intrinsic("llvm.ctlz", &[llty], &[args[0].immediate(), y]);
|
||||
self.intcast(ret, result.layout.llvm_type(self), false)
|
||||
}
|
||||
sym::cttz_nonzero => {
|
||||
let y = self.const_bool(true);
|
||||
let ret =
|
||||
self.call_intrinsic("llvm.cttz", &[llty], &[args[0].immediate(), y]);
|
||||
self.call_intrinsic(llvm_name, &[llty], &[args[0].immediate(), y]);
|
||||
self.intcast(ret, result.layout.llvm_type(self), false)
|
||||
}
|
||||
sym::ctpop => {
|
||||
|
|
|
|||
|
|
@ -767,7 +767,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
|
|||
DefKind::Static { .. } => {
|
||||
check_static_inhabited(tcx, def_id);
|
||||
check_static_linkage(tcx, def_id);
|
||||
res = res.and(wfcheck::check_static_item(tcx, def_id));
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
res = res.and(wfcheck::check_static_item(tcx, def_id, ty, true));
|
||||
}
|
||||
DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)),
|
||||
_ => unreachable!(),
|
||||
|
|
|
|||
|
|
@ -1180,12 +1180,13 @@ fn check_item_fn(
|
|||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
pub(super) fn check_static_item(
|
||||
tcx: TyCtxt<'_>,
|
||||
pub(crate) fn check_static_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item_id: LocalDefId,
|
||||
ty: Ty<'tcx>,
|
||||
should_check_for_sync: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
enter_wf_checking_ctxt(tcx, item_id, |wfcx| {
|
||||
let ty = tcx.type_of(item_id).instantiate_identity();
|
||||
let span = tcx.ty_span(item_id);
|
||||
let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
|
||||
|
|
@ -1212,9 +1213,9 @@ pub(super) fn check_static_item(
|
|||
}
|
||||
|
||||
// Ensure that the end result is `Sync` in a non-thread local `static`.
|
||||
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
|
||||
== Some(hir::Mutability::Not)
|
||||
let should_check_for_sync = should_check_for_sync
|
||||
&& !is_foreign_item
|
||||
&& tcx.static_mutability(item_id.to_def_id()) == Some(hir::Mutability::Not)
|
||||
&& !tcx.is_thread_local_static(item_id.to_def_id());
|
||||
|
||||
if should_check_for_sync {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use rustc_middle::{bug, span_bug};
|
|||
use rustc_span::{DUMMY_SP, Ident, Span};
|
||||
|
||||
use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder};
|
||||
use crate::check::wfcheck::check_static_item;
|
||||
use crate::errors::TypeofReservedKeywordUsed;
|
||||
use crate::hir_ty_lowering::HirTyLowerer;
|
||||
|
||||
|
|
@ -217,7 +218,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
"static variable",
|
||||
)
|
||||
} else {
|
||||
icx.lower_ty(ty)
|
||||
let ty = icx.lower_ty(ty);
|
||||
// MIR relies on references to statics being scalars.
|
||||
// Verify that here to avoid ill-formed MIR.
|
||||
match check_static_item(tcx, def_id, ty, false) {
|
||||
Ok(()) => ty,
|
||||
Err(guar) => Ty::new_error(tcx, guar),
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemKind::Const(ident, _, ty, body_id) => {
|
||||
|
|
@ -275,7 +282,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ForeignItemKind::Static(t, _, _) => icx.lower_ty(t),
|
||||
ForeignItemKind::Static(ty, _, _) => {
|
||||
let ty = icx.lower_ty(ty);
|
||||
// MIR relies on references to statics being scalars.
|
||||
// Verify that here to avoid ill-formed MIR.
|
||||
match check_static_item(tcx, def_id, ty, false) {
|
||||
Ok(()) => ty,
|
||||
Err(guar) => Ty::new_error(tcx, guar),
|
||||
}
|
||||
}
|
||||
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ impl ExpnId {
|
|||
|
||||
/// `expn_id.outer_expn_is_descendant_of(ctxt)` is equivalent to but faster than
|
||||
/// `expn_id.is_descendant_of(ctxt.outer_expn())`.
|
||||
#[inline]
|
||||
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
||||
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
|
||||
}
|
||||
|
|
@ -394,6 +395,7 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with<R>(f: impl FnOnce(&mut HygieneData) -> R) -> R {
|
||||
with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut()))
|
||||
}
|
||||
|
|
@ -406,6 +408,7 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn local_expn_data(&self, expn_id: LocalExpnId) -> &ExpnData {
|
||||
self.local_expn_data[expn_id].as_ref().expect("no expansion data for an expansion ID")
|
||||
}
|
||||
|
|
@ -437,23 +440,28 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_to_macros_2_0(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_to_macro_rules(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId {
|
||||
self.syntax_context_data[ctxt.0 as usize].outer_expn
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
|
||||
let data = &self.syntax_context_data[ctxt.0 as usize];
|
||||
(data.outer_expn, data.outer_transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].parent
|
||||
}
|
||||
|
|
@ -718,11 +726,13 @@ impl SyntaxContext {
|
|||
SyntaxContext(raw as u32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_usize(raw: usize) -> SyntaxContext {
|
||||
SyntaxContext(u32::try_from(raw).unwrap())
|
||||
}
|
||||
|
||||
/// Extend a syntax context with a given expansion and transparency.
|
||||
#[inline]
|
||||
pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
|
||||
HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
|
||||
}
|
||||
|
|
@ -743,10 +753,12 @@ impl SyntaxContext {
|
|||
/// of g (call it g1), calling remove_mark will result in the SyntaxContext for the
|
||||
/// invocation of f that created g1.
|
||||
/// Returns the mark that was removed.
|
||||
#[inline]
|
||||
pub fn remove_mark(&mut self) -> ExpnId {
|
||||
HygieneData::with(|data| data.remove_mark(self).0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
|
||||
HygieneData::with(|data| data.marks(self))
|
||||
}
|
||||
|
|
@ -776,11 +788,13 @@ impl SyntaxContext {
|
|||
/// ```
|
||||
/// This returns the expansion whose definition scope we use to privacy check the resolution,
|
||||
/// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
|
||||
#[inline]
|
||||
pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
|
||||
HygieneData::with(|data| data.adjust(self, expn_id))
|
||||
}
|
||||
|
||||
/// Like `SyntaxContext::adjust`, but also normalizes `self` to macros 2.0.
|
||||
#[inline]
|
||||
pub(crate) fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
|
||||
HygieneData::with(|data| {
|
||||
*self = data.normalize_to_macros_2_0(*self);
|
||||
|
|
@ -901,10 +915,12 @@ impl SyntaxContext {
|
|||
HygieneData::with(|data| data.outer_mark(self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn dollar_crate_name(self) -> Symbol {
|
||||
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn edition(self) -> Edition {
|
||||
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_session_globals<R, F>(f: F) -> R
|
||||
where
|
||||
F: FnOnce(&SessionGlobals) -> R,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
|
|||
CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
|
||||
ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS
|
||||
|
||||
COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test
|
||||
ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \
|
||||
CC_aarch64_unknown_uefi=clang-11 \
|
||||
CXX_aarch64_unknown_uefi=clang++-11 \
|
||||
|
|
@ -88,6 +87,8 @@ ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \
|
|||
CC_x86_64_unknown_uefi=clang-11 \
|
||||
CXX_x86_64_unknown_uefi=clang++-11
|
||||
ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \
|
||||
python3 -u /uefi_qemu_test/run.py
|
||||
python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target aarch64-unknown-uefi && \
|
||||
python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target i686-unknown-uefi && \
|
||||
python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target x86_64-unknown-uefi
|
||||
|
||||
ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
TARGET_AARCH64 = "aarch64-unknown-uefi"
|
||||
TARGET_I686 = "i686-unknown-uefi"
|
||||
TARGET_X86_64 = "x86_64-unknown-uefi"
|
||||
|
||||
|
||||
def run(*cmd, capture=False, check=True, env=None, timeout=None):
|
||||
"""Print and run a command, optionally capturing the output."""
|
||||
cmd = [str(p) for p in cmd]
|
||||
print(" ".join(cmd))
|
||||
return subprocess.run(
|
||||
cmd, capture_output=capture, check=check, env=env, text=True, timeout=timeout
|
||||
)
|
||||
|
||||
|
||||
def build_and_run(tmp_dir, target):
|
||||
if target == TARGET_AARCH64:
|
||||
boot_file_name = "bootaa64.efi"
|
||||
ovmf_dir = Path("/usr/share/AAVMF")
|
||||
ovmf_code = "AAVMF_CODE.fd"
|
||||
ovmf_vars = "AAVMF_VARS.fd"
|
||||
qemu = "qemu-system-aarch64"
|
||||
machine = "virt"
|
||||
cpu = "cortex-a72"
|
||||
elif target == TARGET_I686:
|
||||
boot_file_name = "bootia32.efi"
|
||||
ovmf_dir = Path("/usr/share/OVMF")
|
||||
ovmf_code = "OVMF32_CODE_4M.secboot.fd"
|
||||
ovmf_vars = "OVMF32_VARS_4M.fd"
|
||||
# The i686 target intentionally uses 64-bit qemu; the important
|
||||
# difference is that the OVMF code provides a 32-bit environment.
|
||||
qemu = "qemu-system-x86_64"
|
||||
machine = "q35"
|
||||
cpu = "qemu64"
|
||||
elif target == TARGET_X86_64:
|
||||
boot_file_name = "bootx64.efi"
|
||||
ovmf_dir = Path("/usr/share/OVMF")
|
||||
ovmf_code = "OVMF_CODE.fd"
|
||||
ovmf_vars = "OVMF_VARS.fd"
|
||||
qemu = "qemu-system-x86_64"
|
||||
machine = "q35"
|
||||
cpu = "qemu64"
|
||||
else:
|
||||
raise KeyError("invalid target")
|
||||
|
||||
host_artifacts = Path("/checkout/obj/build/x86_64-unknown-linux-gnu")
|
||||
stage0 = host_artifacts / "stage0/bin"
|
||||
stage2 = host_artifacts / "stage2/bin"
|
||||
|
||||
env = dict(os.environ)
|
||||
env["PATH"] = "{}:{}:{}".format(stage2, stage0, env["PATH"])
|
||||
|
||||
# Copy the test create into `tmp_dir`.
|
||||
test_crate = Path(tmp_dir) / "uefi_qemu_test"
|
||||
shutil.copytree("/uefi_qemu_test", test_crate)
|
||||
|
||||
# Build the UEFI executable.
|
||||
run(
|
||||
"cargo",
|
||||
"build",
|
||||
"--manifest-path",
|
||||
test_crate / "Cargo.toml",
|
||||
"--target",
|
||||
target,
|
||||
env=env,
|
||||
)
|
||||
|
||||
# Create a mock EFI System Partition in a subdirectory.
|
||||
esp = test_crate / "esp"
|
||||
boot = esp / "efi/boot"
|
||||
os.makedirs(boot, exist_ok=True)
|
||||
|
||||
# Copy the executable into the ESP.
|
||||
src_exe_path = test_crate / "target" / target / "debug/uefi_qemu_test.efi"
|
||||
shutil.copy(src_exe_path, boot / boot_file_name)
|
||||
print(src_exe_path, boot / boot_file_name)
|
||||
|
||||
# Select the appropriate EDK2 build.
|
||||
ovmf_code = ovmf_dir / ovmf_code
|
||||
ovmf_vars = ovmf_dir / ovmf_vars
|
||||
|
||||
# Make a writable copy of the vars file. aarch64 doesn't boot
|
||||
# correctly with read-only vars.
|
||||
ovmf_rw_vars = Path(tmp_dir) / "vars.fd"
|
||||
shutil.copy(ovmf_vars, ovmf_rw_vars)
|
||||
|
||||
# Run the executable in QEMU and capture the output.
|
||||
output = run(
|
||||
qemu,
|
||||
"-machine",
|
||||
machine,
|
||||
"-cpu",
|
||||
cpu,
|
||||
"-display",
|
||||
"none",
|
||||
"-serial",
|
||||
"stdio",
|
||||
"-drive",
|
||||
f"if=pflash,format=raw,readonly=on,file={ovmf_code}",
|
||||
"-drive",
|
||||
f"if=pflash,format=raw,readonly=off,file={ovmf_rw_vars}",
|
||||
"-drive",
|
||||
f"format=raw,file=fat:rw:{esp}",
|
||||
capture=True,
|
||||
check=True,
|
||||
# Set a timeout to kill the VM in case something goes wrong.
|
||||
timeout=60,
|
||||
).stdout
|
||||
|
||||
if "Hello World!" in output:
|
||||
print("VM produced expected output")
|
||||
else:
|
||||
print("unexpected VM output:")
|
||||
print("---start---")
|
||||
print(output)
|
||||
print("---end---")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
targets = [TARGET_AARCH64, TARGET_I686, TARGET_X86_64]
|
||||
|
||||
for target in targets:
|
||||
# Create a temporary directory so that we have a writeable
|
||||
# workspace.
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
build_and_run(tmp_dir, target)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -992,6 +992,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"only-stable",
|
||||
"only-thumb",
|
||||
"only-tvos",
|
||||
"only-uefi",
|
||||
"only-unix",
|
||||
"only-visionos",
|
||||
"only-wasm32",
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>,
|
|||
// tidy-alphabetical-start
|
||||
("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]),
|
||||
("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]),
|
||||
("src/ci/docker/host-x86_64/test-various/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]),
|
||||
("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]),
|
||||
//("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored
|
||||
//("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored
|
||||
|
|
@ -81,6 +80,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>,
|
|||
("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]),
|
||||
("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]),
|
||||
("src/tools/test-float-parse", EXCEPTIONS, None, &[]),
|
||||
("tests/run-make/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
//@ known-bug: #121176
|
||||
//@ needs-rustc-debug-assertions
|
||||
use std::fmt::Debug;
|
||||
|
||||
static STATIC_1: dyn Debug + Sync = *();
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", &STATIC_1);
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//@ known-bug: rust-lang/rust#129109
|
||||
//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir
|
||||
|
||||
extern "C" {
|
||||
pub static mut symbol: [i8];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("C", unsafe { &symbol });
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
//@ known-bug: #130970
|
||||
//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir
|
||||
|
||||
fn main() {
|
||||
extern "C" {
|
||||
static symbol: [usize];
|
||||
}
|
||||
println!("{}", symbol[0]);
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
//@ known-bug: #131347
|
||||
//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
|
||||
|
||||
struct S;
|
||||
static STUFF: [i8] = [0; S::N];
|
||||
|
||||
fn main() {
|
||||
assert_eq!(STUFF, [0; 63]);
|
||||
}
|
||||
84
tests/run-make/uefi-qemu/rmake.rs
Normal file
84
tests/run-make/uefi-qemu/rmake.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
//! This test builds and runs a basic UEFI application on QEMU for various targets.
|
||||
//!
|
||||
//! You must have the relevant OVMF or AAVMF firmware installed for this to work.
|
||||
//!
|
||||
//! Requires: qemu-system-x86_64, qemu-system-aarch64
|
||||
//! OVMF/AAVMF firmware
|
||||
//!
|
||||
//! Note: test assumes `/uefi_qemu_test` exists and is a self-contained crate.
|
||||
|
||||
//@ only-uefi
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use run_make_support::{cargo, cmd, path, rfs};
|
||||
|
||||
fn main() {
|
||||
let target = run_make_support::target();
|
||||
|
||||
let (boot_filename, ovmf_dir, ovmf_code_name, ovmf_vars_name, qemu, machine, cpu) =
|
||||
match target.as_str() {
|
||||
"aarch64-unknown-uefi" => (
|
||||
"bootaa64.efi",
|
||||
Path::new("/usr/share/AAVMF"),
|
||||
"AAVMF_CODE.fd",
|
||||
"AAVMF_VARS.fd",
|
||||
"qemu-system-aarch64",
|
||||
"virt",
|
||||
"cortex-a72",
|
||||
),
|
||||
"i686-unknown-uefi" => (
|
||||
"bootia32.efi",
|
||||
Path::new("/usr/share/OVMF"),
|
||||
"OVMF32_CODE_4M.secboot.fd",
|
||||
"OVMF32_VARS_4M.fd",
|
||||
"qemu-system-x86_64",
|
||||
"q35",
|
||||
"qemu64",
|
||||
),
|
||||
"x86_64-unknown-uefi" => (
|
||||
"bootx64.efi",
|
||||
Path::new("/usr/share/OVMF"),
|
||||
"OVMF_CODE_4M.fd",
|
||||
"OVMF_VARS_4M.fd",
|
||||
"qemu-system-x86_64",
|
||||
"q35",
|
||||
"qemu64",
|
||||
),
|
||||
_ => panic!("unsupported target {target}"),
|
||||
};
|
||||
|
||||
let tmp = std::env::temp_dir();
|
||||
let test_crate = tmp.join("uefi_qemu_test");
|
||||
rfs::copy_dir_all(path("uefi_qemu_test"), &test_crate);
|
||||
|
||||
cargo().args(&["build", "--target", &target]).current_dir(&test_crate).run();
|
||||
|
||||
// Prepare ESP
|
||||
let esp = test_crate.join("esp");
|
||||
let boot = esp.join("efi/boot");
|
||||
rfs::create_dir_all(&boot);
|
||||
|
||||
let src_efi = test_crate.join("target").join(&target).join("debug/uefi_qemu_test.efi");
|
||||
let dst_efi = boot.join(boot_filename);
|
||||
rfs::copy(&src_efi, &dst_efi);
|
||||
|
||||
// Copy OVMF files
|
||||
let code = ovmf_dir.join(ovmf_code_name);
|
||||
let vars_src = ovmf_dir.join(ovmf_vars_name);
|
||||
let vars_dst = tmp.join("vars.fd");
|
||||
rfs::copy(&vars_src, &vars_dst);
|
||||
|
||||
let output = cmd(qemu)
|
||||
.args(["-machine", machine])
|
||||
.args(["-cpu", cpu])
|
||||
.args(["-display", "none"])
|
||||
.args(["-serial", "stdio"])
|
||||
.args(["-drive", &format!("if=pflash,format=raw,readonly=on,file={}", code.display())])
|
||||
.args(["-drive", &format!("if=pflash,format=raw,readonly=off,file={}", vars_dst.display())])
|
||||
.args(["-drive", &format!("format=raw,file=fat:rw:{}", esp.display())])
|
||||
.run()
|
||||
.stdout_utf8();
|
||||
|
||||
assert!(output.contains("Hello World!"), "invalid output for {target}:\n{output}");
|
||||
}
|
||||
|
|
@ -15,14 +15,7 @@ fn panic_handler(_info: &panic::PanicInfo) -> ! {
|
|||
|
||||
#[export_name = "efi_main"]
|
||||
pub extern "C" fn main(_h: Handle, st: *mut SystemTable) -> Status {
|
||||
let s = [
|
||||
0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello"
|
||||
0x0020u16, // " "
|
||||
0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World"
|
||||
0x0021u16, // "!"
|
||||
0x000au16, // "\n"
|
||||
0x0000u16, // NUL
|
||||
];
|
||||
let s = b"Hello World!\n\0".map(|c| u16::from(c));
|
||||
|
||||
// Print "Hello World!".
|
||||
let r = unsafe { ((*(*st).con_out).output_string)((*st).con_out, s.as_ptr() as *mut Char16) };
|
||||
|
|
@ -10,14 +10,10 @@ const CONST_FOO: str = *"foo";
|
|||
|
||||
static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR cannot move out of a shared reference
|
||||
|
||||
static STATIC_BAR: str = *"bar";
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR cannot move out of a shared reference
|
||||
|
||||
fn main() {
|
||||
println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
|
||||
//~^ ERROR: cannot move a value of type `str`
|
||||
//~| ERROR: cannot move a value of type `dyn Debug + Sync`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
|||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/const-unsized.rs:15:1
|
||||
--> $DIR/const-unsized.rs:14:1
|
||||
|
|
||||
LL | static STATIC_BAR: str = *"bar";
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -46,31 +46,7 @@ error[E0507]: cannot move out of a shared reference
|
|||
LL | const CONST_FOO: str = *"foo";
|
||||
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0507]: cannot move out of a shared reference
|
||||
--> $DIR/const-unsized.rs:11:37
|
||||
|
|
||||
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
error[E0507]: cannot move out of a shared reference
|
||||
--> $DIR/const-unsized.rs:15:26
|
||||
|
|
||||
LL | static STATIC_BAR: str = *"bar";
|
||||
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0161]: cannot move a value of type `dyn Debug + Sync`
|
||||
--> $DIR/const-unsized.rs:20:38
|
||||
|
|
||||
LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
|
||||
| ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined
|
||||
|
||||
error[E0161]: cannot move a value of type `str`
|
||||
--> $DIR/const-unsized.rs:20:48
|
||||
|
|
||||
LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
|
||||
| ^^^^^^^^^ the size of `str` cannot be statically determined
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0161, E0277, E0507.
|
||||
For more information about an error, try `rustc --explain E0161`.
|
||||
Some errors have detailed explanations: E0277, E0507.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ impl<F: Future> Task<F> {
|
|||
}
|
||||
|
||||
pub type F = impl Future;
|
||||
|
||||
#[define_opaque(F)]
|
||||
fn foo()
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0425]: cannot find value `Foo` in this scope
|
||||
--> $DIR/layout-error.rs:26:17
|
||||
--> $DIR/layout-error.rs:27:17
|
||||
|
|
||||
LL | let a = Foo;
|
||||
| ^^^ not found in this scope
|
||||
|
|
|
|||
|
|
@ -6,6 +6,5 @@ trait Qux {
|
|||
|
||||
static FOO: &(dyn Qux + Sync) = "desc";
|
||||
//~^ ERROR the trait `Qux` is not dyn compatible
|
||||
//~| ERROR the trait `Qux` is not dyn compatible
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -21,30 +21,6 @@ help: alternatively, consider constraining `bar` so it does not apply to trait o
|
|||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Qux` is not dyn compatible
|
||||
--> $DIR/taint-const-eval.rs:7:15
|
||||
|
|
||||
LL | static FOO: &(dyn Qux + Sync) = "desc";
|
||||
| ^^^^^^^^^^^^^^ `Qux` is not dyn compatible
|
||||
|
|
||||
note: for a trait to be dyn compatible it needs to allow building a vtable
|
||||
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
|
||||
--> $DIR/taint-const-eval.rs:4:8
|
||||
|
|
||||
LL | trait Qux {
|
||||
| --- this trait is not dyn compatible...
|
||||
LL | fn bar();
|
||||
| ^^^ ...because associated function `bar` has no `self` parameter
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider turning `bar` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn bar(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn bar() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
||||
|
|
|
|||
|
|
@ -3,5 +3,4 @@ fn main() {
|
|||
static symbol: [usize]; //~ ERROR: the size for values of type
|
||||
}
|
||||
println!("{}", symbol[0]);
|
||||
//~^ ERROR: extern static is unsafe
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,6 @@ LL | static symbol: [usize];
|
|||
= help: the trait `Sized` is not implemented for `[usize]`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0133]: use of extern static is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-36122-accessing-externed-dst.rs:5:20
|
||||
|
|
||||
LL | println!("{}", symbol[0]);
|
||||
| ^^^^^^ use of extern static
|
||||
|
|
||||
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0133, E0277.
|
||||
For more information about an error, try `rustc --explain E0133`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -14,5 +14,3 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
|||
|
||||
static BAZ: ([u8], usize) = ([], 0);
|
||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~| ERROR mismatched types
|
||||
|
|
|
|||
|
|
@ -57,26 +57,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
|
|||
= note: expected slice `[u8]`
|
||||
found array `[_; 0]`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-84108.rs:15:13
|
||||
|
|
||||
LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-84108.rs:15:30
|
||||
|
|
||||
LL | static BAZ: ([u8], usize) = ([], 0);
|
||||
| ^^ expected `[u8]`, found `[_; 0]`
|
||||
|
|
||||
= note: expected slice `[u8]`
|
||||
found array `[_; 0]`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308, E0412.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
14
tests/ui/mir/static-by-value-dyn.rs
Normal file
14
tests/ui/mir/static-by-value-dyn.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
//! Regression test for #121176
|
||||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
|
||||
//! which ICEs with unsized statics.
|
||||
//@ needs-rustc-debug-assertions
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
static STATIC_1: dyn Debug + Sync = *();
|
||||
//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known
|
||||
//~| ERROR type `()` cannot be dereferenced
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", &STATIC_1);
|
||||
}
|
||||
19
tests/ui/mir/static-by-value-dyn.stderr
Normal file
19
tests/ui/mir/static-by-value-dyn.stderr
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
||||
--> $DIR/static-by-value-dyn.rs:8:1
|
||||
|
|
||||
LL | static STATIC_1: dyn Debug + Sync = *();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0614]: type `()` cannot be dereferenced
|
||||
--> $DIR/static-by-value-dyn.rs:8:37
|
||||
|
|
||||
LL | static STATIC_1: dyn Debug + Sync = *();
|
||||
| ^^^ can't be dereferenced
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0614.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
10
tests/ui/mir/static-by-value-slice.rs
Normal file
10
tests/ui/mir/static-by-value-slice.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
//! Regression test for #140332
|
||||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
|
||||
//! which ICEs with unsized statics.
|
||||
|
||||
static mut S: [i8] = ["Some thing"; 1];
|
||||
//~^ ERROR the size for values of type `[i8]` cannot be known
|
||||
|
||||
fn main() {
|
||||
assert_eq!(S, [0; 1]);
|
||||
}
|
||||
12
tests/ui/mir/static-by-value-slice.stderr
Normal file
12
tests/ui/mir/static-by-value-slice.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
|
||||
--> $DIR/static-by-value-slice.rs:5:1
|
||||
|
|
||||
LL | static mut S: [i8] = ["Some thing"; 1];
|
||||
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[i8]`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
15
tests/ui/mir/static-by-value-str.rs
Normal file
15
tests/ui/mir/static-by-value-str.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
//! Regression test for #139872
|
||||
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
|
||||
//! which ICEs with unsized statics.
|
||||
|
||||
enum E {
|
||||
V16(u16),
|
||||
V32(u32),
|
||||
}
|
||||
|
||||
static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
|
||||
//~^ ERROR the size for values of type `str` cannot be known
|
||||
|
||||
pub fn main() {
|
||||
let (_, n, _) = C;
|
||||
}
|
||||
13
tests/ui/mir/static-by-value-str.stderr
Normal file
13
tests/ui/mir/static-by-value-str.stderr
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/static-by-value-str.rs:10:1
|
||||
|
|
||||
LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str`
|
||||
= note: required because it appears within the type `(E, u16, str)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
13
tests/ui/mir/unsized-extern-static.rs
Normal file
13
tests/ui/mir/unsized-extern-static.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//! Regression test for #129109
|
||||
//! MIR building used to produce erroneous constants when referring to statics of unsized type.
|
||||
//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir
|
||||
|
||||
extern "C" {
|
||||
pub static mut symbol: [i8];
|
||||
//~^ ERROR the size for values of type `[i8]`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("C", unsafe { &symbol });
|
||||
//~^ ERROR argument never used
|
||||
}
|
||||
20
tests/ui/mir/unsized-extern-static.stderr
Normal file
20
tests/ui/mir/unsized-extern-static.stderr
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
error: argument never used
|
||||
--> $DIR/unsized-extern-static.rs:11:19
|
||||
|
|
||||
LL | println!("C", unsafe { &symbol });
|
||||
| --- ^^^^^^^^^^^^^^^^^^ argument never used
|
||||
| |
|
||||
| formatting specifier missing
|
||||
|
||||
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
|
||||
--> $DIR/unsized-extern-static.rs:6:5
|
||||
|
|
||||
LL | pub static mut symbol: [i8];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[i8]`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
fn main() {
|
||||
static foo: dyn Fn() -> u32 = || -> u32 {
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR cannot be shared between threads safely
|
||||
//~| ERROR mismatched types
|
||||
0
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,3 @@
|
|||
error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
||||
--> $DIR/issue-24446.rs:2:17
|
||||
|
|
||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||
| ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
||||
= note: shared static variables must have a type that implements `Sync`
|
||||
|
||||
error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time
|
||||
--> $DIR/issue-24446.rs:2:5
|
||||
|
|
||||
|
|
@ -16,19 +7,6 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
|||
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-24446.rs:2:35
|
||||
|
|
||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||
| ___________________________________^
|
||||
... |
|
||||
LL | | };
|
||||
| |_____^ expected `dyn Fn`, found closure
|
||||
|
|
||||
= note: expected trait object `(dyn Fn() -> u32 + 'static)`
|
||||
found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ struct Foo<T:Trait> {
|
|||
x: T,
|
||||
}
|
||||
|
||||
static X: Foo<usize> = Foo {
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
static X: Foo<usize> = Foo { //~ ERROR E0277
|
||||
x: 1, //~ ERROR: E0277
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,29 +15,11 @@ note: required by a bound in `Foo`
|
|||
LL | struct Foo<T:Trait> {
|
||||
| ^^^^^ required by this bound in `Foo`
|
||||
|
||||
error[E0277]: the trait bound `usize: Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-static.rs:9:11
|
||||
|
|
||||
LL | static X: Foo<usize> = Foo {
|
||||
| ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/on-structs-and-enums-static.rs:1:1
|
||||
|
|
||||
LL | trait Trait {
|
||||
| ^^^^^^^^^^^
|
||||
note: required by a bound in `Foo`
|
||||
--> $DIR/on-structs-and-enums-static.rs:5:14
|
||||
|
|
||||
LL | struct Foo<T:Trait> {
|
||||
| ^^^^^ required by this bound in `Foo`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `usize: Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-static.rs:12:8
|
||||
error[E0277]: the trait bound `{integer}: Trait` is not satisfied
|
||||
--> $DIR/on-structs-and-enums-static.rs:10:8
|
||||
|
|
||||
LL | x: 1,
|
||||
| ^ the trait `Trait` is not implemented for `usize`
|
||||
| ^ the trait `Trait` is not implemented for `{integer}`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/on-structs-and-enums-static.rs:1:1
|
||||
|
|
@ -50,6 +32,6 @@ note: required by a bound in `Foo`
|
|||
LL | struct Foo<T:Trait> {
|
||||
| ^^^^^ required by this bound in `Foo`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ struct NotCopy;
|
|||
|
||||
static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
//~| ERROR E0277
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -16,43 +16,6 @@ LL + #[derive(Copy)]
|
|||
LL | struct NotCopy;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
|
||||
--> $DIR/wf-static-type.rs:10:13
|
||||
|
|
||||
LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`
|
||||
|
|
||||
= note: required for `Option<NotCopy>` to implement `Copy`
|
||||
note: required by a bound in `IsCopy`
|
||||
--> $DIR/wf-static-type.rs:7:17
|
||||
|
|
||||
LL | struct IsCopy<T:Copy> { t: T }
|
||||
| ^^^^ required by this bound in `IsCopy`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider annotating `NotCopy` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
LL | struct NotCopy;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
|
||||
--> $DIR/wf-static-type.rs:10:51
|
||||
|
|
||||
LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
|
||||
| ^^^^ the trait `Copy` is not implemented for `NotCopy`
|
||||
|
|
||||
= note: required for `Option<NotCopy>` to implement `Copy`
|
||||
note: required by a bound in `IsCopy`
|
||||
--> $DIR/wf-static-type.rs:7:17
|
||||
|
|
||||
LL | struct IsCopy<T:Copy> { t: T }
|
||||
| ^^^^ required by this bound in `IsCopy`
|
||||
help: consider annotating `NotCopy` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
LL | struct NotCopy;
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue