mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-18 18:53:04 +00:00
Auto merge of #2742 - RalfJung:targets, r=RalfJung
handle unknown targets more gracefully In particular don't require a list of all OSes in the TLS machinery. Instead just fall back to doing nothing.
This commit is contained in:
commit
fbdf926e70
@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let min_align = match this.tcx.sess.target.arch.as_ref() {
|
||||
"x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8,
|
||||
"x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16,
|
||||
arch => bug!("Unsupported target architecture: {}", arch),
|
||||
arch => bug!("unsupported target architecture for malloc: `{}`", arch),
|
||||
};
|
||||
// Windows always aligns, even small allocations.
|
||||
// Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
|
||||
@ -320,7 +320,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
return Ok(Some(body));
|
||||
}
|
||||
|
||||
this.handle_unsupported(format!("can't call foreign function: {link_name}"))?;
|
||||
this.handle_unsupported(format!(
|
||||
"can't call foreign function `{link_name}` on OS `{os}`",
|
||||
os = this.tcx.sess.target.os,
|
||||
))?;
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
@ -336,9 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let allocator_kind = if let Some(allocator_kind) = this.tcx.allocator_kind(()) {
|
||||
allocator_kind
|
||||
} else {
|
||||
let Some(allocator_kind) = this.tcx.allocator_kind(()) else {
|
||||
// in real code, this symbol does not exist without an allocator
|
||||
return Ok(EmulateByNameResult::NotSupported);
|
||||
};
|
||||
@ -420,9 +421,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr).map_err(|_e| {
|
||||
err_machine_stop!(TerminationInfo::Abort(
|
||||
format!("pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}")
|
||||
))
|
||||
err_machine_stop!(TerminationInfo::Abort(format!(
|
||||
"pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}"
|
||||
)))
|
||||
})?;
|
||||
this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
|
||||
}
|
||||
@ -438,7 +439,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr)?;
|
||||
if offset != Size::ZERO {
|
||||
throw_unsup_format!("pointer passed to miri_static_root must point to beginning of an allocated block");
|
||||
throw_unsup_format!(
|
||||
"pointer passed to miri_static_root must point to beginning of an allocated block"
|
||||
);
|
||||
}
|
||||
this.machine.static_roots.push(alloc_id);
|
||||
}
|
||||
@ -453,7 +456,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
// We read this as a plain OsStr and write it as a path, which will convert it to the target.
|
||||
let path = this.read_os_str_from_c_str(ptr)?.to_owned();
|
||||
let (success, needed_size) = this.write_path_to_c_str(Path::new(&path), out, out_size)?;
|
||||
let (success, needed_size) =
|
||||
this.write_path_to_c_str(Path::new(&path), out, out_size)?;
|
||||
// Return value: 0 on success, otherwise the size it would have needed.
|
||||
this.write_int(if success { 0 } else { needed_size }, dest)?;
|
||||
}
|
||||
@ -505,11 +509,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
"calloc" => {
|
||||
let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let [items, len] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let items = this.read_machine_usize(items)?;
|
||||
let len = this.read_machine_usize(len)?;
|
||||
let size =
|
||||
items.checked_mul(len).ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
|
||||
let size = items
|
||||
.checked_mul(len)
|
||||
.ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
|
||||
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
@ -519,7 +525,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
this.free(ptr, MiriMemoryKind::C)?;
|
||||
}
|
||||
"realloc" => {
|
||||
let [old_ptr, new_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let [old_ptr, new_size] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let old_ptr = this.read_pointer(old_ptr)?;
|
||||
let new_size = this.read_machine_usize(new_size)?;
|
||||
let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?;
|
||||
@ -551,11 +558,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
};
|
||||
|
||||
match link_name.as_str() {
|
||||
"__rust_alloc" => return this.emulate_allocator(Symbol::intern("__rg_alloc"), default),
|
||||
"__rust_alloc" =>
|
||||
return this.emulate_allocator(Symbol::intern("__rg_alloc"), default),
|
||||
"miri_alloc" => {
|
||||
default(this)?;
|
||||
return Ok(EmulateByNameResult::NeedsJumping);
|
||||
},
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -574,7 +582,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
)?;
|
||||
|
||||
// We just allocated this, the access is definitely in-bounds.
|
||||
this.write_bytes_ptr(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap();
|
||||
this.write_bytes_ptr(
|
||||
ptr.into(),
|
||||
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
|
||||
)
|
||||
.unwrap();
|
||||
this.write_pointer(ptr, dest)
|
||||
});
|
||||
}
|
||||
@ -600,7 +612,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
};
|
||||
|
||||
match link_name.as_str() {
|
||||
"__rust_dealloc" => return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default),
|
||||
"__rust_dealloc" =>
|
||||
return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default),
|
||||
"miri_dealloc" => {
|
||||
default(this)?;
|
||||
return Ok(EmulateByNameResult::NeedsJumping);
|
||||
@ -609,7 +622,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
"__rust_realloc" => {
|
||||
let [ptr, old_size, align, new_size] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let [ptr, old_size, align, new_size] =
|
||||
this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_machine_usize(old_size)?;
|
||||
let align = this.read_machine_usize(align)?;
|
||||
@ -633,7 +647,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
|
||||
// C memory handling functions
|
||||
"memcmp" => {
|
||||
let [left, right, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let [left, right, n] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let left = this.read_pointer(left)?;
|
||||
let right = this.read_pointer(right)?;
|
||||
let n = Size::from_bytes(this.read_machine_usize(n)?);
|
||||
@ -653,7 +668,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||
}
|
||||
"memrchr" => {
|
||||
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let [ptr, val, num] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
@ -676,7 +692,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
"memchr" => {
|
||||
let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let [ptr, val, num] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_machine_usize(num)?;
|
||||
@ -699,7 +716,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let n = this.read_c_str(ptr)?.len();
|
||||
this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_machine_usize(u64::try_from(n).unwrap(), this),
|
||||
dest,
|
||||
)?;
|
||||
}
|
||||
|
||||
// math functions (note that there are also intrinsics for some other functions)
|
||||
@ -835,7 +855,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let a = this.read_scalar(a)?.to_u64()?;
|
||||
let b = this.read_scalar(b)?.to_u64()?;
|
||||
|
||||
#[allow(clippy::integer_arithmetic)] // adding two u64 and a u8 cannot wrap in a u128
|
||||
#[allow(clippy::integer_arithmetic)]
|
||||
// adding two u64 and a u8 cannot wrap in a u128
|
||||
let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
|
||||
#[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64
|
||||
let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
|
||||
@ -845,7 +866,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let sum_field = this.place_field(dest, 1)?;
|
||||
this.write_scalar(Scalar::from_u64(sum), &sum_field)?;
|
||||
}
|
||||
"llvm.x86.sse2.pause" if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => {
|
||||
"llvm.x86.sse2.pause"
|
||||
if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" =>
|
||||
{
|
||||
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.yield_active_thread();
|
||||
}
|
||||
@ -853,7 +876,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
|
||||
let arg = this.read_scalar(arg)?.to_i32()?;
|
||||
match arg {
|
||||
15 => { // SY ("full system scope")
|
||||
// SY ("full system scope")
|
||||
15 => {
|
||||
this.yield_active_thread();
|
||||
}
|
||||
_ => {
|
||||
@ -863,11 +887,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
// Platform-specific shims
|
||||
_ => match this.tcx.sess.target.os.as_ref() {
|
||||
target if target_os_is_unix(target) => return shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"windows" => return shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
target => throw_unsup_format!("the target `{}` is not supported", target),
|
||||
}
|
||||
_ =>
|
||||
return match this.tcx.sess.target.os.as_ref() {
|
||||
target_os if target_os_is_unix(target_os) =>
|
||||
shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
|
||||
this, link_name, abi, args, dest,
|
||||
),
|
||||
"windows" =>
|
||||
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
|
||||
this, link_name, abi, args, dest,
|
||||
),
|
||||
_ => Ok(EmulateByNameResult::NotSupported),
|
||||
},
|
||||
};
|
||||
// We only fall through to here if we did *not* hit the `_` arm above,
|
||||
// i.e., if we actually emulated the function with one of the shims.
|
||||
|
@ -257,16 +257,11 @@ impl TlsDtorsState {
|
||||
// And move to the final state.
|
||||
self.0 = Done;
|
||||
}
|
||||
"wasi" | "none" => {
|
||||
// No OS, no TLS dtors.
|
||||
_ => {
|
||||
// No TLS dtor support.
|
||||
// FIXME: should we do something on wasi?
|
||||
self.0 = Done;
|
||||
}
|
||||
os => {
|
||||
throw_unsup_format!(
|
||||
"the TLS machinery does not know how to handle OS `{os}`"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
PthreadDtors(state) => {
|
||||
|
@ -596,13 +596,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
// Platform-specific shims
|
||||
_ => {
|
||||
let target_os = &*this.tcx.sess.target.os;
|
||||
match target_os {
|
||||
"android" => return shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"freebsd" => return shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"linux" => return shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"macos" => return shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
_ => panic!("unsupported Unix OS {target_os}"),
|
||||
}
|
||||
return match target_os {
|
||||
"android" => shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"freebsd" => shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"linux" => shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"macos" => shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
_ => Ok(EmulateByNameResult::NotSupported),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//@only-target-linux
|
||||
//@only-on-host
|
||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||
|
||||
extern "C" {
|
||||
fn foo();
|
||||
@ -7,6 +8,6 @@ extern "C" {
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
foo(); //~ ERROR: unsupported operation: can't call foreign function: foo
|
||||
foo(); //~ ERROR: unsupported operation: can't call foreign function `foo`
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: unsupported operation: can't call foreign function: foo
|
||||
error: unsupported operation: can't call foreign function `foo` on $OS
|
||||
--> $DIR/function_not_in_so.rs:LL:CC
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^ can't call foreign function: foo
|
||||
| ^^^^^ can't call foreign function `foo` on $OS
|
||||
|
|
||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
|
||||
= note: BACKTRACE:
|
||||
|
@ -1,3 +1,4 @@
|
||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||
// Make sure we pretend the allocation symbols don't exist when there is no allocator
|
||||
|
||||
#![feature(lang_items, start)]
|
||||
@ -10,7 +11,7 @@ extern "Rust" {
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
unsafe {
|
||||
__rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function: __rust_alloc
|
||||
__rust_alloc(1, 1); //~ERROR: unsupported operation: can't call foreign function `__rust_alloc`
|
||||
}
|
||||
|
||||
0
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: unsupported operation: can't call foreign function: __rust_alloc
|
||||
error: unsupported operation: can't call foreign function `__rust_alloc` on $OS
|
||||
--> $DIR/no_global_allocator.rs:LL:CC
|
||||
|
|
||||
LL | __rust_alloc(1, 1);
|
||||
| ^^^^^^^^^^^^^^^^^^ can't call foreign function: __rust_alloc
|
||||
| ^^^^^^^^^^^^^^^^^^ can't call foreign function `__rust_alloc` on $OS
|
||||
|
|
||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
|
||||
= note: BACKTRACE:
|
||||
|
@ -1,9 +1,11 @@
|
||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||
|
||||
fn main() {
|
||||
extern "Rust" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
foo(); //~ ERROR: unsupported operation: can't call foreign function: foo
|
||||
foo(); //~ ERROR: unsupported operation: can't call foreign function `foo`
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: unsupported operation: can't call foreign function: foo
|
||||
error: unsupported operation: can't call foreign function `foo` on $OS
|
||||
--> $DIR/unsupported_foreign_function.rs:LL:CC
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^ can't call foreign function: foo
|
||||
| ^^^^^ can't call foreign function `foo` on $OS
|
||||
|
|
||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
|
||||
= note: BACKTRACE:
|
||||
|
@ -1,10 +1,11 @@
|
||||
//! `signal()` is special on Linux and macOS that it's only supported within libstd.
|
||||
//! The implementation is not complete enough to permit user code to call it.
|
||||
//@ignore-target-windows: No libc on Windows
|
||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
libc::signal(libc::SIGPIPE, libc::SIG_IGN);
|
||||
//~^ ERROR: unsupported operation: can't call foreign function: signal
|
||||
//~^ ERROR: unsupported operation: can't call foreign function `signal`
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
error: unsupported operation: can't call foreign function: signal
|
||||
--> $DIR/unsupported_signal.rs:LL:CC
|
||||
error: unsupported operation: can't call foreign function `signal` on $OS
|
||||
--> $DIR/unsupported_incomplete_function.rs:LL:CC
|
||||
|
|
||||
LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function: signal
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS
|
||||
|
|
||||
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at $DIR/unsupported_signal.rs:LL:CC
|
||||
= note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
@ -1,4 +1,5 @@
|
||||
//@compile-flags: -Zmiri-panic-on-unsupported
|
||||
//@normalize-stderr-test: "OS `.*`" -> "$$OS"
|
||||
|
||||
fn main() {
|
||||
extern "Rust" {
|
||||
|
@ -1,2 +1,2 @@
|
||||
thread 'main' panicked at 'unsupported Miri functionality: can't call foreign function: foo', $DIR/unsupported_foreign_function.rs:LL:CC
|
||||
thread 'main' panicked at 'unsupported Miri functionality: can't call foreign function `foo` on $OS', $DIR/unsupported_foreign_function.rs:LL:CC
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
Loading…
Reference in New Issue
Block a user