Auto merge of #66997 - Centril:rollup-uraqpgu, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #66750 (Update the `wasi` crate for `wasm32-wasi`)
 - #66878 (Move Sessions into (new) librustc_session)
 - #66903 (parse_enum_item -> parse_enum_variant)
 - #66951 (miri: add throw_machine_stop macro)
 - #66957 (Change Linker for x86_64-fortanix-unknown-sgx target to rust-lld)
 - #66960 ([const-prop] Fix ICE calculating enum discriminant)
 - #66973 (Update the minimum external LLVM to 7)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-12-03 18:42:43 +00:00
commit 7afe6d9d1f
88 changed files with 966 additions and 984 deletions

View File

@ -1294,7 +1294,7 @@ checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
dependencies = [
"cfg-if",
"libc",
"wasi",
"wasi 0.7.0",
]
[[package]]
@ -3205,6 +3205,7 @@ dependencies = [
"rustc_fs_util",
"rustc_index",
"rustc_macros",
"rustc_session",
"rustc_target",
"scoped-tls",
"serialize",
@ -3518,6 +3519,7 @@ dependencies = [
"rustc_fs_util",
"rustc_incremental",
"rustc_index",
"rustc_session",
"rustc_target",
"serialize",
"syntax",
@ -3634,6 +3636,7 @@ dependencies = [
"rustc",
"rustc_data_structures",
"rustc_fs_util",
"rustc_session",
"serialize",
"syntax",
"syntax_pos",
@ -3697,6 +3700,7 @@ dependencies = [
"rustc_error_codes",
"rustc_feature",
"rustc_index",
"rustc_session",
"rustc_target",
"syntax",
"syntax_pos",
@ -3884,6 +3888,22 @@ dependencies = [
"syntax_pos",
]
[[package]]
name = "rustc_session"
version = "0.0.0"
dependencies = [
"log",
"num_cpus",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fs_util",
"rustc_index",
"rustc_target",
"serialize",
"syntax_pos",
]
[[package]]
name = "rustc_target"
version = "0.0.0"
@ -4301,7 +4321,7 @@ dependencies = [
"rustc_msan",
"rustc_tsan",
"unwind",
"wasi",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
@ -4463,6 +4483,7 @@ dependencies = [
"rustc_index",
"rustc_lexer",
"rustc_macros",
"rustc_session",
"scoped-tls",
"serialize",
"smallvec 1.0.0",
@ -5172,6 +5193,12 @@ name = "wasi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",

View File

@ -294,11 +294,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
let mut parts = version.split('.').take(2)
.filter_map(|s| s.parse::<u32>().ok());
if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
if major >= 6 {
if major >= 7 {
return
}
}
panic!("\n\nbad LLVM version: {}, need >=6.0\n\n", version)
panic!("\n\nbad LLVM version: {}, need >=7.0\n\n", version)
}
fn configure_cmake(builder: &Builder<'_>,

View File

@ -18,7 +18,7 @@ jobs:
- template: steps/run.yml
strategy:
matrix:
x86_64-gnu-llvm-6.0:
x86_64-gnu-llvm-7:
RUST_BACKTRACE: 1
dist-x86_64-linux: {}
dist-x86_64-linux-alt:

View File

@ -18,7 +18,7 @@ jobs:
- template: steps/run.yml
strategy:
matrix:
x86_64-gnu-llvm-6.0: {}
x86_64-gnu-llvm-7: {}
mingw-check: {}
x86_64-gnu-tools:
CI_ONLY_WHEN_SUBMODULES_CHANGED: 1

View File

@ -1,4 +1,4 @@
FROM ubuntu:16.04
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
cmake \
sudo \
gdb \
llvm-6.0-tools \
llvm-7-tools \
libedit-dev \
libssl-dev \
pkg-config \
@ -24,7 +24,7 @@ RUN sh /scripts/sccache.sh
# using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
--llvm-root=/usr/lib/llvm-6.0 \
--llvm-root=/usr/lib/llvm-7 \
--enable-llvm-link-shared
ENV SCRIPT python2.7 ../x.py test src/tools/tidy && python2.7 ../x.py test

View File

@ -39,3 +39,4 @@ rustc_fs_util = { path = "../librustc_fs_util" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.4"
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }

View File

@ -5,7 +5,6 @@ mod prev;
mod query;
mod safe;
mod serialized;
pub mod cgu_reuse_tracker;
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};

View File

@ -64,7 +64,6 @@
#![recursion_limit="512"]
#[macro_use] extern crate bitflags;
extern crate getopts;
#[macro_use] extern crate scoped_tls;
#[cfg(windows)]
extern crate libc;
@ -74,10 +73,6 @@ extern crate libc;
#[macro_use] extern crate syntax;
#[macro_use] extern crate smallvec;
// Use the test crate here so we depend on getopts through it. This allow tools to link to both
// librustc_driver and libtest.
extern crate test as _;
#[cfg(test)]
mod tests;
@ -113,7 +108,7 @@ pub mod middle {
}
pub mod mir;
pub mod session;
pub use rustc_session as session;
pub mod traits;
pub mod ty;

View File

@ -12,6 +12,8 @@ use syntax::ast;
use syntax::edition::Edition;
use syntax::source_map::Span;
use syntax::symbol::Symbol;
use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
use rustc_session::declare_lint;
declare_lint! {
pub EXCEEDING_BITSHIFTS,
@ -404,31 +406,6 @@ declare_lint! {
};
}
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
pub mod parser {
declare_lint! {
pub ILL_FORMED_ATTRIBUTE_INPUT,
Deny,
"ill-formed attribute inputs that were previously accepted and used in practice",
@future_incompatible = super::FutureIncompatibleInfo {
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
edition: None,
};
}
declare_lint! {
pub META_VARIABLE_MISUSE,
Allow,
"possible meta-variable misuse at macro definition"
}
declare_lint! {
pub INCOMPLETE_INCLUDE,
Deny,
"trailing content in included file"
}
}
declare_lint! {
pub DEPRECATED_IN_FUTURE,
Allow,
@ -520,8 +497,8 @@ declare_lint_pass! {
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
MACRO_USE_EXTERN_CRATE,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
parser::ILL_FORMED_ATTRIBUTE_INPUT,
parser::META_VARIABLE_MISUSE,
ILL_FORMED_ATTRIBUTE_INPUT,
META_VARIABLE_MISUSE,
DEPRECATED_IN_FUTURE,
AMBIGUOUS_ASSOCIATED_ITEMS,
MUTABLE_BORROW_RESERVATION_CONFLICT,

View File

@ -9,6 +9,7 @@ use errors::Applicability;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::{Ident, Item, ItemKind};
use syntax::symbol::{sym, Symbol};
use rustc_session::declare_tool_lint;
declare_tool_lint! {
pub rustc::DEFAULT_HASH_TYPES,

View File

@ -8,7 +8,7 @@ use crate::lint::{self, Lint, LintId, Level, LintSource};
use crate::session::Session;
use crate::util::nodemap::FxHashMap;
use errors::{Applicability, DiagnosticBuilder};
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use syntax::ast;
use syntax::attr;
use syntax::feature_gate;
@ -93,7 +93,7 @@ impl LintLevelSets {
// If `level` is none then we actually assume the default level for this
// lint.
let mut level = level.unwrap_or_else(|| lint.default_level(sess));
let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition()));
// If we're about to issue a warning, check at the last minute for any
// directives against the warnings "lint". If, for example, there's an
@ -566,19 +566,3 @@ impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {
})
}
}
impl<HCX> HashStable<HCX> for LintId {
#[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
self.lint_name_raw().hash_stable(hcx, hasher);
}
}
impl<HCX> ToStableHashKey<HCX> for LintId {
type KeyType = &'static str;
#[inline]
fn to_stable_hash_key(&self, _: &HCX) -> &'static str {
self.lint_name_raw()
}
}

View File

@ -27,19 +27,14 @@ use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
use crate::hir::intravisit;
use crate::hir;
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::lint::builtin::parser::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE};
use crate::lint::builtin::parser::INCOMPLETE_INCLUDE;
use crate::session::{Session, DiagnosticMessageId};
use crate::ty::TyCtxt;
use crate::ty::query::Providers;
use crate::util::nodemap::NodeMap;
use errors::{DiagnosticBuilder, DiagnosticId};
use std::{hash, ptr};
use syntax::ast;
use syntax::source_map::{MultiSpan, ExpnKind, DesugaringKind};
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::edition::Edition;
use syntax::symbol::{Symbol, sym};
use syntax::symbol::Symbol;
use syntax_pos::hygiene::MacroKind;
use syntax_pos::Span;
@ -47,150 +42,7 @@ pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore
check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult,
BufferedEarlyLint,};
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
/// A string identifier for the lint.
///
/// This identifies the lint in attributes and in command-line arguments.
/// In those contexts it is always lowercase, but this field is compared
/// in a way which is case-insensitive for ASCII characters. This allows
/// `declare_lint!()` invocations to follow the convention of upper-case
/// statics without repeating the name.
///
/// The name is written with underscores, e.g., "unused_imports".
/// On the command line, underscores become dashes.
pub name: &'static str,
/// Default level for the lint.
pub default_level: Level,
/// Description of the lint or the issue it detects.
///
/// e.g., "imports that are never used"
pub desc: &'static str,
/// Starting at the given edition, default to the given lint level. If this is `None`, then use
/// `default_level`.
pub edition_lint_opts: Option<(Edition, Level)>,
/// `true` if this lint is reported even inside expansions of external macros.
pub report_in_external_macro: bool,
pub future_incompatible: Option<FutureIncompatibleInfo>,
pub is_plugin: bool,
}
/// Extra information for a future incompatibility lint.
#[derive(Copy, Clone, Debug)]
pub struct FutureIncompatibleInfo {
/// e.g., a URL for an issue/PR/RFC or error code
pub reference: &'static str,
/// If this is an edition fixing lint, the edition in which
/// this lint becomes obsolete
pub edition: Option<Edition>,
}
impl Lint {
pub const fn default_fields_for_macro() -> Self {
Lint {
name: "",
default_level: Level::Forbid,
desc: "",
edition_lint_opts: None,
is_plugin: false,
report_in_external_macro: false,
future_incompatible: None,
}
}
/// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`.
pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self {
match lint_id {
BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT,
BufferedEarlyLintId::MetaVariableMisuse => META_VARIABLE_MISUSE,
BufferedEarlyLintId::IncompleteInclude => INCOMPLETE_INCLUDE,
}
}
/// Gets the lint's name, with ASCII letters converted to lowercase.
pub fn name_lower(&self) -> String {
self.name.to_ascii_lowercase()
}
pub fn default_level(&self, session: &Session) -> Level {
self.edition_lint_opts
.filter(|(e, _)| *e <= session.edition())
.map(|(_, l)| l)
.unwrap_or(self.default_level)
}
}
/// Declares a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
declare_lint!(
$vis $NAME, $Level, $desc,
);
);
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
$(@future_incompatible = $fi:expr;)? $($v:ident),*) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: None,
is_plugin: false,
$($v: true,)*
$(future_incompatible: Some($fi),)*
..$crate::lint::Lint::default_fields_for_macro()
};
);
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
$lint_edition: expr => $edition_level: ident
) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)),
report_in_external_macro: false,
is_plugin: false,
};
);
}
#[macro_export]
macro_rules! declare_tool_lint {
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
) => (
declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
report_in_external_macro: $rep:expr
) => (
declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
$external:expr
) => (
$(#[$attr])*
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: &concat!(stringify!($tool), "::", stringify!($NAME)),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: None,
report_in_external_macro: $external,
future_incompatible: None,
is_plugin: true,
};
);
}
pub use rustc_session::lint::{Lint, LintId, Level, FutureIncompatibleInfo};
/// Declares a static `LintArray` and return it as an expression.
#[macro_export]
@ -502,86 +354,6 @@ pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync +
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
+ sync::Sync + 'static>;
/// Identifies a lint known to the compiler.
#[derive(Clone, Copy, Debug)]
pub struct LintId {
// Identity is based on pointer equality of this field.
lint: &'static Lint,
}
impl PartialEq for LintId {
fn eq(&self, other: &LintId) -> bool {
ptr::eq(self.lint, other.lint)
}
}
impl Eq for LintId { }
impl hash::Hash for LintId {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
let ptr = self.lint as *const Lint;
ptr.hash(state);
}
}
impl LintId {
/// Gets the `LintId` for a `Lint`.
pub fn of(lint: &'static Lint) -> LintId {
LintId {
lint,
}
}
pub fn lint_name_raw(&self) -> &'static str {
self.lint.name
}
/// Gets the name of the lint.
pub fn to_string(&self) -> String {
self.lint.name_lower()
}
}
/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, HashStable)]
pub enum Level {
Allow, Warn, Deny, Forbid,
}
impl Level {
/// Converts a level to a lower-case string.
pub fn as_str(self) -> &'static str {
match self {
Allow => "allow",
Warn => "warn",
Deny => "deny",
Forbid => "forbid",
}
}
/// Converts a lower-case string to a level.
pub fn from_str(x: &str) -> Option<Level> {
match x {
"allow" => Some(Allow),
"warn" => Some(Warn),
"deny" => Some(Deny),
"forbid" => Some(Forbid),
_ => None,
}
}
/// Converts a symbol to a level.
pub fn from_symbol(x: Symbol) -> Option<Level> {
match x {
sym::allow => Some(Allow),
sym::warn => Some(Warn),
sym::deny => Some(Deny),
sym::forbid => Some(Forbid),
_ => None,
}
}
}
/// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq, HashStable)]
pub enum LintSource {

View File

@ -20,6 +20,7 @@ use rustc_target::spec::Target;
use rustc_data_structures::sync::{self, MetadataRef};
use rustc_macros::HashStable;
pub use rustc_session::utils::NativeLibraryKind;
pub use self::NativeLibraryKind::*;
// lonely orphan structs and enums looking for a better home
@ -94,21 +95,6 @@ pub enum LinkagePreference {
RequireStatic,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
RustcEncodable, RustcDecodable, HashStable)]
pub enum NativeLibraryKind {
/// native static library (.a archive)
NativeStatic,
/// native static library, which doesn't get bundled into .rlibs
NativeStaticNobundle,
/// macOS-specific
NativeFramework,
/// Windows dynamic library without import library.
NativeRawDylib,
/// default way to specify a dynamic library
NativeUnknown,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct NativeLibrary {
pub kind: NativeLibraryKind,

View File

@ -90,6 +90,13 @@ macro_rules! throw_exhaust {
($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) };
}
#[macro_export]
macro_rules! throw_machine_stop {
($($tt:tt)*) => {
return Err($crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)).into())
};
}
mod error;
mod value;
mod allocation;

