提交 6e9a1de0 编写于 作者: E Eric Huss

Introduce restricted-std feature.

上级 9e58908e
......@@ -41,7 +41,7 @@
if #[cfg(target_os = "emscripten")] {
#[path = "emcc.rs"]
mod real_imp;
} else if #[cfg(target_arch = "wasm32")] {
} else if #[cfg(any(target_arch = "wasm32", target_os = "none"))] {
#[path = "dummy.rs"]
mod real_imp;
} else if #[cfg(target_os = "hermit")] {
......
......@@ -26,6 +26,7 @@
#![feature(in_band_lifetimes)]
#![feature(negative_impls)]
#![feature(optin_builtin_traits)]
#![feature(restricted_std)]
#![feature(rustc_attrs)]
#![feature(min_specialization)]
#![recursion_limit = "256"]
......
......@@ -502,7 +502,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
match item.kind {
hir::ItemKind::ExternCrate(_) => {
// compiler-generated `extern crate` items have a dummy span.
if item.span.is_dummy() {
// `std` is still checked for the `restricted-std` feature.
if item.span.is_dummy() && item.ident.as_str() != "std" {
return;
}
......
......@@ -64,4 +64,7 @@ fn main() {
println!("cargo:rustc-link-lib=compiler_rt");
}
println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
if target.contains("-none") || target.contains("nvptx") {
println!("cargo:rustc-cfg=feature=\"restricted-std\"");
}
}
......@@ -197,7 +197,8 @@
//! [primitive types]: ../book/ch03-02-data-types.html
//! [rust-discord]: https://discord.gg/rust-lang
#![stable(feature = "rust1", since = "1.0.0")]
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
......@@ -552,3 +553,9 @@ pub mod task {
// the rustdoc documentation for the existing keywords. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("keyword_docs.rs");
// This is required to avoid an unstable error when `restricted-std` is not
// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std
// is unconditional, so the unstable feature needs to be defined somewhere.
#[cfg_attr(not(feature = "restricted-std"), unstable(feature = "restricted_std", issue = "none"))]
mod __restricted_std_workaround {}
......@@ -48,7 +48,8 @@
mod sgx;
pub use self::sgx::*;
} else {
compile_error!("libstd doesn't compile for this platform yet");
mod unsupported;
pub use self::unsupported::*;
}
}
......
use crate::alloc::{GlobalAlloc, Layout, System};
#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
0 as *mut u8
}
#[inline]
unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 {
0 as *mut u8
}
#[inline]
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
#[inline]
unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 {
0 as *mut u8
}
}
use crate::ffi::OsString;
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
pub unsafe fn cleanup() {}
pub struct Args {}
pub fn args() -> Args {
Args {}
}
impl Args {
pub fn inner_debug(&self) -> &[OsString] {
&[]
}
}
impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<OsString> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl ExactSizeIterator for Args {
fn len(&self) -> usize {
0
}
}
impl DoubleEndedIterator for Args {
fn next_back(&mut self) -> Option<OsString> {
None
}
}
use crate::io as std_io;
pub mod memchr {
pub use core::slice::memchr::{memchr, memrchr};
}
pub use crate::sys_common::os_str_bytes as os_str;
// This is not necessarily correct. May want to consider making it part of the
// spec definition?
use crate::os::raw::c_char;
#[cfg(not(test))]
pub fn init() {}
pub fn unsupported<T>() -> std_io::Result<T> {
Err(unsupported_err())
}
pub fn unsupported_err() -> std_io::Error {
std_io::Error::new(std_io::ErrorKind::Other, "operation not supported on this platform")
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Other
}
pub fn abort_internal() -> ! {
core::intrinsics::abort();
}
pub fn hashmap_random_keys() -> (u64, u64) {
(1, 2)
}
// This enum is used as the storage for a bunch of types which can't actually
// exist.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Void {}
pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
return n;
}
......@@ -18,11 +18,11 @@ pub unsafe fn notify_one(&self) {}
pub unsafe fn notify_all(&self) {}
pub unsafe fn wait(&self, _mutex: &Mutex) {
panic!("can't block with web assembly")
panic!("condvar wait not supported")
}
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
panic!("can't block with web assembly");
panic!("condvar wait not supported");
}
#[inline]
......
pub mod os {
pub const FAMILY: &str = "";
pub const OS: &str = "";
pub const DLL_PREFIX: &str = "";
pub const DLL_SUFFIX: &str = "";
pub const DLL_EXTENSION: &str = "";
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}
pub mod alloc;
pub mod args;
pub mod cmath;
pub mod condvar;
pub mod env;
pub mod fs;
pub mod io;
pub mod mutex;
pub mod net;
pub mod os;
pub mod path;
pub mod pipe;
pub mod process;
pub mod rwlock;
pub mod stack_overflow;
pub mod stdio;
pub mod thread;
#[cfg(target_thread_local)]
pub mod thread_local_dtor;
pub mod thread_local_key;
pub mod time;
mod common;
pub use common::*;
......@@ -5,9 +5,10 @@ pub struct Mutex {
}
unsafe impl Send for Mutex {}
unsafe impl Sync for Mutex {} // no threads on wasm
unsafe impl Sync for Mutex {} // no threads on this platform
impl Mutex {
#[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")]
pub const fn new() -> Mutex {
Mutex { locked: UnsafeCell::new(false) }
}
......@@ -42,8 +43,8 @@ pub unsafe fn try_lock(&self) -> bool {
pub unsafe fn destroy(&self) {}
}
// All empty stubs because wasm has no threads yet, so lock acquisition always
// succeeds.
// All empty stubs because this platform does not yet support threads, so lock
// acquisition always succeeds.
pub struct ReentrantMutex {}
impl ReentrantMutex {
......
use super::{unsupported, Void};
use crate::error::Error as StdError;
use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::io;
use crate::path::{self, PathBuf};
use crate::str;
use crate::sys::{unsupported, Void};
pub fn errno() -> i32 {
0
......@@ -48,14 +47,14 @@ pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"not supported on wasm yet".fmt(f)
"not supported on this platform yet".fmt(f)
}
}
impl StdError for JoinPathsError {
#[allow(deprecated)]
fn description(&self) -> &str {
"not supported on wasm yet"
"not supported on this platform yet"
}
}
......@@ -73,7 +72,7 @@ fn next(&mut self) -> Option<(OsString, OsString)> {
}
pub fn env() -> Env {
panic!("not supported on web assembly")
panic!("not supported on this platform")
}
pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
......@@ -81,15 +80,15 @@ pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
}
pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on wasm32-unknown-unknown"))
Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on this platform"))
}
pub fn unsetenv(_: &OsStr) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on wasm32-unknown-unknown"))
Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on this platform"))
}
pub fn temp_dir() -> PathBuf {
panic!("no filesystem on wasm")
panic!("no filesystem on this platform")
}
pub fn home_dir() -> Option<PathBuf> {
......@@ -97,11 +96,9 @@ pub fn home_dir() -> Option<PathBuf> {
}
pub fn exit(_code: i32) -> ! {
unsafe {
crate::arch::wasm32::unreachable();
}
crate::intrinsics::abort()
}
pub fn getpid() -> u32 {
panic!("no pids on wasm")
panic!("no pids on this platform")
}
......@@ -5,7 +5,7 @@ pub struct RWLock {
}
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {} // no threads on wasm
unsafe impl Sync for RWLock {} // no threads on this platform
impl RWLock {
pub const fn new() -> RWLock {
......
use super::{unsupported, Void};
use crate::ffi::CStr;
use crate::io;
use crate::time::Duration;
pub struct Thread(Void);
pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
impl Thread {
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
unsupported()
}
pub fn yield_now() {
// do nothing
}
pub fn set_name(_name: &CStr) {
// nope
}
pub fn sleep(_dur: Duration) {
panic!("can't sleep");
}
pub fn join(self) {
match self.0 {}
}
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}
......@@ -2,25 +2,25 @@
#[inline]
pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
panic!("should not be used on the wasm target");
panic!("should not be used on this target");
}
#[inline]
pub unsafe fn set(_key: Key, _value: *mut u8) {
panic!("should not be used on the wasm target");
panic!("should not be used on this target");
}
#[inline]
pub unsafe fn get(_key: Key) -> *mut u8 {
panic!("should not be used on the wasm target");
panic!("should not be used on this target");
}
#[inline]
pub unsafe fn destroy(_key: Key) {
panic!("should not be used on the wasm target");
panic!("should not be used on this target");
}
#[inline]
pub fn requires_synchronized_create() -> bool {
panic!("should not be used on the wasm target");
panic!("should not be used on this target");
}
......@@ -10,7 +10,7 @@
impl Instant {
pub fn now() -> Instant {
panic!("time not implemented on wasm32-unknown-unknown")
panic!("time not implemented on this platform")
}
pub const fn zero() -> Instant {
......@@ -36,7 +36,7 @@ pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
impl SystemTime {
pub fn now() -> SystemTime {
panic!("time not implemented on wasm32-unknown-unknown")
panic!("time not implemented on this platform")
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
......
......@@ -16,21 +16,18 @@
use crate::io as std_io;
use crate::mem;
use crate::os::raw::c_char;
pub mod alloc;
pub mod args;
#[path = "../wasm/cmath.rs"]
#[path = "../unsupported/cmath.rs"]
pub mod cmath;
#[path = "../wasm/condvar.rs"]
#[path = "../unsupported/condvar.rs"]
pub mod condvar;
pub mod env;
pub mod fd;
pub mod fs;
pub mod io;
#[path = "../wasm/memchr.rs"]
pub mod memchr;
#[path = "../wasm/mutex.rs"]
#[path = "../unsupported/mutex.rs"]
pub mod mutex;
pub mod net;
pub mod os;
......@@ -39,28 +36,22 @@
pub mod path;
pub mod pipe;
pub mod process;
#[path = "../wasm/rwlock.rs"]
#[path = "../unsupported/rwlock.rs"]
pub mod rwlock;
#[path = "../wasm/stack_overflow.rs"]
#[path = "../unsupported/stack_overflow.rs"]
pub mod stack_overflow;
pub mod stdio;
pub mod thread;
#[path = "../wasm/thread_local_dtor.rs"]
#[path = "../unsupported/thread_local_dtor.rs"]
pub mod thread_local_dtor;
#[path = "../wasm/thread_local_key.rs"]
#[path = "../unsupported/thread_local_key.rs"]
pub mod thread_local_key;
pub mod time;
#[cfg(not(test))]
pub fn init() {}
pub fn unsupported<T>() -> std_io::Result<T> {
Err(unsupported_err())
}
pub fn unsupported_err() -> std_io::Error {
std_io::Error::new(std_io::ErrorKind::Other, "operation not supported on wasm yet")
}
#[path = "../unsupported/common.rs"]
#[allow(unused)]
mod common;
pub use common::*;
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind::*;
......@@ -86,20 +77,6 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
}
}
// This enum is used as the storage for a bunch of types which can't actually
// exist.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Void {}
pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
return n;
}
pub fn abort_internal() -> ! {
unsafe { libc::abort() }
}
......
pub use core::slice::memchr::{memchr, memrchr};
......@@ -14,25 +14,35 @@
//! compiling for wasm. That way it's a compile time error for something that's
//! guaranteed to be a runtime error!
use crate::os::raw::c_char;
pub mod alloc;
pub mod args;
#[path = "../unsupported/cmath.rs"]
pub mod cmath;
pub mod env;
#[path = "../unsupported/fs.rs"]
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod memchr;
#[path = "../unsupported/net.rs"]
pub mod net;
#[path = "../unsupported/os.rs"]
pub mod os;
#[path = "../unsupported/path.rs"]
pub mod path;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
#[path = "../unsupported/stack_overflow.rs"]
pub mod stack_overflow;
#[path = "../unsupported/stdio.rs"]
pub mod stdio;
pub mod thread;
#[path = "../unsupported/thread_local_dtor.rs"]
pub mod thread_local_dtor;
#[path = "../unsupported/thread_local_key.rs"]
pub mod thread_local_key;
#[path = "../unsupported/time.rs"]
pub mod time;
pub use crate::sys_common::os_str_bytes as os_str;
......@@ -46,50 +56,15 @@
#[path = "rwlock_atomics.rs"]
pub mod rwlock;
} else {
#[path = "../unsupported/condvar.rs"]
pub mod condvar;
#[path = "../unsupported/mutex.rs"]
pub mod mutex;
#[path = "../unsupported/rwlock.rs"]
pub mod rwlock;
}
}
#[cfg(not(test))]
pub fn init() {}
pub fn unsupported<T>() -> crate::io::Result<T> {
Err(unsupported_err())
}
pub fn unsupported_err() -> crate::io::Error {
crate::io::Error::new(crate::io::ErrorKind::Other, "operation not supported on wasm yet")
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Other
}
// This enum is used as the storage for a bunch of types which can't actually
// exist.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum Void {}
pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
return n;
}
pub fn abort_internal() -> ! {
unsafe { crate::arch::wasm32::unreachable() }
}
// We don't have randomness yet, but I totally used a random number generator to
// generate these numbers.
//
// More seriously though this is just for DOS protection in hash maps. It's ok
// if we don't do that on wasm just yet.
pub fn hashmap_random_keys() -> (u64, u64) {
(1, 2)
}
#[path = "../unsupported/common.rs"]
mod common;
pub use common::*;
......@@ -57,6 +57,7 @@
target_os = "cloudabi",
target_os = "hermit",
target_arch = "wasm32",
feature = "restricted-std",
all(target_vendor = "fortanix", target_env = "sgx")))]
pub mod os_str_bytes;
pub mod poison;
......@@ -74,6 +75,7 @@
if #[cfg(any(target_os = "cloudabi",
target_os = "l4re",
target_os = "hermit",
feature = "restricted-std",
all(target_arch = "wasm32", not(target_os = "emscripten")),
all(target_vendor = "fortanix", target_env = "sgx")))] {
pub use crate::sys::net;
......
......@@ -17,6 +17,7 @@ impl Mutex {
/// Also, until `init` is called, behavior is undefined if this
/// mutex is ever used reentrantly, i.e., `raw_lock` or `try_lock`
/// are called by the thread currently holding the lock.
#[rustc_const_stable(feature = "const_sys_mutex_new", since = "1.0.0")]
pub const fn new() -> Mutex {
Mutex(imp::Mutex::new())
}
......
......@@ -10,7 +10,16 @@
cfg_if::cfg_if! {
if #[cfg(target_env = "msvc")] {
// no extra unwinder support needed
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
} else if #[cfg(
any(
all(target_arch = "wasm32", not(target_os = "emscripten")),
target_os = "none",
target_os = "hermit",
target_os = "uefi",
target_os = "cuda",
target_os = "l4re",
))]
{
// no unwinder on the system!
} else {
mod libunwind;
......
#![feature(restricted_std)]
pub use std::*;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册