View File

@ -88,15 +88,7 @@ pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) {
what);
}
// Hack up our own formatting for the duration to make it easier for scripts
// to parse (always use the same number of decimal places and the same unit).
pub fn duration_to_secs_str(dur: Duration) -> String {
const NANOS_PER_SEC: f64 = 1_000_000_000.0;
let secs = dur.as_secs() as f64 +
dur.subsec_nanos() as f64 / NANOS_PER_SEC;
format!("{:.3}", secs)
}
pub use rustc_session::utils::duration_to_secs_str;
pub fn to_readable_str(mut val: usize) -> String {
let mut groups = vec![];

View File

@ -10,7 +10,7 @@ use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinShare
use rustc_codegen_ssa::traits::*;
use errors::{FatalError, Handler};
use rustc::dep_graph::WorkProduct;
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::middle::exported_symbols::SymbolExportLevel;
use rustc::session::config::{self, Lto};

View File

@ -167,7 +167,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
let asm_comments = sess.asm_comments();
let relax_elf_relocations = sess.target.target.options.relax_elf_relocations;
Arc::new(move || {
let tm = unsafe {
llvm::LLVMRustCreateTargetMachine(
@ -183,6 +183,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
singlethread,
asm_comments,
emit_stack_size_section,
relax_elf_relocations,
)
};

View File

@ -442,32 +442,11 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
let is_left = name == "rotate_left";
let val = args[0].immediate();
let raw_shift = args[1].immediate();
if llvm_util::get_major_version() >= 7 {
// rotate = funnel shift with first two args the same
let llvm_name = &format!("llvm.fsh{}.i{}",
if is_left { 'l' } else { 'r' }, width);
let llfn = self.get_intrinsic(llvm_name);
self.call(llfn, &[val, val, raw_shift], None)
} else {
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
let width = self.const_uint(
self.type_ix(width),
width,
);
let shift = self.urem(raw_shift, width);
let width_minus_raw_shift = self.sub(width, raw_shift);
let inv_shift = self.urem(width_minus_raw_shift, width);
let shift1 = self.shl(
val,
if is_left { shift } else { inv_shift },
);
let shift2 = self.lshr(
val,
if !is_left { shift } else { inv_shift },
);
self.or(shift1, shift2)
}
// rotate = funnel shift with first two args the same
let llvm_name = &format!("llvm.fsh{}.i{}",
if is_left { 'l' } else { 'r' }, width);
let llfn = self.get_intrinsic(llvm_name);
self.call(llfn, &[val, val, raw_shift], None)
},
"saturating_add" | "saturating_sub" => {
let is_add = name == "saturating_add";

View File

@ -43,6 +43,7 @@ extern crate smallvec;
extern crate syntax;
extern crate syntax_pos;
extern crate rustc_errors as errors;
extern crate rustc_session;
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, FatLTOInput};

View File

@ -1702,7 +1702,8 @@ extern "C" {
TrapUnreachable: bool,
Singlethread: bool,
AsmComments: bool,
EmitStackSizeSection: bool)
EmitStackSizeSection: bool,
RelaxELFRelocations: bool)
-> Option<&'static mut TargetMachine>;
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,

View File

@ -32,3 +32,4 @@ rustc_incremental = { path = "../librustc_incremental" }
rustc_index = { path = "../librustc_index" }
rustc_target = { path = "../librustc_target" }
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }

View File

@ -398,7 +398,8 @@ impl<'a> Linker for GccLinker<'a> {
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
// Symbol visibility in object files typically takes care of this.
if crate_type == CrateType::Executable {
if crate_type == CrateType::Executable &&
self.sess.target.target.options.override_export_symbols.is_none() {
return;
}

View File

@ -10,7 +10,7 @@ use crate::traits::*;
use rustc_incremental::{copy_cgu_workproducts_to_incr_comp_cache_dir,
in_incr_comp_dir, in_incr_comp_dir_sess};
use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind};
use rustc::dep_graph::cgu_reuse_tracker::CguReuseTracker;
use rustc_session::cgu_reuse_tracker::CguReuseTracker;
use rustc::middle::cstore::EncodedMetadata;
use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Lto,
Sanitizer, SwitchWithOptPath};
@ -1752,7 +1752,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
}
};
sess.cgu_reuse_tracker.check_expected_reuse(sess);
sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic());
sess.abort_if_errors();

View File

@ -25,8 +25,8 @@ use crate::mir::operand::OperandValue;
use crate::mir::place::PlaceRef;
use crate::traits::*;
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
use rustc::hir;
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::lang_items::StartFnLangItem;

View File

@ -1,4 +1,4 @@
use jobserver_crate::Client;
pub use jobserver_crate::Client;
use lazy_static::lazy_static;
lazy_static! {

View File

@ -828,7 +828,7 @@ Available lint options:
fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> {
// The sort doesn't case-fold but it's doubtful we care.
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name));
lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess.edition()), x.name));
lints
}

View File

@ -19,3 +19,4 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
rustc_fs_util = { path = "../librustc_fs_util" }
rustc_session = { path = "../librustc_session" }

View File

@ -22,7 +22,7 @@
//! was re-used.
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::dep_graph::cgu_reuse_tracker::*;
use rustc_session::cgu_reuse_tracker::*;
use rustc::mir::mono::CodegenUnitNameBuilder;
use rustc::ty::TyCtxt;
use std::collections::BTreeSet;

View File

@ -439,8 +439,7 @@ fn configure_and_expand_inner<'a>(
sess.parse_sess.buffered_lints.with_lock(|buffered_lints| {
info!("{} parse sess buffered_lints", buffered_lints.len());
for BufferedEarlyLint{id, span, msg, lint_id} in buffered_lints.drain(..) {
let lint = lint::Lint::from_parser_lint_id(lint_id);
resolver.lint_buffer().buffer_lint(lint, id, span, &msg);
resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg);
}
});

View File

@ -18,3 +18,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
rustc_feature = { path = "../librustc_feature" }
rustc_index = { path = "../librustc_index" }
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }

View File

@ -21,6 +21,8 @@
#[macro_use]
extern crate rustc;
#[macro_use]
extern crate rustc_session;
mod array_into_iter;
mod nonstandard_style;

View File

@ -1065,13 +1065,16 @@ where
variant_index: VariantIdx,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
let variant_scalar = Scalar::from_u32(variant_index.as_u32()).into();
// Layout computation excludes uninhabited variants from consideration
// therefore there's no way to represent those variants in the given layout.
if dest.layout.for_variant(self, variant_index).abi.is_uninhabited() {
throw_ub!(Unreachable);
}
match dest.layout.variants {
layout::Variants::Single { index } => {
if index != variant_index {
throw_ub!(InvalidDiscriminant(variant_scalar));
}
assert_eq!(index, variant_index);
}
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
@ -1079,9 +1082,9 @@ where
discr_index,
..
} => {
if !dest.layout.ty.variant_range(*self.tcx).unwrap().contains(&variant_index) {
throw_ub!(InvalidDiscriminant(variant_scalar));
}
// No need to validate that the discriminant here because the
// `TyLayout::for_variant()` call earlier already checks the variant is valid.
let discr_val =
dest.layout.ty.discriminant_for_variant(*self.tcx, variant_index).unwrap().val;
@ -1104,9 +1107,9 @@ where
discr_index,
..
} => {
if !variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len() {
throw_ub!(InvalidDiscriminant(variant_scalar));
}
// No need to validate that the discriminant here because the
// `TyLayout::for_variant()` call earlier already checks the variant is valid.
if variant_index != dataful_variant {
let variants_start = niche_variants.start().as_u32();
let variant_index_relative = variant_index.as_u32()

View File

@ -1325,7 +1325,7 @@ impl<'a> Parser<'a> {
let (variants, _) = self.parse_delim_comma_seq(
token::Brace,
|p| p.parse_enum_item(),
|p| p.parse_enum_variant(),
).map_err(|e| {
self.recover_stmt();
e
@ -1337,7 +1337,7 @@ impl<'a> Parser<'a> {
Ok((id, ItemKind::Enum(enum_definition, generics), None))
}
fn parse_enum_item(&mut self) -> PResult<'a, Option<Variant>> {
fn parse_enum_variant(&mut self) -> PResult<'a, Option<Variant>> {
let variant_attrs = self.parse_outer_attributes()?;
let vlo = self.token.span;

View File

@ -4,7 +4,7 @@ use errors::{PResult, Applicability};
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
use syntax::ast::{self, Attribute, AttrKind, Ident, MacArgs, MetaItem, MetaItemKind};
use syntax::attr::mk_name_value_item_str;
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::early_buffered_lints::ILL_FORMED_ATTRIBUTE_INPUT;
use syntax::sess::ParseSess;
use syntax_pos::{Symbol, sym};
@ -93,7 +93,7 @@ pub fn check_builtin_attribute(
}
if should_warn(name) {
sess.buffer_lint(
BufferedEarlyLintId::IllFormedAttributeInput,
&ILL_FORMED_ATTRIBUTE_INPUT,
meta.span,
ast::CRATE_NODE_ID,
&msg,

View File

@ -0,0 +1,21 @@
[package]
authors = ["The Rust Project Developers"]
name = "rustc_session"
version = "0.0.0"
edition = "2018"
[lib]
name = "rustc_session"
path = "lib.rs"
[dependencies]
log = "0.4"
rustc_errors = { path = "../librustc_errors" }
rustc_feature = { path = "../librustc_feature" }
rustc_target = { path = "../librustc_target" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_data_structures = { path = "../librustc_data_structures" }
syntax_pos = { path = "../libsyntax_pos" }
rustc_index = { path = "../librustc_index" }
rustc_fs_util = { path = "../librustc_fs_util" }
num_cpus = "1.0"

View File

@ -2,10 +2,10 @@
//! compilation. This is used for incremental compilation tests and debug
//! output.
use crate::session::Session;
use rustc_data_structures::fx::FxHashMap;
use std::sync::{Arc, Mutex};
use syntax_pos::Span;
use log::debug;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub enum CguReuse {
@ -94,7 +94,7 @@ impl CguReuseTracker {
}
}
pub fn check_expected_reuse(&self, sess: &Session) {
pub fn check_expected_reuse(&self, diag: &rustc_errors::Handler) {
if let Some(ref data) = self.data {
let data = data.lock().unwrap();
@ -120,14 +120,14 @@ impl CguReuseTracker {
actual_reuse,
at_least,
expected_reuse);
sess.span_err(error_span.0, &msg);
diag.span_err(error_span.0, &msg);
}
} else {
let msg = format!("CGU-reuse for `{}` (mangled: `{}`) was \
not recorded",
cgu_user_name,
cgu_name);
sess.span_fatal(error_span.0, &msg);
diag.span_fatal(error_span.0, &msg).raise();
}
}
}

View File

@ -2,24 +2,24 @@
//! command-line options.
use crate::lint;
use crate::middle::cstore;
use crate::session::{early_error, early_warn, Session};
use crate::session::search_paths::SearchPath;
use crate::utils::NativeLibraryKind;
use crate::{early_error, early_warn, Session};
use crate::search_paths::SearchPath;
use rustc_data_structures::fx::FxHashSet;
use rustc_feature::UnstableFeatures;
use rustc_data_structures::impl_stable_hash_via_hash;
use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
use rustc_target::spec::{Target, TargetTriple};
use syntax;
use syntax::ast;
use syntax::source_map::{FileName, FilePathMapping};
use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
use syntax::symbol::{sym, Symbol};
use syntax_pos::source_map::{FileName, FilePathMapping};
use syntax_pos::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
use syntax_pos::symbol::{sym, Symbol};
use rustc_feature::UnstableFeatures;
use crate::parse::CrateConfig;
use errors::emitter::HumanReadableErrorType;
use errors::{ColorConfig, FatalError, Handler};
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, FatalError, Handler};
use getopts;
@ -348,7 +348,7 @@ macro_rules! hash_option {
($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => ({
if $sub_hashes.insert(stringify!($opt_name),
$opt_expr as &dyn dep_tracking::DepTrackingHash).is_some() {
bug!("duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name))
panic!("duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name))
}
});
}
@ -415,7 +415,7 @@ top_level_options!(
describe_lints: bool [UNTRACKED],
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
libs: Vec<(String, Option<String>, Option<NativeLibraryKind>)> [TRACKED],
maybe_sysroot: Option<PathBuf> [UNTRACKED],
target_triple: TargetTriple [TRACKED],
@ -701,7 +701,7 @@ pub enum EntryFnType {
impl_stable_hash_via_hash!(EntryFnType);
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, HashStable)]
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
pub enum CrateType {
Executable,
Dylib,
@ -711,6 +711,8 @@ pub enum CrateType {
ProcMacro,
}
impl_stable_hash_via_hash!(CrateType);
#[derive(Clone, Hash)]
pub enum Passes {
Some(Vec<String>),
@ -781,7 +783,7 @@ macro_rules! options {
value, $outputname,
key, type_desc))
}
(None, None) => bug!()
(None, None) => panic!()
}
}
found = true;
@ -1535,7 +1537,7 @@ pub const fn default_lib_output() -> CrateType {
CrateType::Rlib
}
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
pub fn default_configuration(sess: &Session) -> CrateConfig {
let end = &sess.target.target.target_endian;
let arch = &sess.target.target.arch;
let wordsz = &sess.target.target.target_pointer_width;
@ -1607,13 +1609,13 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
/// but the symbol interner is not yet set up then, so we must convert it later.
pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> ast::CrateConfig {
pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig {
cfg.into_iter()
.map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b))))
.collect()
}
pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> ast::CrateConfig {
pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
// Combine the configuration requested by the session (command line) with
// some default and generated configuration items.
let default_cfg = default_configuration(sess);
@ -2379,7 +2381,7 @@ fn select_debuginfo(
fn parse_libs(
matches: &getopts::Matches,
error_format: ErrorOutputType,
) -> Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> {
) -> Vec<(String, Option<String>, Option<NativeLibraryKind>)> {
matches
.opt_strs("l")
.into_iter()
@ -2390,10 +2392,12 @@ fn parse_libs(
let kind = parts.next().unwrap();
let (name, kind) = match (parts.next(), kind) {
(None, name) => (name, None),
(Some(name), "dylib") => (name, Some(cstore::NativeUnknown)),
(Some(name), "framework") => (name, Some(cstore::NativeFramework)),
(Some(name), "static") => (name, Some(cstore::NativeStatic)),
(Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)),
(Some(name), "dylib") => (name, Some(NativeLibraryKind::NativeUnknown)),
(Some(name), "framework") => (name, Some(NativeLibraryKind::NativeFramework)),
(Some(name), "static") => (name, Some(NativeLibraryKind::NativeStatic)),
(Some(name), "static-nobundle") => {
(name, Some(NativeLibraryKind::NativeStaticNobundle))
}
(_, s) => {
early_error(
error_format,
@ -2405,7 +2409,8 @@ fn parse_libs(
);
}
};
if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() {
if kind == Some(NativeLibraryKind::NativeStaticNobundle) &&
!nightly_options::is_nightly_build() {
early_error(
error_format,
&format!(
@ -2716,7 +2721,7 @@ pub mod nightly_options {
use getopts;
use rustc_feature::UnstableFeatures;
use super::{ErrorOutputType, OptionStability, RustcOptGroup};
use crate::session::early_error;
use crate::early_error;
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
is_nightly_build()
@ -2855,7 +2860,7 @@ impl PpMode {
/// how the hash should be calculated when adding a new command-line argument.
mod dep_tracking {
use crate::lint;
use crate::middle::cstore;
use crate::utils::NativeLibraryKind;
use std::collections::BTreeMap;
use std::hash::Hash;
use std::path::PathBuf;
@ -2863,9 +2868,9 @@ mod dep_tracking {
use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
SymbolManglingVersion};
use rustc_feature::UnstableFeatures;
use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
use syntax::edition::Edition;
use syntax_pos::edition::Edition;
use rustc_feature::UnstableFeatures;
pub trait DepTrackingHash {
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
@ -2913,7 +2918,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
impl_dep_tracking_hash_via_hash!(Option<cstore::NativeLibraryKind>);
impl_dep_tracking_hash_via_hash!(Option<NativeLibraryKind>);
impl_dep_tracking_hash_via_hash!(CrateType);
impl_dep_tracking_hash_via_hash!(MergeFunctions);
impl_dep_tracking_hash_via_hash!(PanicStrategy);
@ -2924,7 +2929,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(DebugInfo);
impl_dep_tracking_hash_via_hash!(UnstableFeatures);
impl_dep_tracking_hash_via_hash!(OutputTypes);
impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
impl_dep_tracking_hash_via_hash!(NativeLibraryKind);
impl_dep_tracking_hash_via_hash!(Sanitizer);
impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
impl_dep_tracking_hash_via_hash!(TargetTriple);
@ -2940,7 +2945,7 @@ mod dep_tracking {
impl_dep_tracking_hash_for_sortable_vec_of!((
String,
Option<String>,
Option<cstore::NativeLibraryKind>
Option<NativeLibraryKind>
));
impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
impl_dep_tracking_hash_for_sortable_vec_of!(Sanitizer);

View File

@ -7,8 +7,9 @@ use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use crate::session::search_paths::{SearchPath, PathKind};
use crate::search_paths::{SearchPath, PathKind};
use rustc_fs_util::fix_windows_verbatim_for_gcc;
use log::debug;
#[derive(Copy, Clone)]
pub enum FileMatch {
@ -124,7 +125,7 @@ pub fn get_or_default_sysroot() -> PathBuf {
// gcc chokes on verbatim paths which fs::canonicalize generates
// so we try to avoid those kinds of paths.
Ok(canon) => Some(fix_windows_verbatim_for_gcc(&canon)),
Err(e) => bug!("failed to get realpath: {}", e),
Err(e) => panic!("failed to get realpath: {}", e),
}
})
}
@ -133,7 +134,7 @@ pub fn get_or_default_sysroot() -> PathBuf {
Ok(exe) => {
match canonicalize(Some(exe)) {
Some(mut p) => { p.pop(); p.pop(); p },
None => bug!("can't determine value for sysroot")
None => panic!("can't determine value for sysroot")
}
}
Err(ref e) => panic!(format!("failed to get current_exe: {}", e))

View File

@ -0,0 +1,21 @@
#![feature(test)]
// Use the test crate here so we depend on getopts through it. This allow tools to link to both
// librustc_session and libtest.
extern crate test as _;
extern crate getopts;
pub mod cgu_reuse_tracker;
pub mod utils;
#[macro_use]
pub mod lint;
pub mod node_id;
pub mod parse;
mod code_stats;
pub mod config;
pub mod filesearch;
pub mod search_paths;
mod session;
pub use session::*;

View File

@ -0,0 +1,254 @@
use syntax_pos::{MultiSpan, Symbol, sym};
use syntax_pos::edition::Edition;
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
pub use self::Level::*;
use crate::node_id::NodeId;
/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Level {
Allow, Warn, Deny, Forbid,
}
rustc_data_structures::impl_stable_hash_via_hash!(Level);
impl Level {
/// Converts a level to a lower-case string.
pub fn as_str(self) -> &'static str {
match self {
Level::Allow => "allow",
Level::Warn => "warn",
Level::Deny => "deny",
Level::Forbid => "forbid",
}
}
/// Converts a lower-case string to a level.
pub fn from_str(x: &str) -> Option<Level> {
match x {
"allow" => Some(Level::Allow),
"warn" => Some(Level::Warn),
"deny" => Some(Level::Deny),
"forbid" => Some(Level::Forbid),
_ => None,
}
}
/// Converts a symbol to a level.
pub fn from_symbol(x: Symbol) -> Option<Level> {
match x {
sym::allow => Some(Level::Allow),
sym::warn => Some(Level::Warn),
sym::deny => Some(Level::Deny),
sym::forbid => Some(Level::Forbid),
_ => None,
}
}
}
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
/// A string identifier for the lint.
///
/// This identifies the lint in attributes and in command-line arguments.
/// In those contexts it is always lowercase, but this field is compared
/// in a way which is case-insensitive for ASCII characters. This allows
/// `declare_lint!()` invocations to follow the convention of upper-case
/// statics without repeating the name.
///
/// The name is written with underscores, e.g., "unused_imports".
/// On the command line, underscores become dashes.
pub name: &'static str,
/// Default level for the lint.
pub default_level: Level,
/// Description of the lint or the issue it detects.
///
/// e.g., "imports that are never used"
pub desc: &'static str,
/// Starting at the given edition, default to the given lint level. If this is `None`, then use
/// `default_level`.
pub edition_lint_opts: Option<(Edition, Level)>,
/// `true` if this lint is reported even inside expansions of external macros.
pub report_in_external_macro: bool,
pub future_incompatible: Option<FutureIncompatibleInfo>,
pub is_plugin: bool,
}
/// Extra information for a future incompatibility lint.
#[derive(Copy, Clone, Debug)]
pub struct FutureIncompatibleInfo {
/// e.g., a URL for an issue/PR/RFC or error code
pub reference: &'static str,
/// If this is an edition fixing lint, the edition in which
/// this lint becomes obsolete
pub edition: Option<Edition>,
}
impl Lint {
pub const fn default_fields_for_macro() -> Self {
Lint {
name: "",
default_level: Level::Forbid,
desc: "",
edition_lint_opts: None,
is_plugin: false,
report_in_external_macro: false,
future_incompatible: None,
}
}
/// Gets the lint's name, with ASCII letters converted to lowercase.
pub fn name_lower(&self) -> String {
self.name.to_ascii_lowercase()
}
pub fn default_level(&self, edition: Edition) -> Level {
self.edition_lint_opts
.filter(|(e, _)| *e <= edition)
.map(|(_, l)| l)
.unwrap_or(self.default_level)
}
}
/// Identifies a lint known to the compiler.
#[derive(Clone, Copy, Debug)]
pub struct LintId {
// Identity is based on pointer equality of this field.
pub lint: &'static Lint,
}
impl PartialEq for LintId {
fn eq(&self, other: &LintId) -> bool {
std::ptr::eq(self.lint, other.lint)
}
}
impl Eq for LintId { }
impl std::hash::Hash for LintId {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let ptr = self.lint as *const Lint;
ptr.hash(state);
}
}
impl LintId {
/// Gets the `LintId` for a `Lint`.
pub fn of(lint: &'static Lint) -> LintId {
LintId {
lint,
}
}
pub fn lint_name_raw(&self) -> &'static str {
self.lint.name
}
/// Gets the name of the lint.
pub fn to_string(&self) -> String {
self.lint.name_lower()
}
}
impl<HCX> HashStable<HCX> for LintId {
#[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
self.lint_name_raw().hash_stable(hcx, hasher);
}
}
impl<HCX> ToStableHashKey<HCX> for LintId {
type KeyType = &'static str;
#[inline]
fn to_stable_hash_key(&self, _: &HCX) -> &'static str {
self.lint_name_raw()
}
}
/// Stores buffered lint info which can later be passed to `librustc`.
pub struct BufferedEarlyLint {
/// The span of code that we are linting on.
pub span: MultiSpan,
/// The lint message.
pub msg: String,
/// The `NodeId` of the AST node that generated the lint.
pub id: NodeId,
/// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
pub lint_id: &'static Lint,
}
/// Declares a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint {
($vis: vis $NAME: ident, $Level: ident, $desc: expr) => (
$crate::declare_lint!(
$vis $NAME, $Level, $desc,
);
);
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
$(@future_incompatible = $fi:expr;)? $($v:ident),*) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: None,
is_plugin: false,
$($v: true,)*
$(future_incompatible: Some($fi),)*
..$crate::lint::Lint::default_fields_for_macro()
};
);
($vis: vis $NAME: ident, $Level: ident, $desc: expr,
$lint_edition: expr => $edition_level: ident
) => (
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: stringify!($NAME),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)),
report_in_external_macro: false,
is_plugin: false,
};
);
}
#[macro_export]
macro_rules! declare_tool_lint {
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
) => (
$crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
report_in_external_macro: $rep:expr
) => (
$crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
);
(
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
$external:expr
) => (
$(#[$attr])*
$vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
name: &concat!(stringify!($tool), "::", stringify!($NAME)),
default_level: $crate::lint::$Level,
desc: $desc,
edition_lint_opts: None,
report_in_external_macro: $external,
future_incompatible: None,
is_plugin: true,
};
);
}

View File

@ -0,0 +1,39 @@
use std::fmt;
use rustc_index::vec::Idx;
use rustc_serialize::{Encoder, Decoder};
use syntax_pos::ExpnId;
rustc_index::newtype_index! {
pub struct NodeId {
ENCODABLE = custom
DEBUG_FORMAT = "NodeId({})"
}
}
impl NodeId {
pub fn placeholder_from_expn_id(expn_id: ExpnId) -> Self {
NodeId::from_u32(expn_id.as_u32())
}
pub fn placeholder_to_expn_id(self) -> ExpnId {
ExpnId::from_u32(self.as_u32())
}
}
impl fmt::Display for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.as_u32(), f)
}
}
impl rustc_serialize::UseSpecializedEncodable for NodeId {
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u32(self.as_u32())
}
}
impl rustc_serialize::UseSpecializedDecodable for NodeId {
fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
d.read_u32().map(NodeId::from_u32)
}
}

View File

@ -1,10 +1,10 @@
//! Contains `ParseSess` which holds state living beyond what one `Parser` might.
//! It also serves as an input to the parser itself.
use crate::ast::{CrateConfig, NodeId};
use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
use crate::node_id::NodeId;
use crate::lint::BufferedEarlyLint;
use errors::{Applicability, emitter::SilentEmitter, Handler, ColorConfig, DiagnosticBuilder};
use rustc_errors::{Applicability, emitter::SilentEmitter, Handler, ColorConfig, DiagnosticBuilder};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_data_structures::sync::{Lrc, Lock, Once};
use rustc_feature::UnstableFeatures;
@ -16,6 +16,10 @@ use syntax_pos::source_map::{SourceMap, FilePathMapping};
use std::path::PathBuf;
use std::str;
/// The set of keys (and, optionally, values) that define the compilation
/// environment of the crate, used to drive conditional compilation.
pub type CrateConfig = FxHashSet<(Symbol, Option<Symbol>)>;
/// Collected spans during parsing for places where a certain feature was
/// used and should be feature gated accordingly in `check_crate`.
#[derive(Default)]
@ -137,7 +141,7 @@ impl ParseSess {
pub fn buffer_lint(
&self,
lint_id: BufferedEarlyLintId,
lint_id: &'static crate::lint::Lint,
span: impl Into<MultiSpan>,
id: NodeId,
msg: &str,

View File

@ -1,6 +1,6 @@
use std::path::{Path, PathBuf};
use crate::session::{early_error, config};
use crate::session::filesearch::make_target_lib_path;
use crate::{early_error, config};
use crate::filesearch::make_target_lib_path;
#[derive(Clone, Debug)]
pub struct SearchPath {
@ -9,7 +9,7 @@ pub struct SearchPath {
pub files: Vec<PathBuf>,
}
#[derive(PartialEq, Clone, Copy, Debug, HashStable)]
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)]
pub enum PathKind {
Native,
Crate,
@ -19,6 +19,8 @@ pub enum PathKind {
All,
}
rustc_data_structures::impl_stable_hash_via_hash!(PathKind);
impl PathKind {
pub fn matches(&self, kind: PathKind) -> bool {
match (self, kind) {

View File

@ -1,36 +1,38 @@
pub use self::code_stats::{DataTypeKind, SizeKind, FieldInfo, VariantInfo};
use self::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, SizeKind, FieldInfo, VariantInfo};
use crate::code_stats::CodeStats;
use crate::dep_graph::cgu_reuse_tracker::CguReuseTracker;
use crate::cgu_reuse_tracker::CguReuseTracker;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use crate::lint;
use crate::session::config::{OutputType, PrintRequest, Sanitizer, SwitchWithOptPath};
use crate::session::search_paths::{PathKind, SearchPath};
use crate::util::nodemap::{FxHashMap, FxHashSet};
use crate::util::common::{duration_to_secs_str, ErrorReported};
use crate::filesearch;
use crate::config::{self, OutputType, PrintRequest, Sanitizer, SwitchWithOptPath};
use crate::search_paths::{PathKind, SearchPath};
use crate::utils::duration_to_secs_str;
use rustc_errors::ErrorReported;
use rustc_data_structures::base_n;
use rustc_data_structures::sync::{
self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering,
Ordering::SeqCst,
};
use rustc_data_structures::impl_stable_hash_via_hash;
use errors::{DiagnosticBuilder, DiagnosticId, Applicability};
use errors::emitter::{Emitter, EmitterWriter};
use errors::emitter::HumanReadableErrorType;
use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
use syntax::edition::Edition;
use errors::json::JsonEmitter;
use syntax::source_map;
use syntax::sess::ParseSess;
use rustc_errors::{DiagnosticBuilder, DiagnosticId, Applicability};
use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
use syntax_pos::edition::Edition;
use rustc_errors::json::JsonEmitter;
use syntax_pos::source_map;
use crate::parse::ParseSess;
use syntax_pos::{MultiSpan, Span};
use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
use rustc_data_structures::flock;
use rustc_data_structures::jobserver;
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
use ::jobserver::Client;
use std;
use std::cell::{self, RefCell};
@ -42,11 +44,6 @@ use std::path::PathBuf;
use std::time::Duration;
use std::sync::Arc;
mod code_stats;
pub mod config;
pub mod filesearch;
pub mod search_paths;
pub struct OptimizationFuel {
/// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`.
remaining: u64,
@ -335,7 +332,7 @@ impl Session {
self.diagnostic().span_note_without_error(sp, msg)
}
pub fn diagnostic(&self) -> &errors::Handler {
pub fn diagnostic(&self) -> &rustc_errors::Handler {
&self.parse_sess.span_diagnostic
}
@ -680,7 +677,7 @@ impl Session {
if let IncrCompSession::NotInitialized = *incr_comp_session {
} else {
bug!(
panic!(
"Trying to initialize IncrCompSession `{:?}`",
*incr_comp_session
)
@ -698,7 +695,7 @@ impl Session {
if let IncrCompSession::Active { .. } = *incr_comp_session {
} else {
bug!(
panic!(
"trying to finalize `IncrCompSession` `{:?}`",
*incr_comp_session
);
@ -719,7 +716,7 @@ impl Session {
..
} => session_directory.clone(),
IncrCompSession::InvalidBecauseOfErrors { .. } => return,
_ => bug!(
_ => panic!(
"trying to invalidate `IncrCompSession` `{:?}`",
*incr_comp_session
),
@ -736,7 +733,7 @@ impl Session {
cell::Ref::map(
incr_comp_session,
|incr_comp_session| match *incr_comp_session {
IncrCompSession::NotInitialized => bug!(
IncrCompSession::NotInitialized => panic!(
"trying to get session directory from `IncrCompSession`: {:?}",
*incr_comp_session,
),
@ -916,7 +913,7 @@ impl Session {
pub fn build_session(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
registry: errors::registry::Registry,
registry: rustc_errors::registry::Registry,
) -> Session {
let file_path_mapping = sopts.file_path_mapping();
@ -932,7 +929,7 @@ pub fn build_session(
fn default_emitter(
sopts: &config::Options,
registry: errors::registry::Registry,
registry: rustc_errors::registry::Registry,
source_map: &Lrc<source_map::SourceMap>,
emitter_dest: Option<Box<dyn Write + Send>>,
) -> Box<dyn Emitter + sync::Send> {
@ -1001,7 +998,7 @@ pub enum DiagnosticOutput {
pub fn build_session_with_source_map(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
registry: errors::registry::Registry,
registry: rustc_errors::registry::Registry,
source_map: Lrc<source_map::SourceMap>,
diagnostics_output: DiagnosticOutput,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
@ -1032,9 +1029,9 @@ pub fn build_session_with_source_map(
};
let emitter = default_emitter(&sopts, registry, &source_map, write_dest);
let diagnostic_handler = errors::Handler::with_emitter_and_flags(
let diagnostic_handler = rustc_errors::Handler::with_emitter_and_flags(
emitter,
errors::HandlerFlags {
rustc_errors::HandlerFlags {
can_emit_warnings,
treat_err_as_bug,
report_delayed_bugs,
@ -1056,7 +1053,7 @@ pub fn build_session_with_source_map(
fn build_session_(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
span_diagnostic: errors::Handler,
span_diagnostic: rustc_errors::Handler,
source_map: Lrc<source_map::SourceMap>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
) -> Session {
@ -1281,9 +1278,9 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
config::ErrorOutputType::Json { pretty, json_rendered } =>
Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
};
let handler = errors::Handler::with_emitter(true, None, emitter);
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
handler.struct_fatal(msg).emit();
errors::FatalError.raise();
rustc_errors::FatalError.raise();
}
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
@ -1295,7 +1292,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
config::ErrorOutputType::Json { pretty, json_rendered } =>
Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
};
let handler = errors::Handler::with_emitter(true, None, emitter);
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
handler.struct_warn(msg).emit();
}

View File

@ -0,0 +1,25 @@
// Hack up our own formatting for the duration to make it easier for scripts
// to parse (always use the same number of decimal places and the same unit).
pub fn duration_to_secs_str(dur: std::time::Duration) -> String {
const NANOS_PER_SEC: f64 = 1_000_000_000.0;
let secs = dur.as_secs() as f64 +
dur.subsec_nanos() as f64 / NANOS_PER_SEC;
format!("{:.3}", secs)
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum NativeLibraryKind {
/// native static library (.a archive)
NativeStatic,
/// native static library, which doesn't get bundled into .rlibs
NativeStaticNobundle,
/// macOS-specific
NativeFramework,
/// Windows dynamic library without import library.
NativeRawDylib,
/// default way to specify a dynamic library
NativeUnknown,
}
rustc_data_structures::impl_stable_hash_via_hash!(NativeLibraryKind);

View File

@ -803,6 +803,9 @@ pub struct TargetOptions {
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
pub llvm_abiname: String,
/// Whether or not RelaxElfRelocation flag will be passed to the linker
pub relax_elf_relocations: bool,
}
impl Default for TargetOptions {
@ -890,6 +893,7 @@ impl Default for TargetOptions {
merge_functions: MergeFunctions::Aliases,
target_mcount: "mcount".to_string(),
llvm_abiname: "".to_string(),
relax_elf_relocations: false,
}
}
}
@ -1207,6 +1211,7 @@ impl Target {
key!(merge_functions, MergeFunctions)?;
key!(target_mcount);
key!(llvm_abiname);
key!(relax_elf_relocations, bool);
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
for name in array.iter().filter_map(|abi| abi.as_string()) {
@ -1426,6 +1431,7 @@ impl ToJson for Target {
target_option_val!(merge_functions);
target_option_val!(target_mcount);
target_option_val!(llvm_abiname);
target_option_val!(relax_elf_relocations);
if default.abi_blacklist != self.options.abi_blacklist {
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()

View File

@ -1,35 +1,31 @@
use std::iter;
use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
pub fn target() -> Result<Target, String> {
const PRE_LINK_ARGS: &[&str] = &[
"-Wl,--as-needed",
"-Wl,-z,noexecstack",
"-m64",
"-fuse-ld=gold",
"-nostdlib",
"-shared",
"-Wl,-e,sgx_entry",
"-Wl,-Bstatic",
"-Wl,--gc-sections",
"-Wl,-z,text",
"-Wl,-z,norelro",
"-Wl,--rosegment",
"-Wl,--no-undefined",
"-Wl,--error-unresolved-symbols",
"-Wl,--no-undefined-version",
"-Wl,-Bsymbolic",
"-Wl,--export-dynamic",
"--as-needed",
"--eh-frame-hdr",
"-z" , "noexecstack",
"-e","sgx_entry",
"-Bstatic",
"--gc-sections",
"-z","text",
"-z","norelro",
"--no-undefined",
"--error-unresolved-symbols",
"--no-undefined-version",
"-Bsymbolic",
"--export-dynamic",
// The following symbols are needed by libunwind, which is linked after
// libstd. Make sure they're included in the link.
"-Wl,-u,__rust_abort",
"-Wl,-u,__rust_c_alloc",
"-Wl,-u,__rust_c_dealloc",
"-Wl,-u,__rust_print_err",
"-Wl,-u,__rust_rwlock_rdlock",
"-Wl,-u,__rust_rwlock_unlock",
"-Wl,-u,__rust_rwlock_wrlock",
"-u","__rust_abort",
"-u","__rust_c_alloc",
"-u","__rust_c_dealloc",
"-u","__rust_print_err",
"-u","__rust_rwlock_rdlock",
"-u","__rust_rwlock_unlock",
"-u","__rust_rwlock_wrlock"
];
const EXPORT_SYMBOLS: &[&str] = &[
@ -50,18 +46,20 @@ pub fn target() -> Result<Target, String> {
dynamic_linking: false,
executables: true,
linker_is_gnu: true,
linker: Some("rust-lld".to_owned()),
max_atomic_width: Some(64),
panic_strategy: PanicStrategy::Unwind,
cpu: "x86-64".into(),
features: "+rdrnd,+rdseed".into(),
position_independent_executables: true,
pre_link_args: iter::once((
LinkerFlavor::Gcc,
LinkerFlavor::Lld(LldFlavor::Ld),
PRE_LINK_ARGS.iter().cloned().map(String::from).collect(),
))
.collect(),
post_link_objects: vec!["libunwind.a".into()],
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()),
relax_elf_relocations: true,
..Default::default()
};
Ok(Target {
@ -74,7 +72,7 @@ pub fn target() -> Result<Target, String> {
target_vendor: "fortanix".into(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(),
arch: "x86_64".into(),
linker_flavor: LinkerFlavor::Gcc,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
options: opts,
})
}

View File

@ -54,7 +54,7 @@ fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
hermit-abi = { version = "0.1", features = ['rustc-dep-of-std'] }
[target.wasm32-wasi.dependencies]
wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] }
wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false }
[features]
default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]

View File

@ -1,15 +1,11 @@
use crate::ffi::OsString;
use crate::ffi::{CStr, OsStr, OsString};
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStringExt;
use crate::os::wasi::ffi::OsStrExt;
use crate::vec;
use ::wasi::wasi_unstable as wasi;
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
}
pub unsafe fn cleanup() {
}
pub unsafe fn cleanup() {}
pub struct Args {
iter: vec::IntoIter<OsString>,
@ -18,17 +14,24 @@ pub struct Args {
/// Returns the command line arguments
pub fn args() -> Args {
let buf = wasi::args_sizes_get().and_then(|args_sizes| {
let mut buf = Vec::with_capacity(args_sizes.get_count());
wasi::args_get(args_sizes, |arg| {
let arg = OsString::from_vec(arg.to_vec());
buf.push(arg);
})?;
Ok(buf)
}).unwrap_or(vec![]);
Args {
iter: buf.into_iter(),
_dont_send_or_sync_me: PhantomData
iter: maybe_args().unwrap_or(Vec::new()).into_iter(),
_dont_send_or_sync_me: PhantomData,
}
}
fn maybe_args() -> Option<Vec<OsString>> {
unsafe {
let (argc, buf_size) = wasi::args_sizes_get().ok()?;
let mut argv = Vec::with_capacity(argc);
let mut buf = Vec::with_capacity(buf_size);
wasi::args_get(argv.as_mut_ptr(), buf.as_mut_ptr()).ok()?;
let mut ret = Vec::with_capacity(argc);
for ptr in argv {
let s = CStr::from_ptr(ptr.cast());
ret.push(OsStr::from_bytes(s.to_bytes()).to_owned());
}
Some(ret)
}
}

View File

@ -4,12 +4,10 @@
use crate::fs::{self, File, Metadata, OpenOptions};
use crate::io::{self, IoSlice, IoSliceMut};
use crate::os::wasi::ffi::OsStrExt;
use crate::path::{Path, PathBuf};
use crate::sys::fs::osstr2str;
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
use ::wasi::wasi_unstable as wasi;
/// WASI-specific extensions to [`File`].
///
/// [`File`]: ../../../../std/fs/struct.File.html
@ -49,62 +47,62 @@ pub trait FileExt {
/// Returns the current position within the file.
///
/// This corresponds to the `__wasi_fd_tell` syscall and is similar to
/// This corresponds to the `fd_tell` syscall and is similar to
/// `seek` where you offset 0 bytes from the current position.
fn tell(&self) -> io::Result<u64>;
/// Adjust the flags associated with this file.
///
/// This corresponds to the `__wasi_fd_fdstat_set_flags` syscall.
/// This corresponds to the `fd_fdstat_set_flags` syscall.
fn fdstat_set_flags(&self, flags: u16) -> io::Result<()>;
/// Adjust the rights associated with this file.
///
/// This corresponds to the `__wasi_fd_fdstat_set_rights` syscall.
/// This corresponds to the `fd_fdstat_set_rights` syscall.
fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()>;
/// Provide file advisory information on a file descriptor.
///
/// This corresponds to the `__wasi_fd_advise` syscall.
/// This corresponds to the `fd_advise` syscall.
fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()>;
/// Force the allocation of space in a file.
///
/// This corresponds to the `__wasi_fd_allocate` syscall.
/// This corresponds to the `fd_allocate` syscall.
fn allocate(&self, offset: u64, len: u64) -> io::Result<()>;
/// Create a directory.
///
/// This corresponds to the `__wasi_path_create_directory` syscall.
/// This corresponds to the `path_create_directory` syscall.
fn create_directory<P: AsRef<Path>>(&self, dir: P) -> io::Result<()>;
/// Read the contents of a symbolic link.
///
/// This corresponds to the `__wasi_path_readlink` syscall.
/// This corresponds to the `path_readlink` syscall.
fn read_link<P: AsRef<Path>>(&self, path: P) -> io::Result<PathBuf>;
/// Return the attributes of a file or directory.
///
/// This corresponds to the `__wasi_path_filestat_get` syscall.
/// This corresponds to the `path_filestat_get` syscall.
fn metadata_at<P: AsRef<Path>>(&self, lookup_flags: u32, path: P) -> io::Result<Metadata>;
/// Unlink a file.
///
/// This corresponds to the `__wasi_path_unlink_file` syscall.
/// This corresponds to the `path_unlink_file` syscall.
fn remove_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()>;
/// Remove a directory.
///
/// This corresponds to the `__wasi_path_remove_directory` syscall.
/// This corresponds to the `path_remove_directory` syscall.
fn remove_directory<P: AsRef<Path>>(&self, path: P) -> io::Result<()>;
}
// FIXME: bind __wasi_fd_fdstat_get - need to define a custom return type
// FIXME: bind __wasi_fd_readdir - can't return `ReadDir` since we only have entry name
// FIXME: bind __wasi_fd_filestat_set_times maybe? - on crates.io for unix
// FIXME: bind __wasi_path_filestat_set_times maybe? - on crates.io for unix
// FIXME: bind __wasi_poll_oneoff maybe? - probably should wait for I/O to settle
// FIXME: bind __wasi_random_get maybe? - on crates.io for unix
// FIXME: bind fd_fdstat_get - need to define a custom return type
// FIXME: bind fd_readdir - can't return `ReadDir` since we only have entry name
// FIXME: bind fd_filestat_set_times maybe? - on crates.io for unix
// FIXME: bind path_filestat_set_times maybe? - on crates.io for unix
// FIXME: bind poll_oneoff maybe? - probably should wait for I/O to settle
// FIXME: bind random_get maybe? - on crates.io for unix
impl FileExt for fs::File {
fn read_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
@ -136,9 +134,7 @@ impl FileExt for fs::File {
}
fn create_directory<P: AsRef<Path>>(&self, dir: P) -> io::Result<()> {
self.as_inner()
.fd()
.create_directory(dir.as_ref().as_os_str().as_bytes())
self.as_inner().fd().create_directory(osstr2str(dir.as_ref().as_ref())?)
}
fn read_link<P: AsRef<Path>>(&self, path: P) -> io::Result<PathBuf> {
@ -151,15 +147,11 @@ impl FileExt for fs::File {
}
fn remove_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
self.as_inner()
.fd()
.unlink_file(path.as_ref().as_os_str().as_bytes())
self.as_inner().fd().unlink_file(osstr2str(path.as_ref().as_ref())?)
}
fn remove_directory<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
self.as_inner()
.fd()
.remove_directory(path.as_ref().as_os_str().as_bytes())
self.as_inner().fd().remove_directory(osstr2str(path.as_ref().as_ref())?)
}
}
@ -167,10 +159,10 @@ impl FileExt for fs::File {
///
/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
pub trait OpenOptionsExt {
/// Pass custom `dirflags` argument to `__wasi_path_open`.
/// Pass custom `dirflags` argument to `path_open`.
///
/// This option configures the `dirflags` argument to the
/// `__wasi_path_open` syscall which `OpenOptions` will eventually call. The
/// `path_open` syscall which `OpenOptions` will eventually call. The
/// `dirflags` argument configures how the file is looked up, currently
/// primarily affecting whether symlinks are followed or not.
///
@ -188,31 +180,31 @@ pub trait OpenOptionsExt {
fn directory(&mut self, dir: bool) -> &mut Self;
/// Indicates whether `__WASI_FDFLAG_DSYNC` is passed in the `fs_flags`
/// field of `__wasi_path_open`.
/// field of `path_open`.
///
/// This option is by default `false`
fn dsync(&mut self, dsync: bool) -> &mut Self;
/// Indicates whether `__WASI_FDFLAG_NONBLOCK` is passed in the `fs_flags`
/// field of `__wasi_path_open`.
/// field of `path_open`.
///
/// This option is by default `false`
fn nonblock(&mut self, nonblock: bool) -> &mut Self;
/// Indicates whether `__WASI_FDFLAG_RSYNC` is passed in the `fs_flags`
/// field of `__wasi_path_open`.
/// field of `path_open`.
///
/// This option is by default `false`
fn rsync(&mut self, rsync: bool) -> &mut Self;
/// Indicates whether `__WASI_FDFLAG_SYNC` is passed in the `fs_flags`
/// field of `__wasi_path_open`.
/// field of `path_open`.
///
/// This option is by default `false`
fn sync(&mut self, sync: bool) -> &mut Self;
/// Indicates the value that should be passed in for the `fs_rights_base`
/// parameter of `__wasi_path_open`.
/// parameter of `path_open`.
///
/// This option defaults based on the `read` and `write` configuration of
/// this `OpenOptions` builder. If this method is called, however, the
@ -220,7 +212,7 @@ pub trait OpenOptionsExt {
fn fs_rights_base(&mut self, rights: u64) -> &mut Self;
/// Indicates the value that should be passed in for the
/// `fs_rights_inheriting` parameter of `__wasi_path_open`.
/// `fs_rights_inheriting` parameter of `path_open`.
///
/// The default for this option is the same value as what will be passed
/// for the `fs_rights_base` parameter but if this method is called then
@ -229,7 +221,7 @@ pub trait OpenOptionsExt {
/// Open a file or directory.
///
/// This corresponds to the `__wasi_path_open` syscall.
/// This corresponds to the `path_open` syscall.
fn open_at<P: AsRef<Path>>(&self, file: &File, path: P) -> io::Result<File>;
}
@ -284,38 +276,38 @@ impl OpenOptionsExt for OpenOptions {
///
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
pub trait MetadataExt {
/// Returns the `st_dev` field of the internal `__wasi_filestat_t`
/// Returns the `st_dev` field of the internal `filestat_t`
fn dev(&self) -> u64;
/// Returns the `st_ino` field of the internal `__wasi_filestat_t`
/// Returns the `st_ino` field of the internal `filestat_t`
fn ino(&self) -> u64;
/// Returns the `st_nlink` field of the internal `__wasi_filestat_t`
fn nlink(&self) -> u32;
/// Returns the `st_atim` field of the internal `__wasi_filestat_t`
/// Returns the `st_nlink` field of the internal `filestat_t`
fn nlink(&self) -> u64;
/// Returns the `st_atim` field of the internal `filestat_t`
fn atim(&self) -> u64;
/// Returns the `st_mtim` field of the internal `__wasi_filestat_t`
/// Returns the `st_mtim` field of the internal `filestat_t`
fn mtim(&self) -> u64;
/// Returns the `st_ctim` field of the internal `__wasi_filestat_t`
/// Returns the `st_ctim` field of the internal `filestat_t`
fn ctim(&self) -> u64;
}
impl MetadataExt for fs::Metadata {
fn dev(&self) -> u64 {
self.as_inner().as_wasi().st_dev
self.as_inner().as_wasi().dev
}
fn ino(&self) -> u64 {
self.as_inner().as_wasi().st_ino
self.as_inner().as_wasi().ino
}
fn nlink(&self) -> u32 {
self.as_inner().as_wasi().st_nlink
fn nlink(&self) -> u64 {
self.as_inner().as_wasi().nlink
}
fn atim(&self) -> u64 {
self.as_inner().as_wasi().st_atim
self.as_inner().as_wasi().atim
}
fn mtim(&self) -> u64 {
self.as_inner().as_wasi().st_mtim
self.as_inner().as_wasi().mtim
}
fn ctim(&self) -> u64 {
self.as_inner().as_wasi().st_ctim
self.as_inner().as_wasi().ctim
}
}
@ -355,7 +347,7 @@ impl FileTypeExt for fs::FileType {
///
/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
pub trait DirEntryExt {
/// Returns the underlying `d_ino` field of the `__wasi_dirent_t`
/// Returns the underlying `d_ino` field of the `dirent_t`
fn ino(&self) -> u64;
}
@ -367,7 +359,7 @@ impl DirEntryExt for fs::DirEntry {
/// Create a hard link.
///
/// This corresponds to the `__wasi_path_link` syscall.
/// This corresponds to the `path_link` syscall.
pub fn link<P: AsRef<Path>, U: AsRef<Path>>(
old_fd: &File,
old_flags: u32,
@ -377,15 +369,15 @@ pub fn link<P: AsRef<Path>, U: AsRef<Path>>(
) -> io::Result<()> {
old_fd.as_inner().fd().link(
old_flags,
old_path.as_ref().as_os_str().as_bytes(),
osstr2str(old_path.as_ref().as_ref())?,
new_fd.as_inner().fd(),
new_path.as_ref().as_os_str().as_bytes(),
osstr2str(new_path.as_ref().as_ref())?,
)
}
/// Rename a file or directory.
///
/// This corresponds to the `__wasi_path_rename` syscall.
/// This corresponds to the `path_rename` syscall.
pub fn rename<P: AsRef<Path>, U: AsRef<Path>>(
old_fd: &File,
old_path: P,
@ -393,22 +385,21 @@ pub fn rename<P: AsRef<Path>, U: AsRef<Path>>(
new_path: U,
) -> io::Result<()> {
old_fd.as_inner().fd().rename(
old_path.as_ref().as_os_str().as_bytes(),
osstr2str(old_path.as_ref().as_ref())?,
new_fd.as_inner().fd(),
new_path.as_ref().as_os_str().as_bytes(),
osstr2str(new_path.as_ref().as_ref())?,
)
}
/// Create a symbolic link.
///
/// This corresponds to the `__wasi_path_symlink` syscall.
/// This corresponds to the `path_symlink` syscall.
pub fn symlink<P: AsRef<Path>, U: AsRef<Path>>(
old_path: P,
fd: &File,
new_path: U,
) -> io::Result<()> {
fd.as_inner().fd().symlink(
old_path.as_ref().as_os_str().as_bytes(),
new_path.as_ref().as_os_str().as_bytes(),
)
fd.as_inner()
.fd()
.symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?)
}

View File

@ -8,8 +8,6 @@ use crate::sys;
use crate::net;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use ::wasi::wasi_unstable as wasi;
/// Raw file descriptors.
pub type RawFd = u32;
@ -127,18 +125,18 @@ impl IntoRawFd for fs::File {
impl AsRawFd for io::Stdin {
fn as_raw_fd(&self) -> RawFd {
wasi::STDIN_FD
sys::stdio::Stdin.as_raw_fd()
}
}
impl AsRawFd for io::Stdout {
fn as_raw_fd(&self) -> RawFd {
wasi::STDOUT_FD
sys::stdio::Stdout.as_raw_fd()
}
}
impl AsRawFd for io::Stderr {
fn as_raw_fd(&self) -> RawFd {
wasi::STDERR_FD
sys::stdio::Stderr.as_raw_fd()
}
}

View File

@ -1,40 +1,31 @@
#![allow(dead_code)]
use super::err2io;
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
use crate::net::Shutdown;
use super::err2io;
use ::wasi::wasi_unstable as wasi;
#[derive(Debug)]
pub struct WasiFd {
fd: wasi::Fd,
}
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] {
assert_eq!(
mem::size_of::<IoSliceMut<'_>>(),
mem::size_of::<wasi::IoVec>()
);
assert_eq!(
mem::align_of::<IoSliceMut<'_>>(),
mem::align_of::<wasi::IoVec>()
);
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
/// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
unsafe { mem::transmute(a) }
unsafe {
mem::transmute(a)
}
}
fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] {
assert_eq!(
mem::size_of::<IoSlice<'_>>(),
mem::size_of::<wasi::CIoVec>()
);
assert_eq!(
mem::align_of::<IoSlice<'_>>(),
mem::align_of::<wasi::CIoVec>()
);
fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
/// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
unsafe { mem::transmute(a) }
unsafe {
mem::transmute(a)
}
}
impl WasiFd {
@ -87,7 +78,7 @@ impl WasiFd {
// FIXME: __wasi_fd_fdstat_get
pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> {
pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
}
@ -107,31 +98,30 @@ impl WasiFd {
unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
}
pub fn create_directory(&self, path: &[u8]) -> io::Result<()> {
pub fn create_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
}
pub fn link(
&self,
old_flags: wasi::LookupFlags,
old_path: &[u8],
old_flags: wasi::Lookupflags,
old_path: &str,
new_fd: &WasiFd,
new_path: &[u8],
new_path: &str,
) -> io::Result<()> {
unsafe {
wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
.map_err(err2io)
wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io)
}
}
pub fn open(
&self,
dirflags: wasi::LookupFlags,
path: &[u8],
oflags: wasi::OFlags,
dirflags: wasi::Lookupflags,
path: &str,
oflags: wasi::Oflags,
fs_rights_base: wasi::Rights,
fs_rights_inheriting: wasi::Rights,
fs_flags: wasi::FdFlags,
fs_flags: wasi::Fdflags,
) -> io::Result<WasiFd> {
unsafe {
wasi::path_open(
@ -142,25 +132,25 @@ impl WasiFd {
fs_rights_base,
fs_rights_inheriting,
fs_flags,
).map(|fd| WasiFd::from_raw(fd)).map_err(err2io)
)
.map(|fd| WasiFd::from_raw(fd))
.map_err(err2io)
}
}
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result<usize> {
unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) }
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) }
}
pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result<usize> {
unsafe { wasi::path_readlink(self.fd, path, buf).map_err(err2io) }
pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) }
}
pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> {
unsafe {
wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io)
}
pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) }
}
pub fn filestat_get(&self) -> io::Result<wasi::FileStat> {
pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
}
@ -168,11 +158,9 @@ impl WasiFd {
&self,
atim: wasi::Timestamp,
mtim: wasi::Timestamp,
fstflags: wasi::FstFlags,
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe {
wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io)
}
unsafe { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) }
}
pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
@ -181,61 +169,55 @@ impl WasiFd {
pub fn path_filestat_get(
&self,
flags: wasi::LookupFlags,
path: &[u8],
) -> io::Result<wasi::FileStat> {
flags: wasi::Lookupflags,
path: &str,
) -> io::Result<wasi::Filestat> {
unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
}
pub fn path_filestat_set_times(
&self,
flags: wasi::LookupFlags,
path: &[u8],
flags: wasi::Lookupflags,
path: &str,
atim: wasi::Timestamp,
mtim: wasi::Timestamp,
fstflags: wasi::FstFlags,
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe {
wasi::path_filestat_set_times(
self.fd,
flags,
path,
atim,
mtim,
fstflags,
).map_err(err2io)
wasi::path_filestat_set_times(self.fd, flags, path, atim, mtim, fstflags)
.map_err(err2io)
}
}
pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> {
pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
}
pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> {
pub fn unlink_file(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
}
pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> {
pub fn remove_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
}
pub fn sock_recv(
&self,
ri_data: &mut [IoSliceMut<'_>],
ri_flags: wasi::RiFlags,
) -> io::Result<(usize, wasi::RoFlags)> {
ri_flags: wasi::Riflags,
) -> io::Result<(usize, wasi::Roflags)> {
unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
}
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result<usize> {
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
}
pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
let how = match how {
Shutdown::Read => wasi::SHUT_RD,
Shutdown::Write => wasi::SHUT_WR,
Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD,
Shutdown::Read => wasi::SDFLAGS_RD,
Shutdown::Write => wasi::SDFLAGS_WR,
Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
};
unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
}

View File

@ -15,20 +15,18 @@ use crate::sys_common::FromInner;
pub use crate::sys_common::fs::copy;
pub use crate::sys_common::fs::remove_dir_all;
use ::wasi::wasi_unstable as wasi;
pub struct File {
fd: WasiFd,
}
#[derive(Clone)]
pub struct FileAttr {
meta: wasi::FileStat,
meta: wasi::Filestat,
}
pub struct ReadDir {
inner: Arc<ReadDirInner>,
cookie: Option<wasi::DirCookie>,
cookie: Option<wasi::Dircookie>,
buf: Vec<u8>,
offset: usize,
cap: usize,
@ -49,9 +47,9 @@ pub struct DirEntry {
pub struct OpenOptions {
read: bool,
write: bool,
dirflags: wasi::LookupFlags,
fdflags: wasi::FdFlags,
oflags: wasi::OFlags,
dirflags: wasi::Lookupflags,
fdflags: wasi::Fdflags,
oflags: wasi::Oflags,
rights_base: Option<wasi::Rights>,
rights_inheriting: Option<wasi::Rights>,
}
@ -63,7 +61,7 @@ pub struct FilePermissions {
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
pub struct FileType {
bits: wasi::FileType,
bits: wasi::Filetype,
}
#[derive(Debug)]
@ -71,7 +69,7 @@ pub struct DirBuilder {}
impl FileAttr {
pub fn size(&self) -> u64 {
self.meta.st_size
self.meta.size
}
pub fn perm(&self) -> FilePermissions {
@ -80,24 +78,22 @@ impl FileAttr {
}
pub fn file_type(&self) -> FileType {
FileType {
bits: self.meta.st_filetype,
}
FileType { bits: self.meta.filetype }
}
pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::from_wasi_timestamp(self.meta.st_mtim))
Ok(SystemTime::from_wasi_timestamp(self.meta.mtim))
}
pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::from_wasi_timestamp(self.meta.st_atim))
Ok(SystemTime::from_wasi_timestamp(self.meta.atim))
}
pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::from_wasi_timestamp(self.meta.st_ctim))
Ok(SystemTime::from_wasi_timestamp(self.meta.ctim))
}
pub fn as_wasi(&self) -> &wasi::FileStat {
pub fn as_wasi(&self) -> &wasi::Filestat {
&self.meta
}
}
@ -125,7 +121,7 @@ impl FileType {
self.bits == wasi::FILETYPE_SYMBOLIC_LINK
}
pub fn bits(&self) -> wasi::FileType {
pub fn bits(&self) -> wasi::Filetype {
self.bits
}
}
@ -177,8 +173,7 @@ impl Iterator for ReadDir {
continue;
}
let (dirent, data) = data.split_at(dirent_size);
let dirent =
unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };
let dirent = unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };
// If the file name was truncated, then we need to reinvoke
// `readdir` so we truncate our buffer to start over and reread this
@ -224,17 +219,11 @@ impl DirEntry {
}
pub fn metadata(&self) -> io::Result<FileAttr> {
metadata_at(
&self.inner.dir.fd,
0,
OsStr::from_bytes(&self.name).as_ref(),
)
metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref())
}
pub fn file_type(&self) -> io::Result<FileType> {
Ok(FileType {
bits: self.meta.d_type,
})
Ok(FileType { bits: self.meta.d_type })
}
pub fn ino(&self) -> wasi::Inode {
@ -245,7 +234,7 @@ impl DirEntry {
impl OpenOptions {
pub fn new() -> OpenOptions {
let mut base = OpenOptions::default();
base.dirflags = wasi::LOOKUP_SYMLINK_FOLLOW;
base.dirflags = wasi::LOOKUPFLAGS_SYMLINK_FOLLOW;
return base;
}
@ -258,23 +247,23 @@ impl OpenOptions {
}
pub fn truncate(&mut self, truncate: bool) {
self.oflag(wasi::O_TRUNC, truncate);
self.oflag(wasi::OFLAGS_TRUNC, truncate);
}
pub fn create(&mut self, create: bool) {
self.oflag(wasi::O_CREAT, create);
self.oflag(wasi::OFLAGS_CREAT, create);
}
pub fn create_new(&mut self, create_new: bool) {
self.oflag(wasi::O_EXCL, create_new);
self.oflag(wasi::O_CREAT, create_new);
self.oflag(wasi::OFLAGS_EXCL, create_new);
self.oflag(wasi::OFLAGS_CREAT, create_new);
}
pub fn directory(&mut self, directory: bool) {
self.oflag(wasi::O_DIRECTORY, directory);
self.oflag(wasi::OFLAGS_DIRECTORY, directory);
}
fn oflag(&mut self, bit: wasi::OFlags, set: bool) {
fn oflag(&mut self, bit: wasi::Oflags, set: bool) {
if set {
self.oflags |= bit;
} else {
@ -283,26 +272,26 @@ impl OpenOptions {
}
pub fn append(&mut self, set: bool) {
self.fdflag(wasi::FDFLAG_APPEND, set);
self.fdflag(wasi::FDFLAGS_APPEND, set);
}
pub fn dsync(&mut self, set: bool) {
self.fdflag(wasi::FDFLAG_DSYNC, set);
self.fdflag(wasi::FDFLAGS_DSYNC, set);
}
pub fn nonblock(&mut self, set: bool) {
self.fdflag(wasi::FDFLAG_NONBLOCK, set);
self.fdflag(wasi::FDFLAGS_NONBLOCK, set);
}
pub fn rsync(&mut self, set: bool) {
self.fdflag(wasi::FDFLAG_RSYNC, set);
self.fdflag(wasi::FDFLAGS_RSYNC, set);
}
pub fn sync(&mut self, set: bool) {
self.fdflag(wasi::FDFLAG_SYNC, set);
self.fdflag(wasi::FDFLAGS_SYNC, set);
}
fn fdflag(&mut self, bit: wasi::FdFlags, set: bool) {
fn fdflag(&mut self, bit: wasi::Fdflags, set: bool) {
if set {
self.fdflags |= bit;
} else {
@ -330,36 +319,36 @@ impl OpenOptions {
// based on that.
let mut base = 0;
if self.read {
base |= wasi::RIGHT_FD_READ;
base |= wasi::RIGHT_FD_READDIR;
base |= wasi::RIGHTS_FD_READ;
base |= wasi::RIGHTS_FD_READDIR;
}
if self.write {
base |= wasi::RIGHT_FD_WRITE;
base |= wasi::RIGHT_FD_DATASYNC;
base |= wasi::RIGHT_FD_ALLOCATE;
base |= wasi::RIGHT_FD_FILESTAT_SET_SIZE;
base |= wasi::RIGHTS_FD_WRITE;
base |= wasi::RIGHTS_FD_DATASYNC;
base |= wasi::RIGHTS_FD_ALLOCATE;
base |= wasi::RIGHTS_FD_FILESTAT_SET_SIZE;
}
// FIXME: some of these should probably be read-only or write-only...
base |= wasi::RIGHT_FD_ADVISE;
base |= wasi::RIGHT_FD_FDSTAT_SET_FLAGS;
base |= wasi::RIGHT_FD_FILESTAT_SET_TIMES;
base |= wasi::RIGHT_FD_SEEK;
base |= wasi::RIGHT_FD_SYNC;
base |= wasi::RIGHT_FD_TELL;
base |= wasi::RIGHT_PATH_CREATE_DIRECTORY;
base |= wasi::RIGHT_PATH_CREATE_FILE;
base |= wasi::RIGHT_PATH_FILESTAT_GET;
base |= wasi::RIGHT_PATH_LINK_SOURCE;
base |= wasi::RIGHT_PATH_LINK_TARGET;
base |= wasi::RIGHT_PATH_OPEN;
base |= wasi::RIGHT_PATH_READLINK;
base |= wasi::RIGHT_PATH_REMOVE_DIRECTORY;
base |= wasi::RIGHT_PATH_RENAME_SOURCE;
base |= wasi::RIGHT_PATH_RENAME_TARGET;
base |= wasi::RIGHT_PATH_SYMLINK;
base |= wasi::RIGHT_PATH_UNLINK_FILE;
base |= wasi::RIGHT_POLL_FD_READWRITE;
base |= wasi::RIGHTS_FD_ADVISE;
base |= wasi::RIGHTS_FD_FDSTAT_SET_FLAGS;
base |= wasi::RIGHTS_FD_FILESTAT_SET_TIMES;
base |= wasi::RIGHTS_FD_SEEK;
base |= wasi::RIGHTS_FD_SYNC;
base |= wasi::RIGHTS_FD_TELL;
base |= wasi::RIGHTS_PATH_CREATE_DIRECTORY;
base |= wasi::RIGHTS_PATH_CREATE_FILE;
base |= wasi::RIGHTS_PATH_FILESTAT_GET;
base |= wasi::RIGHTS_PATH_LINK_SOURCE;
base |= wasi::RIGHTS_PATH_LINK_TARGET;
base |= wasi::RIGHTS_PATH_OPEN;
base |= wasi::RIGHTS_PATH_READLINK;
base |= wasi::RIGHTS_PATH_REMOVE_DIRECTORY;
base |= wasi::RIGHTS_PATH_RENAME_SOURCE;
base |= wasi::RIGHTS_PATH_RENAME_TARGET;
base |= wasi::RIGHTS_PATH_SYMLINK;
base |= wasi::RIGHTS_PATH_UNLINK_FILE;
base |= wasi::RIGHTS_POLL_FD_READWRITE;
return base;
}
@ -368,14 +357,14 @@ impl OpenOptions {
self.rights_inheriting.unwrap_or_else(|| self.rights_base())
}
pub fn lookup_flags(&mut self, flags: wasi::LookupFlags) {
pub fn lookup_flags(&mut self, flags: wasi::Lookupflags) {
self.dirflags = flags;
}
}
impl File {
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
let (dir, file) = open_parent(path, wasi::RIGHT_PATH_OPEN)?;
let (dir, file) = open_parent(path, wasi::RIGHTS_PATH_OPEN)?;
open_at(&dir, &file, opts)
}
@ -387,11 +376,7 @@ impl File {
self.fd.filestat_get().map(|meta| FileAttr { meta })
}
pub fn metadata_at(
&self,
flags: wasi::LookupFlags,
path: &Path,
) -> io::Result<FileAttr> {
pub fn metadata_at(&self, flags: wasi::Lookupflags, path: &Path) -> io::Result<FileAttr> {
metadata_at(&self.fd, flags, path)
}
@ -457,11 +442,7 @@ impl File {
impl FromInner<u32> for File {
fn from_inner(fd: u32) -> File {
unsafe {
File {
fd: WasiFd::from_raw(fd),
}
}
unsafe { File { fd: WasiFd::from_raw(fd) } }
}
}
@ -471,16 +452,14 @@ impl DirBuilder {
}
pub fn mkdir(&self, p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_CREATE_DIRECTORY)?;
dir.create_directory(file.as_os_str().as_bytes())
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_CREATE_DIRECTORY)?;
dir.create_directory(osstr2str(file.as_ref())?)
}
}
impl fmt::Debug for File {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("File")
.field("fd", &self.fd.as_raw())
.finish()
f.debug_struct("File").field("fd", &self.fd.as_raw()).finish()
}
}
@ -494,26 +473,19 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
buf: vec![0; 128],
offset: 0,
cap: 0,
inner: Arc::new(ReadDirInner {
dir,
root: p.to_path_buf(),
}),
inner: Arc::new(ReadDirInner { dir, root: p.to_path_buf() }),
})
}
pub fn unlink(p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_UNLINK_FILE)?;
dir.unlink_file(file.as_os_str().as_bytes())
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_UNLINK_FILE)?;
dir.unlink_file(osstr2str(file.as_ref())?)
}
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
let (old, old_file) = open_parent(old, wasi::RIGHT_PATH_RENAME_SOURCE)?;
let (new, new_file) = open_parent(new, wasi::RIGHT_PATH_RENAME_TARGET)?;
old.rename(
old_file.as_os_str().as_bytes(),
&new,
new_file.as_os_str().as_bytes(),
)
let (old, old_file) = open_parent(old, wasi::RIGHTS_PATH_RENAME_SOURCE)?;
let (new, new_file) = open_parent(new, wasi::RIGHTS_PATH_RENAME_TARGET)?;
old.rename(osstr2str(old_file.as_ref())?, &new, osstr2str(new_file.as_ref())?)
}
pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
@ -523,12 +495,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
}
pub fn rmdir(p: &Path) -> io::Result<()> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_REMOVE_DIRECTORY)?;
dir.remove_directory(file.as_os_str().as_bytes())
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_REMOVE_DIRECTORY)?;
dir.remove_directory(osstr2str(file.as_ref())?)
}
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_READLINK)?;
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_READLINK)?;
read_link(&dir, &file)
}
@ -549,7 +521,7 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
// Now that we have an initial guess of how big to make our buffer, call
// `readlink` in a loop until it fails or reports it filled fewer bytes than
// we asked for, indicating we got everything.
let file = file.as_os_str().as_bytes();
let file = osstr2str(file.as_ref())?;
let mut destination = vec![0u8; initial_size];
loop {
let len = fd.readlink(file, &mut destination)?;
@ -564,38 +536,34 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
}
pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_SYMLINK)?;
dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes())
let (dst, dst_file) = open_parent(dst, wasi::RIGHTS_PATH_SYMLINK)?;
dst.symlink(osstr2str(src.as_ref())?, osstr2str(dst_file.as_ref())?)
}
pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
let (src, src_file) = open_parent(src, wasi::RIGHT_PATH_LINK_SOURCE)?;
let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_LINK_TARGET)?;
let (src, src_file) = open_parent(src, wasi::RIGHTS_PATH_LINK_SOURCE)?;
let (dst, dst_file) = open_parent(dst, wasi::RIGHTS_PATH_LINK_TARGET)?;
src.link(
wasi::LOOKUP_SYMLINK_FOLLOW,
src_file.as_os_str().as_bytes(),
wasi::LOOKUPFLAGS_SYMLINK_FOLLOW,
osstr2str(src_file.as_ref())?,
&dst,
dst_file.as_os_str().as_bytes(),
osstr2str(dst_file.as_ref())?,
)
}
pub fn stat(p: &Path) -> io::Result<FileAttr> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
metadata_at(&dir, wasi::LOOKUP_SYMLINK_FOLLOW, &file)
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?;
metadata_at(&dir, wasi::LOOKUPFLAGS_SYMLINK_FOLLOW, &file)
}
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
let (dir, file) = open_parent(p, wasi::RIGHTS_PATH_FILESTAT_GET)?;
metadata_at(&dir, 0, &file)
}
fn metadata_at(
fd: &WasiFd,
flags: wasi::LookupFlags,
path: &Path,
) -> io::Result<FileAttr> {
fd.path_filestat_get(flags, path.as_os_str().as_bytes())
.map(|meta| FileAttr { meta })
fn metadata_at(fd: &WasiFd, flags: wasi::Lookupflags, path: &Path) -> io::Result<FileAttr> {
let meta = fd.path_filestat_get(flags, osstr2str(path.as_ref())?)?;
Ok(FileAttr { meta })
}
pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
@ -607,7 +575,7 @@ pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
let fd = fd.open(
opts.dirflags,
path.as_os_str().as_bytes(),
osstr2str(path.as_ref())?,
opts.oflags,
opts.rights_base(),
opts.rights_inheriting(),
@ -643,10 +611,7 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
///
/// Note that this can fail if `p` doesn't look like it can be opened relative
/// to any preopened file descriptor.
fn open_parent(
p: &Path,
rights: wasi::Rights,
) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
fn open_parent(p: &Path, rights: wasi::Rights) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
let p = CString::new(p.as_os_str().as_bytes())?;
unsafe {
let mut ret = ptr::null();
@ -671,3 +636,7 @@ fn open_parent(
return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path));
}
}
pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8"))
}

View File

@ -1,12 +1,9 @@
use crate::marker::PhantomData;
use crate::slice;
use ::wasi::wasi_unstable as wasi;
use core::ffi::c_void;
#[repr(transparent)]
pub struct IoSlice<'a> {
vec: wasi::CIoVec,
vec: wasi::Ciovec,
_p: PhantomData<&'a [u8]>,
}
@ -14,8 +11,8 @@ impl<'a> IoSlice<'a> {
#[inline]
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
IoSlice {
vec: wasi::CIoVec {
buf: buf.as_ptr() as *const c_void,
vec: wasi::Ciovec {
buf: buf.as_ptr(),
buf_len: buf.len(),
},
_p: PhantomData,
@ -44,7 +41,7 @@ impl<'a> IoSlice<'a> {
#[repr(transparent)]
pub struct IoSliceMut<'a> {
vec: wasi::IoVec,
vec: wasi::Iovec,
_p: PhantomData<&'a mut [u8]>,
}
@ -52,8 +49,8 @@ impl<'a> IoSliceMut<'a> {
#[inline]
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
IoSliceMut {
vec: wasi::IoVec {
buf: buf.as_mut_ptr() as *mut c_void,
vec: wasi::Iovec {
buf: buf.as_mut_ptr(),
buf_len: buf.len()
},
_p: PhantomData,

View File

@ -17,7 +17,6 @@
use crate::io as std_io;
use crate::mem;
use crate::os::raw::c_char;
use ::wasi::wasi_unstable as wasi;
pub mod alloc;
pub mod args;
@ -72,25 +71,21 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
if errno > u16::max_value() as i32 || errno < 0 {
return Other;
}
let code = match wasi::Error::new(errno as u16) {
Some(code) => code,
None => return Other,
};
match code {
wasi::ECONNREFUSED => ConnectionRefused,
wasi::ECONNRESET => ConnectionReset,
wasi::EPERM | wasi::EACCES => PermissionDenied,
wasi::EPIPE => BrokenPipe,
wasi::ENOTCONN => NotConnected,
wasi::ECONNABORTED => ConnectionAborted,
wasi::EADDRNOTAVAIL => AddrNotAvailable,
wasi::EADDRINUSE => AddrInUse,
wasi::ENOENT => NotFound,
wasi::EINTR => Interrupted,
wasi::EINVAL => InvalidInput,
wasi::ETIMEDOUT => TimedOut,
wasi::EEXIST => AlreadyExists,
wasi::EAGAIN => WouldBlock,
match errno as u16 {
wasi::ERRNO_CONNREFUSED => ConnectionRefused,
wasi::ERRNO_CONNRESET => ConnectionReset,
wasi::ERRNO_PERM | wasi::ERRNO_ACCES => PermissionDenied,
wasi::ERRNO_PIPE => BrokenPipe,
wasi::ERRNO_NOTCONN => NotConnected,
wasi::ERRNO_CONNABORTED => ConnectionAborted,
wasi::ERRNO_ADDRNOTAVAIL => AddrNotAvailable,
wasi::ERRNO_ADDRINUSE => AddrInUse,
wasi::ERRNO_NOENT => NotFound,
wasi::ERRNO_INTR => Interrupted,
wasi::ERRNO_INVAL => InvalidInput,
wasi::ERRNO_TIMEDOUT => TimedOut,
wasi::ERRNO_EXIST => AlreadyExists,
wasi::ERRNO_AGAIN => WouldBlock,
_ => Other,
}
}
@ -116,16 +111,13 @@ pub unsafe fn abort_internal() -> ! {
pub fn hashmap_random_keys() -> (u64, u64) {
let mut ret = (0u64, 0u64);
unsafe {
let base = &mut ret as *mut (u64, u64) as *mut core::ffi::c_void;
let base = &mut ret as *mut (u64, u64) as *mut u8;
let len = mem::size_of_val(&ret);
let ret = wasi::raw::__wasi_random_get(base, len);
if ret != 0 {
panic!("__wasi_random_get failure")
}
wasi::random_get(base, len).expect("random_get failure");
}
return ret
}
fn err2io(err: wasi::Error) -> std_io::Error {
std_io::Error::from_raw_os_error(err.get() as i32)
std_io::Error::from_raw_os_error(err.raw_error().into())
}

View File

@ -2,8 +2,6 @@ use crate::io::{self, IoSlice, IoSliceMut};
use crate::mem::ManuallyDrop;
use crate::sys::fd::WasiFd;
use ::wasi::wasi_unstable as wasi;
pub struct Stdin;
pub struct Stdout;
pub struct Stderr;
@ -18,8 +16,11 @@ impl Stdin {
}
pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDIN_FD) })
.read(data)
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).read(data)
}
pub fn as_raw_fd(&self) -> u32 {
0
}
}
@ -33,13 +34,16 @@ impl Stdout {
}
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDOUT_FD) })
.write(data)
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
}
pub fn flush(&self) -> io::Result<()> {
Ok(())
}
pub fn as_raw_fd(&self) -> u32 {
1
}
}
impl Stderr {
@ -52,13 +56,16 @@ impl Stderr {
}
pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDERR_FD) })
.write(data)
ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
}
pub fn flush(&self) -> io::Result<()> {
Ok(())
}
pub fn as_raw_fd(&self) -> u32 {
2
}
}
impl io::Write for Stderr {
@ -74,7 +81,7 @@ impl io::Write for Stderr {
pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
pub fn is_ebadf(err: &io::Error) -> bool {
err.raw_os_error() == Some(wasi::EBADF.get() as i32)
err.raw_os_error() == Some(wasi::ERRNO_BADF.into())
}
pub fn panic_output() -> Option<impl io::Write> {

View File

@ -4,22 +4,18 @@ use crate::mem;
use crate::sys::{unsupported, Void};
use crate::time::Duration;
use ::wasi::wasi_unstable as wasi;
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>
{
pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
unsupported()
}
pub fn yield_now() {
let ret = wasi::sched_yield();
let ret = unsafe { wasi::sched_yield() };
debug_assert_eq!(ret, Ok(()));
}
@ -33,32 +29,30 @@ impl Thread {
const USERDATA: wasi::Userdata = 0x0123_45678;
let clock = wasi::raw::__wasi_subscription_u_clock_t {
identifier: 0,
clock_id: wasi::CLOCK_MONOTONIC,
let clock = wasi::SubscriptionClock {
id: wasi::CLOCKID_MONOTONIC,
timeout: nanos as u64,
precision: 0,
flags: 0,
};
let in_ = [wasi::Subscription {
let in_ = wasi::Subscription {
userdata: USERDATA,
type_: wasi::EVENTTYPE_CLOCK,
u: wasi::raw::__wasi_subscription_u { clock: clock },
}];
let (res, event) = unsafe {
let mut out: [wasi::Event; 1] = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut out);
(res, out[0])
r#type: wasi::EVENTTYPE_CLOCK,
u: wasi::SubscriptionU { clock },
};
match (res, event) {
(Ok(1), wasi::Event {
userdata: USERDATA,
error: 0,
type_: wasi::EVENTTYPE_CLOCK,
..
}) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
unsafe {
let mut event: wasi::Event = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut event, 1);
match (res, event) {
(
Ok(1),
wasi::Event {
userdata: USERDATA, error: 0, r#type: wasi::EVENTTYPE_CLOCK, ..
},
) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
}
}
}
@ -69,6 +63,10 @@ impl Thread {
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -1,5 +1,4 @@
use crate::time::Duration;
use ::wasi::wasi_unstable as wasi;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant(Duration);
@ -10,19 +9,18 @@ pub struct SystemTime(Duration);
pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
fn current_time(clock: u32) -> Duration {
let ts = wasi::clock_time_get(
clock,
1, // precision... seems ignored though?
).unwrap();
Duration::new(
(ts / 1_000_000_000) as u64,
(ts % 1_000_000_000) as u32,
)
let ts = unsafe {
wasi::clock_time_get(
clock, 1, // precision... seems ignored though?
)
.unwrap()
};
Duration::new((ts / 1_000_000_000) as u64, (ts % 1_000_000_000) as u32)
}
impl Instant {
pub fn now() -> Instant {
Instant(current_time(wasi::CLOCK_MONOTONIC))
Instant(current_time(wasi::CLOCKID_MONOTONIC))
}
pub const fn zero() -> Instant {
@ -48,15 +46,14 @@ impl Instant {
impl SystemTime {
pub fn now() -> SystemTime {
SystemTime(current_time(wasi::CLOCK_REALTIME))
SystemTime(current_time(wasi::CLOCKID_REALTIME))
}
pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
SystemTime(Duration::from_nanos(ts))
}
pub fn sub_time(&self, other: &SystemTime)
-> Result<Duration, Duration> {
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
}

View File

@ -24,3 +24,4 @@ rustc_lexer = { path = "../librustc_lexer" }
rustc_macros = { path = "../librustc_macros" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }

View File

@ -30,9 +30,8 @@ use crate::token::{self, DelimToken};
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
use syntax_pos::symbol::{kw, sym, Symbol};
use syntax_pos::{Span, DUMMY_SP, ExpnId};
use syntax_pos::{Span, DUMMY_SP};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec;
@ -268,46 +267,7 @@ impl ParenthesizedArgs {
}
}
// hack to ensure that we don't try to access the private parts of `NodeId` in this module
mod node_id_inner {
use rustc_index::vec::Idx;
rustc_index::newtype_index! {
pub struct NodeId {
ENCODABLE = custom
DEBUG_FORMAT = "NodeId({})"
}
}
}
pub use node_id_inner::NodeId;
impl NodeId {
pub fn placeholder_from_expn_id(expn_id: ExpnId) -> Self {
NodeId::from_u32(expn_id.as_u32())
}
pub fn placeholder_to_expn_id(self) -> ExpnId {
ExpnId::from_u32(self.as_u32())
}
}
impl fmt::Display for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.as_u32(), f)
}
}
impl rustc_serialize::UseSpecializedEncodable for NodeId {
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u32(self.as_u32())
}
}
impl rustc_serialize::UseSpecializedDecodable for NodeId {
fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
d.read_u32().map(NodeId::from_u32)
}
}
pub use rustc_session::node_id::NodeId;
/// `NodeId` used to represent the root of the crate.
pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0);
@ -470,9 +430,7 @@ pub struct WhereEqPredicate {
pub rhs_ty: P<Ty>,
}
/// The set of `MetaItem`s that define the compilation environment of the crate,
/// used to drive conditional compilation.
pub type CrateConfig = FxHashSet<(Name, Option<Symbol>)>;
pub use rustc_session::parse::CrateConfig;
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Crate {

View File

@ -3,28 +3,28 @@
//! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat
//! redundant. Later, these types can be converted to types for use by the rest of the compiler.
use crate::ast::NodeId;
use syntax_pos::MultiSpan;
use rustc_session::lint::FutureIncompatibleInfo;
use rustc_session::declare_lint;
pub use rustc_session::lint::BufferedEarlyLint;
/// Since we cannot import `LintId`s from `rustc::lint`, we define some Ids here which can later be
/// passed to `rustc::lint::Lint::from_parser_lint_id` to get a `rustc::lint::Lint`.
pub enum BufferedEarlyLintId {
IllFormedAttributeInput,
MetaVariableMisuse,
IncompleteInclude,
declare_lint! {
pub ILL_FORMED_ATTRIBUTE_INPUT,
Deny,
"ill-formed attribute inputs that were previously accepted and used in practice",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
edition: None,
};
}
/// Stores buffered lint info which can later be passed to `librustc`.
pub struct BufferedEarlyLint {
/// The span of code that we are linting on.
pub span: MultiSpan,
/// The lint message.
pub msg: String,
/// The `NodeId` of the AST node that generated the lint.
pub id: NodeId,
/// A lint Id that can be passed to `rustc::lint::Lint::from_parser_lint_id`.
pub lint_id: BufferedEarlyLintId,
declare_lint! {
pub META_VARIABLE_MISUSE,
Allow,
"possible meta-variable misuse at macro definition"
}
declare_lint! {
pub INCOMPLETE_INCLUDE,
Deny,
"trailing content in included file"
}

View File

@ -102,7 +102,7 @@ pub mod ptr;
pub mod show_span;
pub use syntax_pos::edition;
pub use syntax_pos::symbol;
pub mod sess;
pub use rustc_session::parse as sess;
pub mod token;
pub mod tokenstream;
pub mod visit;

View File

@ -924,7 +924,6 @@ impl<'a> ExtCtxt<'a> {
}
pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
pub fn parse_sess(&self) -> &'a ParseSess { self.parse_sess }
pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
pub fn call_site(&self) -> Span {
self.current_expansion.id.expn_data().call_site
}

View File

@ -107,7 +107,7 @@
use crate::mbe::{KleeneToken, TokenTree};
use syntax::ast::NodeId;
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::early_buffered_lints::META_VARIABLE_MISUSE;
use syntax::token::{DelimToken, Token, TokenKind};
use syntax::sess::ParseSess;
use syntax::symbol::{kw, sym};
@ -623,5 +623,5 @@ fn ops_is_prefix(
}
fn buffer_lint(sess: &ParseSess, span: MultiSpan, node_id: NodeId, message: &str) {
sess.buffer_lint(BufferedEarlyLintId::MetaVariableMisuse, span, node_id, message);
sess.buffer_lint(&META_VARIABLE_MISUSE, span, node_id, message);
}

View File

@ -5,7 +5,7 @@ use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax::token;
use syntax::tokenstream::TokenStream;
use syntax::early_buffered_lints::BufferedEarlyLintId;
use syntax::early_buffered_lints::INCOMPLETE_INCLUDE;
use syntax_expand::panictry;
use syntax_expand::base::{self, *};
@ -101,7 +101,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
let r = panictry!(self.p.parse_expr());
if self.p.token != token::Eof {
self.p.sess.buffer_lint(
BufferedEarlyLintId::IncompleteInclude,
&INCOMPLETE_INCLUDE,
self.p.token.span,
ast::CRATE_NODE_ID,
"include macro expected single expression in source",

View File

@ -101,11 +101,13 @@ extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
}
extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
#if LLVM_VERSION_GE(8, 0)
#if LLVM_VERSION_GE(9, 0)
const bool CompileKernel = false;
return wrap(createMemorySanitizerLegacyPassPass(
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
#elif LLVM_VERSION_GE(8, 0)
return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover));
#else
return wrap(createMemorySanitizerPass(TrackOrigins, Recover));
#endif
@ -393,7 +395,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
bool TrapUnreachable,
bool Singlethread,
bool AsmComments,
bool EmitStackSizeSection) {
bool EmitStackSizeSection,
bool RelaxELFRelocations) {
auto OptLevel = fromRust(RustOptLevel);
auto RM = fromRust(RustReloc);
@ -418,6 +421,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
Options.MCOptions.AsmVerbose = AsmComments;
Options.MCOptions.PreserveAsmComments = AsmComments;
Options.MCOptions.ABIName = ABIStr;
Options.RelaxELFRelocations = RelaxELFRelocations;
if (TrapUnreachable) {
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.
@ -449,9 +453,7 @@ extern "C" void LLVMRustConfigurePassManagerBuilder(
LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
const char* PGOGenPath, const char* PGOUsePath) {
#if LLVM_VERSION_GE(7, 0)
unwrap(PMBR)->MergeFunctions = MergeFunctions;
#endif
unwrap(PMBR)->SLPVectorize = SLPVectorize;
unwrap(PMBR)->OptLevel = fromRust(OptLevel);
unwrap(PMBR)->LoopVectorize = LoopVectorize;
@ -558,12 +560,8 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
return LLVMRustResult::Failure;
}
#if LLVM_VERSION_GE(7, 0)
buffer_ostream BOS(OS);
unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
#else
unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
#endif
PM->run(*unwrap(M));
// Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
@ -847,9 +845,7 @@ struct LLVMRustThinLTOData {
StringMap<FunctionImporter::ExportSetTy> ExportLists;
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
#if LLVM_VERSION_GE(7, 0)
LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
#endif
};
// Just an argument to the `LLVMRustCreateThinLTOData` function below.
@ -920,7 +916,6 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
// combined index
//
// This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
#if LLVM_VERSION_GE(7, 0)
auto deadIsPrevailing = [&](GlobalValue::GUID G) {
return PrevailingType::Unknown;
};
@ -932,9 +927,6 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
deadIsPrevailing, /* ImportEnabled = */ false);
#else
computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing);
#endif
#else
computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols);
#endif
ComputeCrossModuleImport(
Ret->Index,

View File

@ -88,11 +88,7 @@ extern "C" char *LLVMRustGetLastError(void) {
}
extern "C" unsigned int LLVMRustGetInstructionCount(LLVMModuleRef M) {
#if LLVM_VERSION_GE(7, 0)
return unwrap(M)->getInstructionCount();
#else
report_fatal_error("Module::getInstructionCount not available before LLVM 7");
#endif
}
extern "C" void LLVMRustSetLastError(const char *Err) {
@ -761,14 +757,10 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart(
LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Discriminator,
LLVMMetadataRef Elements, const char *UniqueId) {
#if LLVM_VERSION_GE(7, 0)
return wrap(Builder->createVariantPart(
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
SizeInBits, AlignInBits, fromRust(Flags), unwrapDI<DIDerivedType>(Discriminator),
DINodeArray(unwrapDI<MDTuple>(Elements)), UniqueId));
#else
abort();
#endif
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
@ -787,7 +779,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
const char *Name, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant,
LLVMRustDIFlags Flags, LLVMMetadataRef Ty) {
#if LLVM_VERSION_GE(7, 0)
llvm::ConstantInt* D = nullptr;
if (Discriminant) {
D = unwrap<llvm::ConstantInt>(Discriminant);
@ -796,12 +787,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
unwrapDI<DIFile>(File), LineNo,
SizeInBits, AlignInBits, OffsetInBits, D,
fromRust(Flags), unwrapDI<DIType>(Ty)));
#else
return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNo,
SizeInBits, AlignInBits, OffsetInBits,
fromRust(Flags), unwrapDI<DIType>(Ty)));
#endif
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
@ -911,18 +896,10 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
uint32_t AlignInBits, LLVMMetadataRef Elements,
LLVMMetadataRef ClassTy, bool IsScoped) {
#if LLVM_VERSION_GE(7, 0)
return wrap(Builder->createEnumerationType(
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
unwrapDI<DIType>(ClassTy), "", IsScoped));
#else
// Ignore IsScoped on older LLVM.
return wrap(Builder->createEnumerationType(
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
unwrapDI<DIType>(ClassTy), ""));
#endif
}
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
@ -1275,34 +1252,20 @@ extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size, bool IsVolatile) {
#if LLVM_VERSION_GE(7, 0)
return wrap(unwrap(B)->CreateMemCpy(
unwrap(Dst), DstAlign,
unwrap(Src), SrcAlign,
unwrap(Size), IsVolatile));
#else
unsigned Align = std::min(DstAlign, SrcAlign);
return wrap(unwrap(B)->CreateMemCpy(
unwrap(Dst), unwrap(Src),
unwrap(Size), Align, IsVolatile));
#endif
}
extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size, bool IsVolatile) {
#if LLVM_VERSION_GE(7, 0)
return wrap(unwrap(B)->CreateMemMove(
unwrap(Dst), DstAlign,
unwrap(Src), SrcAlign,
unwrap(Size), IsVolatile));
#else
unsigned Align = std::min(DstAlign, SrcAlign);
return wrap(unwrap(B)->CreateMemMove(
unwrap(Dst), unwrap(Src),
unwrap(Size), Align, IsVolatile));
#endif
}
extern "C" LLVMValueRef

View File

@ -1,6 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -1,6 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -1,6 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -1,6 +1,5 @@
// ignore-tidy-linelength
// compile-flags: -C no-prepopulate-passes
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -1,6 +1,5 @@
// compile-flags: -O
// ignore-tidy-linelength
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -1,5 +1,3 @@
// min-llvm-version 7.0
// compile-flags: -C no-prepopulate-passes
#![crate_type = "lib"]

View File

@ -1,6 +1,5 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
// min-llvm-version 7.0
#![crate_type = "lib"]

View File

@ -2,7 +2,6 @@
# ignore-windows
# ignore-macos
# min-llvm-version 6.0
#
# This feature only works when the output object format is ELF so we ignore
# macOS and Windows

View File

@ -1,8 +1,8 @@
#![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
#![crate_type = "dylib"]
#[macro_use]
extern crate rustc;
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
extern crate syntax;

View File

@ -2,8 +2,8 @@
#![feature(plugin_registrar, rustc_private)]
#![feature(box_syntax)]
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
extern crate syntax;

View File

@ -4,6 +4,7 @@
#![feature(box_syntax)]
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
extern crate syntax;

View File

@ -4,8 +4,8 @@
#![feature(box_syntax, rustc_private)]
// Load rustc as a plugin to get macros.
#[macro_use]
extern crate rustc;
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
use rustc::hir;

View File

@ -6,8 +6,8 @@
extern crate syntax;
// Load rustc as a plugin to get macros
#[macro_use]
extern crate rustc;
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray};

View File

@ -4,8 +4,8 @@
extern crate syntax;
// Load rustc as a plugin to get macros
#[macro_use]
extern crate rustc;
#[macro_use] extern crate rustc;
#[macro_use] extern crate rustc_session;
extern crate rustc_driver;
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId};

View File

@ -4,9 +4,11 @@
#![deny(rustc::lint_pass_impl_without_macro)]
extern crate rustc;
extern crate rustc_session;
use rustc::lint::{LintArray, LintPass};
use rustc::{declare_lint, declare_lint_pass, impl_lint_pass};
use rustc::{declare_lint_pass, impl_lint_pass};
use rustc_session::declare_lint;
declare_lint! {
pub TEST_LINT,

View File

@ -1,5 +1,5 @@
error: implementing `LintPass` by hand
--> $DIR/lint_pass_impl_without_macro.rs:19:6
--> $DIR/lint_pass_impl_without_macro.rs:21:6
|
LL | impl LintPass for Foo {
| ^^^^^^^^
@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)]
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
error: implementing `LintPass` by hand
--> $DIR/lint_pass_impl_without_macro.rs:29:14
--> $DIR/lint_pass_impl_without_macro.rs:31:14
|
LL | impl LintPass for Custom {
| ^^^^^^^^

View File

@ -0,0 +1,39 @@
// build-pass
// compile-flags: --crate-type lib
// Regression test for ICE which occurred when const propagating an enum with three variants
// one of which is uninhabited.
pub enum ApiError {}
#[allow(dead_code)]
pub struct TokioError {
b: bool,
}
pub enum Error {
Api {
source: ApiError,
},
Ethereum,
Tokio {
source: TokioError,
},
}
struct Api;
impl IntoError<Error> for Api
{
type Source = ApiError;
fn into_error(self, error: Self::Source) -> Error {
Error::Api {
source: (|v| v)(error),
}
}
}
pub trait IntoError<E>
{
/// The underlying error
type Source;
/// Combine the information to produce the error
fn into_error(self, source: Self::Source) -> E;
}

View File

@ -1,6 +1,5 @@
// run-pass
// ignore-emscripten
// min-llvm-version 7.0
// Test that the simd_f{min,max} intrinsics produce the correct results.

View File

@ -25,7 +25,6 @@
// gate-test-movbe_target_feature
// gate-test-rtm_target_feature
// gate-test-f16c_target_feature
// min-llvm-version 6.0
#[target_feature(enable = "avx512bw")]
//~^ ERROR: currently unstable

View File

@ -1,5 +1,5 @@
error[E0658]: the target feature `avx512bw` is currently unstable
--> $DIR/gate.rs:30:18
--> $DIR/gate.rs:29:18
|
LL | #[target_feature(enable = "avx512bw")]
| ^^^^^^^^^^^^^^^^^^^