Auto merge of #151107 - JonathanBrouwer:rollup-9CIxxuZ, r=JonathanBrouwer

Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#149408 (refactor: remove Ord bound from BinaryHeap::new etc)
 - rust-lang/rust#150406 (Change some `matches!(.., .. if ..)` with let-chains)
 - rust-lang/rust#150723 (std: move `errno` and related functions into `sys::io`)
 - rust-lang/rust#150877 (resolve: Refactor away the side table `decl_parent_modules`)
 - rust-lang/rust#150902 (Update to_uppercase docs to avoid ß->SS example)
 - rust-lang/rust#151034 (std: Change UEFI env vars to volatile storage)
 - rust-lang/rust#151036 (Better handle when trying to iterate on a `Range` of a type that isn't `Step`)
 - rust-lang/rust#151067 (Avoid should-fail in two ui tests and a codegen-llvm test)
 - rust-lang/rust#151072 (also handle ENOTTY ioctl errors when checking pidfd -> pid support)
 - rust-lang/rust#151077 (Recognize potential `impl<const N: usize>` to `impl<N>` mistake)
 - rust-lang/rust#151096 (Remove `Deref`/`DerefMut` impl for `Providers`.)

Failed merges:

 - rust-lang/rust#150939 (resolve: Relax some asserts in glob overwriting and add tests)

r? @ghost
This commit is contained in:
bors 2026-01-14 13:12:51 +00:00
commit 8c52f735ab
150 changed files with 1254 additions and 1143 deletions

View file

@ -286,7 +286,8 @@ impl CodegenBackend for GccCodegenBackend {
}
fn provide(&self, providers: &mut Providers) {
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess)
providers.queries.global_backend_features =
|tcx, ()| gcc_util::global_gcc_features(tcx.sess)
}
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {

View file

@ -264,7 +264,7 @@ impl CodegenBackend for LlvmCodegenBackend {
}
fn provide(&self, providers: &mut Providers) {
providers.global_backend_features =
providers.queries.global_backend_features =
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, false)
}

View file

@ -474,15 +474,15 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId)
}
pub(crate) fn provide(providers: &mut Providers) {
providers.reachable_non_generics = reachable_non_generics_provider;
providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
providers.exported_generic_symbols = exported_generic_symbols_provider_local;
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
providers.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider;
providers.wasm_import_module_map = wasm_import_module_map;
providers.queries.reachable_non_generics = reachable_non_generics_provider;
providers.queries.is_reachable_non_generic = is_reachable_non_generic_provider_local;
providers.queries.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
providers.queries.exported_generic_symbols = exported_generic_symbols_provider_local;
providers.queries.upstream_monomorphizations = upstream_monomorphizations_provider;
providers.queries.is_unreachable_local_definition = is_unreachable_local_definition_provider;
providers.queries.upstream_drop_glue_for = upstream_drop_glue_for_provider;
providers.queries.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider;
providers.queries.wasm_import_module_map = wasm_import_module_map;
providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
providers.extern_queries.upstream_monomorphizations_for =
upstream_monomorphizations_for_provider;

View file

@ -266,9 +266,9 @@ pub enum CodegenErrors {
pub fn provide(providers: &mut Providers) {
crate::back::symbol_export::provide(providers);
crate::base::provide(providers);
crate::target_features::provide(providers);
crate::codegen_attrs::provide(providers);
crate::base::provide(&mut providers.queries);
crate::target_features::provide(&mut providers.queries);
crate::codegen_attrs::provide(&mut providers.queries);
providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![];
}

View file

@ -833,13 +833,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// const-eval of `panic_display` assumes the argument is `&&str`
if tcx.is_lang_item(callee, LangItem::PanicDisplay) {
match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
{}
_ => {
if let ty::Ref(_, ty, _) =
args[0].node.ty(&self.ccx.body.local_decls, tcx).kind()
&& let ty::Ref(_, ty, _) = ty.kind()
&& ty.is_str()
{
} else {
self.check_op(ops::PanicNonStr);
}
}
// Allow this call, skip all the checks below.
return;
}

View file

@ -30,20 +30,20 @@ pub use self::errors::ReportErrorExt;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) {
const_eval::provide(providers);
providers.tag_for_variant = const_eval::tag_for_variant_provider;
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
providers.eval_static_initializer = const_eval::eval_static_initializer_provider;
const_eval::provide(&mut providers.queries);
providers.queries.tag_for_variant = const_eval::tag_for_variant_provider;
providers.queries.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
providers.queries.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
providers.queries.eval_static_initializer = const_eval::eval_static_initializer_provider;
providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
providers.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| {
providers.queries.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| {
const_eval::eval_to_valtree(tcx, typing_env, value)
};
providers.hooks.try_destructure_mir_constant_for_user_output =
const_eval::try_destructure_mir_constant_for_user_output;
providers.valtree_to_const_val =
providers.queries.valtree_to_const_val =
|tcx, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv);
providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
providers.queries.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
};
providers.hooks.validate_scalar_in_layout =

View file

@ -880,36 +880,36 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) {
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
let providers = &mut Providers::default();
providers.analysis = analysis;
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
providers.resolver_for_lowering_raw = resolver_for_lowering_raw;
providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
providers.early_lint_checks = early_lint_checks;
providers.env_var_os = env_var_os;
limits::provide(providers);
proc_macro_decls::provide(providers);
providers.queries.analysis = analysis;
providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir;
providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw;
providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
providers.queries.early_lint_checks = early_lint_checks;
providers.queries.env_var_os = env_var_os;
limits::provide(&mut providers.queries);
proc_macro_decls::provide(&mut providers.queries);
rustc_const_eval::provide(providers);
rustc_middle::hir::provide(providers);
rustc_borrowck::provide(providers);
rustc_middle::hir::provide(&mut providers.queries);
rustc_borrowck::provide(&mut providers.queries);
rustc_incremental::provide(providers);
rustc_mir_build::provide(providers);
rustc_mir_transform::provide(providers);
rustc_monomorphize::provide(providers);
rustc_privacy::provide(providers);
rustc_privacy::provide(&mut providers.queries);
rustc_query_impl::provide(providers);
rustc_resolve::provide(providers);
rustc_hir_analysis::provide(providers);
rustc_hir_typeck::provide(providers);
ty::provide(providers);
traits::provide(providers);
solve::provide(providers);
rustc_passes::provide(providers);
rustc_traits::provide(providers);
rustc_ty_utils::provide(providers);
rustc_resolve::provide(&mut providers.queries);
rustc_hir_analysis::provide(&mut providers.queries);
rustc_hir_typeck::provide(&mut providers.queries);
ty::provide(&mut providers.queries);
traits::provide(&mut providers.queries);
solve::provide(&mut providers.queries);
rustc_passes::provide(&mut providers.queries);
rustc_traits::provide(&mut providers.queries);
rustc_ty_utils::provide(&mut providers.queries);
rustc_metadata::provide(providers);
rustc_lint::provide(providers);
rustc_symbol_mangling::provide(providers);
rustc_lint::provide(&mut providers.queries);
rustc_symbol_mangling::provide(&mut providers.queries);
rustc_codegen_ssa::provide(providers);
*providers
});

View file

@ -70,7 +70,7 @@ fn cargo_help_sub(
// `build_script_build`) to try to figure out if we are building a Cargo build script
let unescaped = &inst(EscapeQuotes::No);
if matches!(&sess.opts.crate_name, Some(crate_name) if crate_name == "build_script_build") {
if let Some("build_script_build") = sess.opts.crate_name.as_deref() {
lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped)
} else {
lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))

View file

@ -152,7 +152,9 @@ fn check_int_to_ptr_transmute<'tcx>(
return;
};
// bail-out if the argument is literal 0 as we have other lints for those cases
if matches!(arg.kind, hir::ExprKind::Lit(hir::Lit { node: LitKind::Int(v, _), .. }) if v == 0) {
if let hir::ExprKind::Lit(hir::Lit { node: LitKind::Int(v, _), .. }) = arg.kind
&& v == 0
{
return;
}
// bail-out if the inner type is a ZST

View file

@ -585,6 +585,6 @@ const SYMBOL_OFFSET: u8 = 1;
const SYMBOL_PREDEFINED: u8 = 2;
pub fn provide(providers: &mut Providers) {
encoder::provide(providers);
encoder::provide(&mut providers.queries);
decoder::provide(providers);
}

View file

@ -1871,13 +1871,16 @@ fn pretty_print_const_value_tcx<'tcx>(
let u8_type = tcx.types.u8;
match (ct, ty.kind()) {
// Byte/string slices, printed as (byte) string literals.
(_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
(_, ty::Ref(_, inner_ty, _)) if let ty::Str = inner_ty.kind() => {
if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
return Ok(());
}
}
(_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(t) if *t == u8_type) => {
(_, ty::Ref(_, inner_ty, _))
if let ty::Slice(t) = inner_ty.kind()
&& *t == u8_type =>
{
if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
pretty_print_byte_str(fmt, data)?;
return Ok(());

View file

@ -6,20 +6,3 @@ pub struct Providers {
pub extern_queries: crate::query::ExternProviders,
pub hooks: crate::hooks::Providers,
}
/// Backwards compatibility hack to keep the diff small. This
/// gives direct access to the `queries` field's fields, which
/// are what almost everything wants access to.
impl std::ops::DerefMut for Providers {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.queries
}
}
impl std::ops::Deref for Providers {
type Target = crate::query::Providers;
fn deref(&self) -> &Self::Target {
&self.queries
}
}

View file

@ -23,12 +23,12 @@ use rustc_middle::util::Providers;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) {
providers.check_match = thir::pattern::check_match;
providers.lit_to_const = thir::constant::lit_to_const;
providers.closure_saved_names_of_captured_variables =
providers.queries.check_match = thir::pattern::check_match;
providers.queries.lit_to_const = thir::constant::lit_to_const;
providers.queries.closure_saved_names_of_captured_variables =
builder::closure_saved_names_of_captured_variables;
providers.check_unsafety = check_unsafety::check_unsafety;
providers.check_tail_calls = check_tail_calls::check_tail_calls;
providers.thir_body = thir::cx::thir_body;
providers.queries.check_unsafety = check_unsafety::check_unsafety;
providers.queries.check_tail_calls = check_tail_calls::check_tail_calls;
providers.queries.thir_body = thir::cx::thir_body;
providers.hooks.build_mir_inner_impl = builder::build_mir_inner_impl;
}

View file

@ -206,9 +206,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) {
coverage::query::provide(providers);
ffi_unwind_calls::provide(providers);
shim::provide(providers);
cross_crate_inline::provide(providers);
ffi_unwind_calls::provide(&mut providers.queries);
shim::provide(&mut providers.queries);
cross_crate_inline::provide(&mut providers.queries);
providers.queries = query::Providers {
mir_keys,
mir_built,

View file

@ -1825,5 +1825,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
pub(crate) fn provide(providers: &mut Providers) {
providers.hooks.should_codegen_locally = should_codegen_locally;
providers.items_of_instance = items_of_instance;
providers.queries.items_of_instance = items_of_instance;
}

View file

@ -52,5 +52,5 @@ fn custom_coerce_unsize_info<'tcx>(
pub fn provide(providers: &mut Providers) {
partitioning::provide(providers);
mono_checks::provide(providers);
mono_checks::provide(&mut providers.queries);
}

View file

@ -1313,12 +1313,12 @@ fn dump_mono_items_stats<'tcx>(
}
pub(crate) fn provide(providers: &mut Providers) {
providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
providers.queries.collect_and_partition_mono_items = collect_and_partition_mono_items;
providers.is_codegened_item =
providers.queries.is_codegened_item =
|tcx, def_id| tcx.collect_and_partition_mono_items(()).all_mono_items.contains(&def_id);
providers.codegen_unit = |tcx, name| {
providers.queries.codegen_unit = |tcx, name| {
tcx.collect_and_partition_mono_items(())
.codegen_units
.iter()
@ -1326,7 +1326,7 @@ pub(crate) fn provide(providers: &mut Providers) {
.unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
};
providers.size_estimate = |tcx, instance| {
providers.queries.size_estimate = |tcx, instance| {
match instance.def {
// "Normal" functions size estimate: the number of
// statements, plus one for the terminator.

View file

@ -761,7 +761,9 @@ impl<'a> Parser<'a> {
}
// Check for misspelled keywords if there are no suggestions added to the diagnostic.
if matches!(&err.suggestions, Suggestions::Enabled(list) if list.is_empty()) {
if let Suggestions::Enabled(list) = &err.suggestions
&& list.is_empty()
{
self.check_for_misspelled_kw(&mut err, &expected);
}
Err(err)

View file

@ -1203,10 +1203,9 @@ impl<'a> Parser<'a> {
let mut token = Token::dummy();
while i < dist {
token = cursor.next().0;
if matches!(
token.kind,
token::OpenInvisible(origin) | token::CloseInvisible(origin) if origin.skip()
) {
if let token::OpenInvisible(origin) | token::CloseInvisible(origin) = token.kind
&& origin.skip()
{
continue;
}
i += 1;

View file

@ -9,7 +9,7 @@
#![feature(map_try_insert)]
// tidy-alphabetical-end
use rustc_middle::util::Providers;
use rustc_middle::query::Providers;
pub mod abi_test;
mod check_attr;

View file

@ -48,14 +48,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// and report an error in case of a collision.
pub(crate) fn plant_decl_into_local_module(
&mut self,
parent: Module<'ra>,
ident: Macros20NormalizedIdent,
ns: Namespace,
decl: Decl<'ra>,
) {
if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false)
{
self.report_conflict(parent, ident.0, ns, old_decl, decl);
if let Err(old_decl) = self.try_plant_decl_into_local_module(ident, ns, decl, false) {
self.report_conflict(ident.0, ns, old_decl, decl);
}
}
@ -70,9 +68,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
span: Span,
expn_id: LocalExpnId,
) {
let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id);
let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id, Some(parent));
let ident = Macros20NormalizedIdent::new(ident);
self.plant_decl_into_local_module(parent, ident, ns, decl);
self.plant_decl_into_local_module(ident, ns, decl);
}
/// Create a name definitinon from the given components, and put it into the extern module.
@ -96,6 +94,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
vis: CmCell::new(vis),
span,
expansion,
parent_module: Some(parent),
});
// Even if underscore names cannot be looked up, we still need to add them to modules,
// because they can be fetched by glob imports from those modules, and bring traits
@ -289,7 +288,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
let span = child_span(self, reexport_chain, res);
let res = res.expect_non_local();
self.arenas.new_def_decl(res, vis, span, expansion)
self.arenas.new_def_decl(res, vis, span, expansion, Some(parent))
});
// Record primary definitions.
@ -844,7 +843,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ident,
local_def_id,
vis,
parent,
);
}
@ -976,10 +974,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
ident: Ident,
local_def_id: LocalDefId,
vis: Visibility,
parent: Module<'ra>,
) {
let sp = item.span;
let parent_scope = self.parent_scope;
let parent = parent_scope.module;
let expansion = parent_scope.expansion;
let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower {
@ -1009,7 +1007,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let import = self.r.arenas.alloc_import(ImportData {
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
root_id: item.id,
parent_scope: self.parent_scope,
parent_scope,
imported_module: CmCell::new(module),
has_attributes: !item.attrs.is_empty(),
use_span_with_attributes: item.span_with_attributes(),
@ -1057,7 +1055,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}),
};
}
self.r.plant_decl_into_local_module(parent, ident, TypeNS, import_decl);
self.r.plant_decl_into_local_module(ident, TypeNS, import_decl);
}
/// Constructs the reduced graph for one foreign item.
@ -1300,14 +1298,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
} else {
Visibility::Restricted(CRATE_DEF_ID)
};
let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion);
self.r.set_decl_parent_module(decl, parent_scope.module);
let decl = self.r.arenas.new_def_decl(
res,
vis.to_def_id(),
span,
expansion,
Some(parent_scope.module),
);
self.r.all_macro_rules.insert(ident.name);
if is_macro_export {
let import = self.r.arenas.alloc_import(ImportData {
kind: ImportKind::MacroExport,
root_id: item.id,
parent_scope: self.parent_scope,
parent_scope: ParentScope { module: self.r.graph_root, ..parent_scope },
imported_module: CmCell::new(None),
has_attributes: false,
use_span_with_attributes: span,
@ -1320,7 +1323,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
});
self.r.import_use_map.insert(import, Used::Other);
let import_decl = self.r.new_import_decl(decl, import);
self.r.plant_decl_into_local_module(self.r.graph_root, ident, MacroNS, import_decl);
self.r.plant_decl_into_local_module(ident, MacroNS, import_decl);
} else {
self.r.check_reserved_macro_name(ident.0, res);
self.insert_unused_macro(ident.0, def_id, item.id);

View file

@ -210,7 +210,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub(crate) fn report_conflict(
&mut self,
parent: Module<'_>,
ident: Ident,
ns: Namespace,
new_binding: Decl<'ra>,
@ -218,13 +217,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
) {
// Error on the second of two conflicting names
if old_binding.span.lo() > new_binding.span.lo() {
return self.report_conflict(parent, ident, ns, old_binding, new_binding);
return self.report_conflict(ident, ns, old_binding, new_binding);
}
let container = match parent.kind {
let container = match old_binding.parent_module.unwrap().kind {
// Avoid using TyCtxt::def_kind_descr in the resolver, because it
// indirectly *calls* the resolver, and would cause a query cycle.
ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
ModuleKind::Def(kind, def_id, _) => kind.descr(def_id),
ModuleKind::Block => "block",
};
@ -2034,17 +2033,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously"))
}
if kind != AmbiguityKind::GlobVsGlob {
if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope {
if module == self.graph_root {
help_msgs.push(format!(
"use `crate::{ident}` to refer to this {thing} unambiguously"
));
} else if module != self.empty_module && module.is_normal() {
} else if module.is_normal() {
help_msgs.push(format!(
"use `self::{ident}` to refer to this {thing} unambiguously"
));
}
}
}
(
Spanned { node: note_msg, span: b.span },

View file

@ -867,6 +867,19 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg {
pub applicability: Applicability,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
resolve_unexpected_res_change_ty_to_const_param_sugg,
applicability = "has-placeholders",
style = "verbose"
)]
pub(crate) struct UnexpectedResChangeTyParamToConstParamSugg {
#[suggestion_part(code = "const ")]
pub before: Span,
#[suggestion_part(code = ": /* Type */")]
pub after: Span,
}
#[derive(Subdiagnostic)]
#[suggestion(
resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg,

View file

@ -340,6 +340,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
span: import.span,
vis: CmCell::new(vis),
expansion: import.parent_scope.expansion,
parent_module: Some(import.parent_scope.module),
})
}
@ -409,15 +410,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// and return existing declaration if there is a collision.
pub(crate) fn try_plant_decl_into_local_module(
&mut self,
module: Module<'ra>,
ident: Macros20NormalizedIdent,
ns: Namespace,
decl: Decl<'ra>,
warn_ambiguity: bool,
) -> Result<(), Decl<'ra>> {
let module = decl.parent_module.unwrap();
let res = decl.res();
self.check_reserved_macro_name(ident.0, res);
self.set_decl_parent_module(decl, module);
// Even if underscore names cannot be looked up, we still need to add them to modules,
// because they can be fetched by glob imports from those modules, and bring traits
// into scope both directly and through glob imports.
@ -511,7 +511,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if self.is_accessible_from(binding.vis(), scope) {
let import_decl = self.new_import_decl(binding, *import);
let _ = self.try_plant_decl_into_local_module(
import.parent_scope.module,
ident,
key.ns,
import_decl,
@ -535,7 +534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.per_ns(|this, ns| {
let module = import.parent_scope.module;
let ident = Macros20NormalizedIdent::new(target);
let _ = this.try_plant_decl_into_local_module(module, ident, ns, dummy_decl, false);
let _ = this.try_plant_decl_into_local_module(ident, ns, dummy_decl, false);
// Don't remove underscores from `single_imports`, they were never added.
if target.name != kw::Underscore {
let key = BindingKey::new(ident, ns);
@ -916,7 +915,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// We need the `target`, `source` can be extracted.
let import_decl = this.new_import_decl(binding, import);
this.get_mut_unchecked().plant_decl_into_local_module(
parent,
Macros20NormalizedIdent::new(target),
ns,
import_decl,
@ -1542,7 +1540,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.and_then(|r| r.binding())
.is_some_and(|binding| binding.warn_ambiguity_recursive());
let _ = self.try_plant_decl_into_local_module(
import.parent_scope.module,
key.ident,
key.ns,
import_decl,

View file

@ -414,6 +414,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
/// Handles error reporting for `smart_resolve_path_fragment` function.
/// Creates base error and amends it with one short label and possibly some longer helps/notes.
#[tracing::instrument(skip(self), level = "debug")]
pub(crate) fn smart_resolve_report_errors(
&mut self,
path: &[Segment],
@ -451,7 +452,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect);
}
self.suggest_changing_type_to_const_param(&mut err, res, source, span);
self.suggest_changing_type_to_const_param(&mut err, res, source, path, following_seg, span);
self.explain_functions_in_pattern(&mut err, res, source);
if self.suggest_pattern_match_with_let(&mut err, source, span) {
@ -1505,8 +1506,40 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
err: &mut Diag<'_>,
res: Option<Res>,
source: PathSource<'_, '_, '_>,
path: &[Segment],
following_seg: Option<&Segment>,
span: Span,
) {
if let PathSource::Expr(None) = source
&& let Some(Res::Def(DefKind::TyParam, _)) = res
&& following_seg.is_none()
&& let [segment] = path
{
// We have something like
// impl<T, N> From<[T; N]> for VecWrapper<T> {
// fn from(slice: [T; N]) -> Self {
// VecWrapper(slice.to_vec())
// }
// }
// where `N` is a type param but should likely have been a const param.
let Some(item) = self.diag_metadata.current_item else { return };
let Some(generics) = item.kind.generics() else { return };
let Some(span) = generics.params.iter().find_map(|param| {
// Only consider type params with no bounds.
if param.bounds.is_empty() && param.ident.name == segment.ident.name {
Some(param.ident.span)
} else {
None
}
}) else {
return;
};
err.subdiagnostic(errors::UnexpectedResChangeTyParamToConstParamSugg {
before: span.shrink_to_lo(),
after: span.shrink_to_hi(),
});
return;
}
let PathSource::Trait(_) = source else { return };
// We don't include `DefKind::Str` and `DefKind::AssocTy` as they can't be reached here anyway.

View file

@ -67,7 +67,6 @@ use rustc_metadata::creader::CStore;
use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::query::Providers;
use rustc_middle::span_bug;
use rustc_middle::ty::{
self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools,
ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
@ -812,6 +811,7 @@ struct DeclData<'ra> {
expansion: LocalExpnId,
span: Span,
vis: CmCell<Visibility<DefId>>,
parent_module: Option<Module<'ra>>,
}
/// All name declarations are unique and allocated on a same arena,
@ -922,7 +922,6 @@ struct AmbiguityError<'ra> {
ident: Ident,
b1: Decl<'ra>,
b2: Decl<'ra>,
// `empty_module` in module scope serves as an unknown module here.
scope1: Scope<'ra>,
scope2: Scope<'ra>,
warning: Option<AmbiguityWarning>,
@ -1186,7 +1185,6 @@ pub struct Resolver<'ra, 'tcx> {
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
/// Lazily populated cache of modules loaded from external crates.
extern_module_map: CacheRefCell<FxIndexMap<DefId, Module<'ra>>>,
decl_parent_modules: FxHashMap<Decl<'ra>, Module<'ra>>,
/// Maps glob imports to the names of items actually imported.
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
@ -1349,6 +1347,7 @@ impl<'ra> ResolverArenas<'ra> {
vis: Visibility<DefId>,
span: Span,
expansion: LocalExpnId,
parent_module: Option<Module<'ra>>,
) -> Decl<'ra> {
self.alloc_decl(DeclData {
kind: DeclKind::Def(res),
@ -1357,11 +1356,12 @@ impl<'ra> ResolverArenas<'ra> {
vis: CmCell::new(vis),
span,
expansion,
parent_module,
})
}
fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> {
self.new_def_decl(res, Visibility::Public, span, expn_id)
self.new_def_decl(res, Visibility::Public, span, expn_id, None)
}
fn new_module(
@ -1616,7 +1616,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
local_module_map,
extern_module_map: Default::default(),
block_map: Default::default(),
decl_parent_modules: FxHashMap::default(),
ast_transform_scopes: FxHashMap::default(),
glob_map: Default::default(),
@ -2071,8 +2070,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
b1: used_decl,
b2,
scope1: Scope::ModuleGlobs(self.empty_module, None),
scope2: Scope::ModuleGlobs(self.empty_module, None),
scope1: Scope::ModuleGlobs(used_decl.parent_module.unwrap(), None),
scope2: Scope::ModuleGlobs(b2.parent_module.unwrap(), None),
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
};
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
@ -2237,14 +2236,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
}
fn set_decl_parent_module(&mut self, decl: Decl<'ra>, module: Module<'ra>) {
if let Some(old_module) = self.decl_parent_modules.insert(decl, module) {
if module != old_module {
span_bug!(decl.span, "parent module is reset for a name declaration");
}
}
}
fn disambiguate_macro_rules_vs_modularized(
&self,
macro_rules: Decl<'ra>,
@ -2254,13 +2245,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// is disambiguated to mitigate regressions from macro modularization.
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
//
// panic on index should be impossible, the only name_bindings passed in should be from
// Panic on unwrap should be impossible, the only name_bindings passed in should be from
// `resolve_ident_in_scope_set` which will always refer to a local binding from an
// import or macro definition
let macro_rules = &self.decl_parent_modules[&macro_rules];
let modularized = &self.decl_parent_modules[&modularized];
// import or macro definition.
let macro_rules = macro_rules.parent_module.unwrap();
let modularized = modularized.parent_module.unwrap();
macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
&& modularized.is_ancestor_of(*macro_rules)
&& modularized.is_ancestor_of(macro_rules)
}
fn extern_prelude_get_item<'r>(

View file

@ -681,7 +681,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// Ambiguous predicates should never error
| ty::PredicateKind::Ambiguous
// We never return Err when proving UnstableFeature goal.
| ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature{ .. })
| ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })
| ty::PredicateKind::NormalizesTo { .. }
| ty::PredicateKind::AliasRelate { .. }
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {

View file

@ -4759,7 +4759,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// slices of `element_ty` with `mutability`.
let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
ty::RawPtr(t, m) | ty::Ref(_, t, m) => {
if matches!(*t.kind(), ty::Slice(e) if e == element_ty)
if let ty::Slice(e) = *t.kind()
&& e == element_ty
&& m == mutability.unwrap_or(m)
{
// Use the candidate's mutability going forward.
@ -5549,7 +5550,14 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
};
if let ty::PredicatePolarity::Positive = trait_predicate.polarity() {
format!(
"{pre_message}the trait `{}` is not implemented for{desc} `{}`",
"{pre_message}the {}trait `{}` is not implemented for{desc} `{}`",
if tcx.lookup_stability(trait_predicate.def_id()).map(|s| s.level.is_stable())
== Some(false)
{
"nightly-only, unstable "
} else {
""
},
trait_predicate.print_modifiers_and_trait_path(),
tcx.short_string(trait_predicate.self_ty().skip_binder(), long_ty_path),
)

View file

@ -466,7 +466,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Default for BinaryHeap<T> {
impl<T> Default for BinaryHeap<T> {
/// Creates an empty `BinaryHeap<T>`.
#[inline]
fn default() -> BinaryHeap<T> {
@ -496,7 +496,7 @@ impl<T: Ord, A: Allocator> Drop for RebuildOnDrop<'_, T, A> {
}
}
impl<T: Ord> BinaryHeap<T> {
impl<T> BinaryHeap<T> {
/// Creates an empty `BinaryHeap` as a max-heap.
///
/// # Examples
@ -537,7 +537,7 @@ impl<T: Ord> BinaryHeap<T> {
}
}
impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
impl<T, A: Allocator> BinaryHeap<T, A> {
/// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator.
///
/// # Examples
@ -581,7 +581,9 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap<T, A> {
BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) }
}
}
impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
/// Returns a mutable reference to the greatest item in the binary heap, or
/// `None` if it is empty.
///

View file

@ -1143,11 +1143,12 @@ impl char {
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
///
/// # Examples
/// `'ſt'` (U+FB05) is a single Unicode code point (a ligature) that maps to "ST" in uppercase.
///
/// As an iterator:
///
/// ```
/// for c in 'ß'.to_uppercase() {
/// for c in ''.to_uppercase() {
/// print!("{c}");
/// }
/// println!();
@ -1156,13 +1157,13 @@ impl char {
/// Using `println!` directly:
///
/// ```
/// println!("{}", 'ß'.to_uppercase());
/// println!("{}", ''.to_uppercase());
/// ```
///
/// Both are equivalent to:
///
/// ```
/// println!("SS");
/// println!("ST");
/// ```
///
/// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
@ -1171,7 +1172,7 @@ impl char {
/// assert_eq!('c'.to_uppercase().to_string(), "C");
///
/// // Sometimes the result is more than one character:
/// assert_eq!('ß'.to_uppercase().to_string(), "SS");
/// assert_eq!('ſt'.to_uppercase().to_string(), "ST");
///
/// // Characters that do not have both uppercase and lowercase
/// // convert into themselves.

View file

@ -21,6 +21,13 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6
/// The *successor* operation moves towards values that compare greater.
/// The *predecessor* operation moves towards values that compare lesser.
#[rustc_diagnostic_item = "range_step"]
#[rustc_on_unimplemented(
message = "`std::ops::Range<{Self}>` is not an iterator",
label = "`Range<{Self}>` is not an iterator",
note = "`Range` only implements `Iterator` for select types in the standard library, \
particularly integers; to see the full list of types, see the documentation for the \
unstable `Step` trait"
)]
#[unstable(feature = "step_trait", issue = "42168")]
pub trait Step: Clone + PartialOrd + Sized {
/// Returns the bounds on the number of *successor* steps required to get from `start` to `end`

View file

@ -653,7 +653,7 @@ impl Error {
#[must_use]
#[inline]
pub fn last_os_error() -> Error {
Error::from_raw_os_error(sys::os::errno())
Error::from_raw_os_error(sys::io::errno())
}
/// Creates a new instance of an [`Error`] from a particular OS error code.
@ -1004,7 +1004,7 @@ impl Error {
#[inline]
pub fn kind(&self) -> ErrorKind {
match self.repr.data() {
ErrorData::Os(code) => sys::decode_error_kind(code),
ErrorData::Os(code) => sys::io::decode_error_kind(code),
ErrorData::Custom(c) => c.kind,
ErrorData::Simple(kind) => kind,
ErrorData::SimpleMessage(m) => m.kind,
@ -1014,7 +1014,7 @@ impl Error {
#[inline]
pub(crate) fn is_interrupted(&self) -> bool {
match self.repr.data() {
ErrorData::Os(code) => sys::is_interrupted(code),
ErrorData::Os(code) => sys::io::is_interrupted(code),
ErrorData::Custom(c) => c.kind == ErrorKind::Interrupted,
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
@ -1028,8 +1028,8 @@ impl fmt::Debug for Repr {
ErrorData::Os(code) => fmt
.debug_struct("Os")
.field("code", &code)
.field("kind", &sys::decode_error_kind(code))
.field("message", &sys::os::error_string(code))
.field("kind", &sys::io::decode_error_kind(code))
.field("message", &sys::io::error_string(code))
.finish(),
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
@ -1047,7 +1047,7 @@ impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.repr.data() {
ErrorData::Os(code) => {
let detail = sys::os::error_string(code);
let detail = sys::io::error_string(code);
write!(fmt, "{detail} (os error {code})")
}
ErrorData::Custom(ref c) => c.error.fmt(fmt),

View file

@ -1,7 +1,6 @@
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
use crate::assert_matches::assert_matches;
use crate::sys::decode_error_kind;
use crate::sys::os::error_string;
use crate::sys::io::{decode_error_kind, error_string};
use crate::{error, fmt};
#[test]

View file

@ -95,8 +95,8 @@ mod uefi_env {
val_ptr: *mut r_efi::efi::Char16,
) -> io::Result<()> {
let shell = helpers::open_shell().ok_or(unsupported_err())?;
let r =
unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, r_efi::efi::Boolean::FALSE) };
let volatile = r_efi::efi::Boolean::TRUE;
let r = unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, volatile) };
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
}
}

View file

@ -34,7 +34,7 @@ cfg_select! {
// lifetime of the thread. Additionally, accesses to `errno` are
// async-signal-safe, so this function is available in all imaginable
// circumstances.
let this_thread_id = crate::sys::os::errno_location();
let this_thread_id = crate::sys::io::errno_location();
match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
Ok(_) => {
// This is the first thread to call `unique_thread_exit`,

View file

@ -850,7 +850,7 @@ impl Iterator for ReadDir {
target_os = "wasi",
))]
fn next(&mut self) -> Option<io::Result<DirEntry>> {
use crate::sys::os::{errno, set_errno};
use crate::sys::io::{errno, set_errno};
if self.end_of_stream {
return None;
@ -988,7 +988,7 @@ impl Iterator for ReadDir {
/// The downside is that it costs an extra syscall, so we only do it for debug.
#[inline]
pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
use crate::sys::os::errno;
use crate::sys::io::errno;
// this is similar to assert_unsafe_precondition!() but it doesn't require const
if core::ub_checks::check_library_ub() {

View file

@ -0,0 +1,15 @@
pub fn errno() -> i32 {
0
}
pub fn is_interrupted(_code: i32) -> bool {
false
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}
pub fn error_string(_errno: i32) -> String {
"operation successful".to_string()
}

View file

@ -0,0 +1,35 @@
use crate::io;
pub fn errno() -> i32 {
unsafe { hermit_abi::get_errno() }
}
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == hermit_abi::errno::EINTR
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
match errno {
hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
_ => io::ErrorKind::Uncategorized,
}
}
pub fn error_string(errno: i32) -> String {
hermit_abi::error_string(errno).to_string()
}

View file

@ -0,0 +1,55 @@
cfg_select! {
target_os = "hermit" => {
mod hermit;
pub use hermit::*;
}
target_os = "motor" => {
mod motor;
pub use motor::*;
}
all(target_vendor = "fortanix", target_env = "sgx") => {
mod sgx;
pub use sgx::*;
}
target_os = "solid_asp3" => {
mod solid;
pub use solid::*;
}
target_os = "teeos" => {
mod teeos;
pub use teeos::*;
}
target_os = "uefi" => {
mod uefi;
pub use uefi::*;
}
target_family = "unix" => {
mod unix;
pub use unix::*;
}
target_os = "wasi" => {
mod wasi;
pub use wasi::*;
}
target_os = "windows" => {
mod windows;
pub use windows::*;
}
target_os = "xous" => {
mod xous;
pub use xous::*;
}
any(
target_os = "vexos",
target_family = "wasm",
target_os = "zkvm",
) => {
mod generic;
pub use generic::*;
}
}
pub type RawOsError = cfg_select! {
target_os = "uefi" => usize,
_ => i32,
};

View file

@ -0,0 +1,67 @@
use crate::io;
use crate::sys::io::RawOsError;
pub fn errno() -> RawOsError {
// Not used in Motor OS because it is ambiguous: Motor OS
// is micro-kernel-based, and I/O happens via a shared-memory
// ring buffer, so an I/O operation that on a unix is a syscall
// may involve no sycalls on Motor OS at all, or a syscall
// that e.g. waits for a notification from the I/O driver
// (sys-io); and the wait syscall may succeed, but the
// driver may report an I/O error; or a bunch of results
// for several I/O operations, some successful and some
// not.
//
// Also I/O operations in a Motor OS process are handled by a
// separate runtime background/I/O thread, so it is really hard
// to define what "last system error in the current thread"
// actually means.
let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
error_code.into()
}
pub fn is_interrupted(_code: io::RawOsError) -> bool {
false // Motor OS doesn't have signals.
}
pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
if code < 0 || code > u16::MAX.into() {
return io::ErrorKind::Uncategorized;
}
let error = moto_rt::Error::from(code as moto_rt::ErrorCode);
match error {
moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
moto_rt::Error::NotFound => io::ErrorKind::NotFound,
moto_rt::Error::InternalError => io::ErrorKind::Other,
moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
_ => io::ErrorKind::Uncategorized,
}
}
pub fn error_string(errno: RawOsError) -> String {
let error: moto_rt::Error = match errno {
x if x < 0 => moto_rt::Error::Unknown,
x if x > u16::MAX.into() => moto_rt::Error::Unknown,
x => (x as moto_rt::ErrorCode).into(), /* u16 */
};
format!("{}", error)
}

View file

@ -0,0 +1,65 @@
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
use crate::io;
pub fn errno() -> i32 {
RESULT_SUCCESS
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
code == fortanix_sgx_abi::Error::Interrupted as _
}
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
// FIXME: not sure how to make sure all variants of Error are covered
if code == Error::NotFound as _ {
io::ErrorKind::NotFound
} else if code == Error::PermissionDenied as _ {
io::ErrorKind::PermissionDenied
} else if code == Error::ConnectionRefused as _ {
io::ErrorKind::ConnectionRefused
} else if code == Error::ConnectionReset as _ {
io::ErrorKind::ConnectionReset
} else if code == Error::ConnectionAborted as _ {
io::ErrorKind::ConnectionAborted
} else if code == Error::NotConnected as _ {
io::ErrorKind::NotConnected
} else if code == Error::AddrInUse as _ {
io::ErrorKind::AddrInUse
} else if code == Error::AddrNotAvailable as _ {
io::ErrorKind::AddrNotAvailable
} else if code == Error::BrokenPipe as _ {
io::ErrorKind::BrokenPipe
} else if code == Error::AlreadyExists as _ {
io::ErrorKind::AlreadyExists
} else if code == Error::WouldBlock as _ {
io::ErrorKind::WouldBlock
} else if code == Error::InvalidInput as _ {
io::ErrorKind::InvalidInput
} else if code == Error::InvalidData as _ {
io::ErrorKind::InvalidData
} else if code == Error::TimedOut as _ {
io::ErrorKind::TimedOut
} else if code == Error::WriteZero as _ {
io::ErrorKind::WriteZero
} else if code == Error::Interrupted as _ {
io::ErrorKind::Interrupted
} else if code == Error::Other as _ {
io::ErrorKind::Uncategorized
} else if code == Error::UnexpectedEof as _ {
io::ErrorKind::UnexpectedEof
} else {
io::ErrorKind::Uncategorized
}
}
pub fn error_string(errno: i32) -> String {
if errno == RESULT_SUCCESS {
"operation successful".into()
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
format!("user-specified error {errno:08x}")
} else {
decode_error_kind(errno).as_str().into()
}
}

View file

@ -0,0 +1,19 @@
use crate::io;
use crate::sys::pal::error;
pub fn errno() -> i32 {
0
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
crate::sys::net::is_interrupted(code)
}
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
error::decode_error_kind(code)
}
pub fn error_string(errno: i32) -> String {
if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
}

View file

@ -0,0 +1,64 @@
use crate::io;
pub fn errno() -> i32 {
unsafe { (*libc::__errno_location()) as i32 }
}
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
// Note: code below is 1:1 copied from unix/mod.rs
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
libc::ENOTEMPTY => DirectoryNotEmpty,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EACCES | libc::EPERM => PermissionDenied,
// These two constants can have the same value on some systems,
// but different values on others, so we can't use a match
// clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
pub fn error_string(_errno: i32) -> String {
"error string unimplemented".to_string()
}

View file

@ -0,0 +1,104 @@
use r_efi::efi::Status;
use crate::io;
pub fn errno() -> io::RawOsError {
0
}
pub fn is_interrupted(_code: io::RawOsError) -> bool {
false
}
pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
match Status::from_usize(code) {
Status::ALREADY_STARTED
| Status::COMPROMISED_DATA
| Status::CONNECTION_FIN
| Status::CRC_ERROR
| Status::DEVICE_ERROR
| Status::END_OF_MEDIA
| Status::HTTP_ERROR
| Status::ICMP_ERROR
| Status::INCOMPATIBLE_VERSION
| Status::LOAD_ERROR
| Status::MEDIA_CHANGED
| Status::NO_MAPPING
| Status::NO_MEDIA
| Status::NOT_STARTED
| Status::PROTOCOL_ERROR
| Status::PROTOCOL_UNREACHABLE
| Status::TFTP_ERROR
| Status::VOLUME_CORRUPTED => io::ErrorKind::Other,
Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData,
Status::ABORTED => io::ErrorKind::ConnectionAborted,
Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied,
Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge,
Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused,
Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset,
Status::END_OF_FILE => io::ErrorKind::UnexpectedEof,
Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable,
Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput,
Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse,
Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable,
Status::NO_RESPONSE => io::ErrorKind::HostUnreachable,
Status::NOT_FOUND => io::ErrorKind::NotFound,
Status::NOT_READY => io::ErrorKind::ResourceBusy,
Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory,
Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied,
Status::TIMEOUT => io::ErrorKind::TimedOut,
Status::UNSUPPORTED => io::ErrorKind::Unsupported,
Status::VOLUME_FULL => io::ErrorKind::StorageFull,
Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem,
_ => io::ErrorKind::Uncategorized,
}
}
pub fn error_string(errno: io::RawOsError) -> String {
// Keep the List in Alphabetical Order
// The Messages are taken from UEFI Specification Appendix D - Status Codes
#[rustfmt::skip]
let msg = match Status::from_usize(errno) {
Status::ABORTED => "The operation was aborted.",
Status::ACCESS_DENIED => "Access was denied.",
Status::ALREADY_STARTED => "The protocol has already been started.",
Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.",
Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.",
Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.",
Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.",
Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.",
Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.",
Status::CRC_ERROR => "A CRC error was detected.",
Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.",
Status::END_OF_FILE => "The end of the file was reached.",
Status::END_OF_MEDIA => "Beginning or end of media was reached",
Status::HOST_UNREACHABLE => "The remote host is not reachable.",
Status::HTTP_ERROR => "A HTTP error occurred during the network operation.",
Status::ICMP_ERROR => "An ICMP error occurred during the network operation.",
Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.",
Status::INVALID_LANGUAGE => "The language specified was invalid.",
Status::INVALID_PARAMETER => "A parameter was incorrect.",
Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation",
Status::LOAD_ERROR => "The image failed to load.",
Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.",
Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.",
Status::NO_MAPPING => "A mapping to a device does not exist.",
Status::NO_MEDIA => "The device does not contain any medium to perform the operation.",
Status::NO_RESPONSE => "The server was not found or did not respond to the request.",
Status::NOT_FOUND => "The item was not found.",
Status::NOT_READY => "There is no data pending upon return.",
Status::NOT_STARTED => "The protocol has not been started.",
Status::OUT_OF_RESOURCES => "A resource has run out.",
Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.",
Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.",
Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.",
Status::TFTP_ERROR => "A TFTP error occurred during the network operation.",
Status::TIMEOUT => "The timeout time expired.",
Status::UNSUPPORTED => "The operation is not supported.",
Status::VOLUME_FULL => "There is no more space on the file system.",
Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.",
Status::WRITE_PROTECTED => "The device cannot be written to.",
_ => return format!("Status: {errno}"),
};
msg.to_owned()
}

View file

@ -0,0 +1,186 @@
use crate::ffi::{CStr, c_char, c_int};
use crate::io;
unsafe extern "C" {
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[cfg_attr(
any(
target_os = "linux",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "l4re",
target_os = "hurd",
),
link_name = "__errno_location"
)]
#[cfg_attr(
any(
target_os = "netbsd",
target_os = "openbsd",
target_os = "cygwin",
target_os = "android",
target_os = "redox",
target_os = "nuttx",
target_env = "newlib"
),
link_name = "__errno"
)]
#[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
#[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")]
#[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
#[cfg_attr(target_os = "aix", link_name = "_Errno")]
// SAFETY: this will always return the same pointer on a given thread.
#[unsafe(ffi_const)]
pub safe fn errno_location() -> *mut c_int;
}
/// Returns the platform-specific value of errno
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[inline]
pub fn errno() -> i32 {
unsafe { (*errno_location()) as i32 }
}
/// Sets the platform-specific value of errno
// needed for readdir and syscall!
#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
#[allow(dead_code)] // but not all target cfgs actually end up using it
#[inline]
pub fn set_errno(e: i32) {
unsafe { *errno_location() = e as c_int }
}
#[cfg(target_os = "vxworks")]
#[inline]
pub fn errno() -> i32 {
unsafe { libc::errnoGet() }
}
#[cfg(target_os = "rtems")]
#[inline]
pub fn errno() -> i32 {
unsafe extern "C" {
#[thread_local]
static _tls_errno: c_int;
}
unsafe { _tls_errno as i32 }
}
#[cfg(target_os = "dragonfly")]
#[inline]
pub fn errno() -> i32 {
unsafe extern "C" {
#[thread_local]
static errno: c_int;
}
unsafe { errno as i32 }
}
#[cfg(target_os = "dragonfly")]
#[allow(dead_code)]
#[inline]
pub fn set_errno(e: i32) {
unsafe extern "C" {
#[thread_local]
static mut errno: c_int;
}
unsafe {
errno = e;
}
}
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
#[cfg(not(target_os = "aix"))]
libc::ENOTEMPTY => DirectoryNotEmpty,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EINPROGRESS => InProgress,
libc::EOPNOTSUPP => Unsupported,
libc::EACCES | libc::EPERM => PermissionDenied,
// These two constants can have the same value on some systems,
// but different values on others, so we can't use a match
// clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
/// Gets a detailed string description for the given error number.
pub fn error_string(errno: i32) -> String {
const TMPBUF_SZ: usize = 128;
unsafe extern "C" {
#[cfg_attr(
all(
any(
target_os = "linux",
target_os = "hurd",
target_env = "newlib",
target_os = "cygwin"
),
not(target_env = "ohos")
),
link_name = "__xpg_strerror_r"
)]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
}
let mut buf = [0 as c_char; TMPBUF_SZ];
let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
let p = p as *const _;
// We can't always expect a UTF-8 environment. When we don't get that luxury,
// it's better to give a low-quality error message than none at all.
String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into()
}
}

View file

@ -0,0 +1,80 @@
use crate::ffi::CStr;
use crate::io as std_io;
unsafe extern "C" {
#[thread_local]
#[link_name = "errno"]
static mut libc_errno: libc::c_int;
}
pub fn errno() -> i32 {
unsafe { libc_errno as i32 }
}
pub fn set_errno(val: i32) {
unsafe {
libc_errno = val;
}
}
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EINPROGRESS => InProgress,
libc::EOPNOTSUPP => Unsupported,
libc::EACCES | libc::EPERM => PermissionDenied,
libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
pub fn error_string(errno: i32) -> String {
let mut buf = [0 as libc::c_char; 1024];
let p = buf.as_mut_ptr();
unsafe {
if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
}
}

View file

@ -0,0 +1,140 @@
use crate::sys::pal::{api, c};
use crate::{io, ptr};
pub fn errno() -> i32 {
api::get_last_error().code as i32
}
#[inline]
pub fn is_interrupted(_errno: i32) -> bool {
false
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as u32 {
c::ERROR_ACCESS_DENIED => return PermissionDenied,
c::ERROR_ALREADY_EXISTS => return AlreadyExists,
c::ERROR_FILE_EXISTS => return AlreadyExists,
c::ERROR_BROKEN_PIPE => return BrokenPipe,
c::ERROR_FILE_NOT_FOUND
| c::ERROR_PATH_NOT_FOUND
| c::ERROR_INVALID_DRIVE
| c::ERROR_BAD_NETPATH
| c::ERROR_BAD_NET_NAME => return NotFound,
c::ERROR_NO_DATA => return BrokenPipe,
c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
c::ERROR_INVALID_PARAMETER => return InvalidInput,
c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
c::ERROR_SEM_TIMEOUT
| c::WAIT_TIMEOUT
| c::ERROR_DRIVER_CANCEL_TIMEOUT
| c::ERROR_OPERATION_ABORTED
| c::ERROR_SERVICE_REQUEST_TIMEOUT
| c::ERROR_COUNTER_TIMEOUT
| c::ERROR_TIMEOUT
| c::ERROR_RESOURCE_CALL_TIMED_OUT
| c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
| c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
| c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
| c::ERROR_DS_TIMELIMIT_EXCEEDED
| c::DNS_ERROR_RECORD_TIMED_OUT
| c::ERROR_IPSEC_IKE_TIMED_OUT
| c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
| c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
c::ERROR_DIRECTORY => return NotADirectory,
c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded,
c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
c::ERROR_BUSY => return ResourceBusy,
c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
_ => {}
}
match errno {
c::WSAEACCES => PermissionDenied,
c::WSAEADDRINUSE => AddrInUse,
c::WSAEADDRNOTAVAIL => AddrNotAvailable,
c::WSAECONNABORTED => ConnectionAborted,
c::WSAECONNREFUSED => ConnectionRefused,
c::WSAECONNRESET => ConnectionReset,
c::WSAEINVAL => InvalidInput,
c::WSAENOTCONN => NotConnected,
c::WSAEWOULDBLOCK => WouldBlock,
c::WSAETIMEDOUT => TimedOut,
c::WSAEHOSTUNREACH => HostUnreachable,
c::WSAENETDOWN => NetworkDown,
c::WSAENETUNREACH => NetworkUnreachable,
c::WSAEDQUOT => QuotaExceeded,
_ => Uncategorized,
}
}
/// Gets a detailed string description for the given error number.
pub fn error_string(mut errnum: i32) -> String {
let mut buf = [0 as c::WCHAR; 2048];
unsafe {
let mut module = ptr::null_mut();
let mut flags = 0;
// NTSTATUS errors may be encoded as HRESULT, which may returned from
// GetLastError. For more information about Windows error codes, see
// `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
// format according to https://support.microsoft.com/en-us/help/259693
const NTDLL_DLL: &[u16] = &[
'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
'L' as _, 0,
];
module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
if !module.is_null() {
errnum ^= c::FACILITY_NT_BIT as i32;
flags = c::FORMAT_MESSAGE_FROM_HMODULE;
}
}
let res = c::FormatMessageW(
flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
module,
errnum as u32,
0,
buf.as_mut_ptr(),
buf.len() as u32,
ptr::null(),
) as usize;
if res == 0 {
// Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId,
let fm_err = errno();
return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
}
match String::from_utf16(&buf[..res]) {
Ok(mut msg) => {
// Trim trailing CRLF inserted by FormatMessageW
let len = msg.trim_end().len();
msg.truncate(len);
msg
}
Err(..) => format!(
"OS Error {} (FormatMessageW() returned \
invalid UTF-16)",
errnum
),
}
}
}

View file

@ -0,0 +1,17 @@
use crate::os::xous::ffi::Error as XousError;
pub fn errno() -> i32 {
0
}
pub fn is_interrupted(_code: i32) -> bool {
false
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}
pub fn error_string(errno: i32) -> String {
Into::<XousError>::into(errno).to_string()
}

View file

@ -1,5 +1,7 @@
#![forbid(unsafe_op_in_unsafe_fn)]
mod error;
mod io_slice {
cfg_select! {
any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => {
@ -48,6 +50,19 @@ mod is_terminal {
mod kernel_copy;
#[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
#[cfg(all(
target_family = "unix",
not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems"))
))]
pub use error::errno_location;
#[cfg_attr(not(target_os = "linux"), allow(unused_imports))]
#[cfg(any(
all(target_family = "unix", not(any(target_os = "vxworks", target_os = "rtems"))),
target_os = "wasi",
))]
pub use error::set_errno;
pub use error::{RawOsError, decode_error_kind, errno, error_string, is_interrupted};
pub use io_slice::{IoSlice, IoSliceMut};
pub use is_terminal::is_terminal;
pub use kernel_copy::{CopyState, kernel_copy};
@ -55,8 +70,3 @@ pub use kernel_copy::{CopyState, kernel_copy};
// Bare metal platforms usually have very small amounts of RAM
// (in the order of hundreds of KB)
pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
pub type RawOsError = cfg_select! {
target_os = "uefi" => usize,
_ => i32,
};

View file

@ -151,7 +151,7 @@ impl Socket {
loop {
let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) };
if result.is_minus_one() {
let err = crate::sys::os::errno();
let err = crate::sys::io::errno();
match err {
libc::EINTR => continue,
libc::EISCONN => return Ok(()),

View file

@ -1,7 +1,7 @@
use crate::ffi::OsString;
use crate::io;
use crate::os::unix::ffi::OsStringExt;
use crate::sys::pal::os::errno;
use crate::sys::io::errno;
pub fn hostname() -> io::Result<OsString> {
// Query the system for the maximum host name length.

View file

@ -75,32 +75,6 @@ pub unsafe extern "C" fn runtime_entry(
}
}
#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == hermit_abi::errno::EINTR
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
match errno {
hermit_abi::errno::EACCES => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EADDRINUSE => io::ErrorKind::AddrInUse,
hermit_abi::errno::EADDRNOTAVAIL => io::ErrorKind::AddrNotAvailable,
hermit_abi::errno::EAGAIN => io::ErrorKind::WouldBlock,
hermit_abi::errno::ECONNABORTED => io::ErrorKind::ConnectionAborted,
hermit_abi::errno::ECONNREFUSED => io::ErrorKind::ConnectionRefused,
hermit_abi::errno::ECONNRESET => io::ErrorKind::ConnectionReset,
hermit_abi::errno::EEXIST => io::ErrorKind::AlreadyExists,
hermit_abi::errno::EINTR => io::ErrorKind::Interrupted,
hermit_abi::errno::EINVAL => io::ErrorKind::InvalidInput,
hermit_abi::errno::ENOENT => io::ErrorKind::NotFound,
hermit_abi::errno::ENOTCONN => io::ErrorKind::NotConnected,
hermit_abi::errno::EPERM => io::ErrorKind::PermissionDenied,
hermit_abi::errno::EPIPE => io::ErrorKind::BrokenPipe,
hermit_abi::errno::ETIMEDOUT => io::ErrorKind::TimedOut,
_ => io::ErrorKind::Uncategorized,
}
}
#[doc(hidden)]
pub trait IsNegative {
fn is_negative(&self) -> bool;
@ -131,12 +105,7 @@ impl IsNegative for i32 {
impl_is_negative! { i8 i16 i64 isize }
pub fn cvt<T: IsNegative>(t: T) -> io::Result<T> {
if t.is_negative() {
let e = decode_error_kind(t.negate());
Err(io::Error::from(e))
} else {
Ok(t)
}
if t.is_negative() { Err(io::Error::from_raw_os_error(t.negate())) } else { Ok(t) }
}
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>

View file

@ -5,14 +5,6 @@ use crate::path::{self, PathBuf};
use crate::sys::unsupported;
use crate::{fmt, io};
pub fn errno() -> i32 {
unsafe { hermit_abi::get_errno() }
}
pub fn error_string(errno: i32) -> String {
hermit_abi::error_string(errno).to_string()
}
pub fn getcwd() -> io::Result<PathBuf> {
Ok(PathBuf::from("/"))
}

View file

@ -44,45 +44,6 @@ pub fn unsupported_err() -> io::Error {
io::Error::UNSUPPORTED_PLATFORM
}
pub fn is_interrupted(_code: io::RawOsError) -> bool {
false // Motor OS doesn't have signals.
}
pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
use moto_rt::error::*;
if code < 0 || code > u16::MAX.into() {
return io::ErrorKind::Uncategorized;
}
let error = moto_rt::Error::from(code as moto_rt::ErrorCode);
match error {
moto_rt::Error::Unspecified => io::ErrorKind::Uncategorized,
moto_rt::Error::Unknown => io::ErrorKind::Uncategorized,
moto_rt::Error::NotReady => io::ErrorKind::WouldBlock,
moto_rt::Error::NotImplemented => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooHigh => io::ErrorKind::Unsupported,
moto_rt::Error::VersionTooLow => io::ErrorKind::Unsupported,
moto_rt::Error::InvalidArgument => io::ErrorKind::InvalidInput,
moto_rt::Error::OutOfMemory => io::ErrorKind::OutOfMemory,
moto_rt::Error::NotAllowed => io::ErrorKind::PermissionDenied,
moto_rt::Error::NotFound => io::ErrorKind::NotFound,
moto_rt::Error::InternalError => io::ErrorKind::Other,
moto_rt::Error::TimedOut => io::ErrorKind::TimedOut,
moto_rt::Error::AlreadyInUse => io::ErrorKind::AlreadyExists,
moto_rt::Error::UnexpectedEof => io::ErrorKind::UnexpectedEof,
moto_rt::Error::InvalidFilename => io::ErrorKind::InvalidFilename,
moto_rt::Error::NotADirectory => io::ErrorKind::NotADirectory,
moto_rt::Error::BadHandle => io::ErrorKind::InvalidInput,
moto_rt::Error::FileTooLarge => io::ErrorKind::FileTooLarge,
moto_rt::Error::NotConnected => io::ErrorKind::NotConnected,
moto_rt::Error::StorageFull => io::ErrorKind::StorageFull,
moto_rt::Error::InvalidData => io::ErrorKind::InvalidData,
_ => io::ErrorKind::Uncategorized,
}
}
pub fn abort_internal() -> ! {
core::intrinsics::abort();
}

View file

@ -4,37 +4,8 @@ use crate::ffi::{OsStr, OsString};
use crate::marker::PhantomData;
use crate::os::motor::ffi::OsStrExt;
use crate::path::{self, PathBuf};
use crate::sys::io::RawOsError;
use crate::{fmt, io};
pub fn errno() -> RawOsError {
// Not used in Motor OS because it is ambiguous: Motor OS
// is micro-kernel-based, and I/O happens via a shared-memory
// ring buffer, so an I/O operation that on a unix is a syscall
// may involve no sycalls on Motor OS at all, or a syscall
// that e.g. waits for a notification from the I/O driver
// (sys-io); and the wait syscall may succeed, but the
// driver may report an I/O error; or a bunch of results
// for several I/O operations, some successful and some
// not.
//
// Also I/O operations in a Motor OS process are handled by a
// separate runtime background/I/O thread, so it is really hard
// to define what "last system error in the current thread"
// actually means.
let error_code: moto_rt::ErrorCode = moto_rt::Error::Unknown.into();
error_code.into()
}
pub fn error_string(errno: RawOsError) -> String {
let error: moto_rt::Error = match errno {
x if x < 0 => moto_rt::Error::Unknown,
x if x > u16::MAX.into() => moto_rt::Error::Unknown,
x => (x as moto_rt::ErrorCode).into(), /* u16 */
};
format!("{}", error)
}
pub fn getcwd() -> io::Result<PathBuf> {
moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error)
}

View file

@ -54,56 +54,6 @@ pub fn sgx_ineffective<T>(v: T) -> io::Result<T> {
}
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
code == fortanix_sgx_abi::Error::Interrupted as _
}
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
use fortanix_sgx_abi::Error;
// FIXME: not sure how to make sure all variants of Error are covered
if code == Error::NotFound as _ {
io::ErrorKind::NotFound
} else if code == Error::PermissionDenied as _ {
io::ErrorKind::PermissionDenied
} else if code == Error::ConnectionRefused as _ {
io::ErrorKind::ConnectionRefused
} else if code == Error::ConnectionReset as _ {
io::ErrorKind::ConnectionReset
} else if code == Error::ConnectionAborted as _ {
io::ErrorKind::ConnectionAborted
} else if code == Error::NotConnected as _ {
io::ErrorKind::NotConnected
} else if code == Error::AddrInUse as _ {
io::ErrorKind::AddrInUse
} else if code == Error::AddrNotAvailable as _ {
io::ErrorKind::AddrNotAvailable
} else if code == Error::BrokenPipe as _ {
io::ErrorKind::BrokenPipe
} else if code == Error::AlreadyExists as _ {
io::ErrorKind::AlreadyExists
} else if code == Error::WouldBlock as _ {
io::ErrorKind::WouldBlock
} else if code == Error::InvalidInput as _ {
io::ErrorKind::InvalidInput
} else if code == Error::InvalidData as _ {
io::ErrorKind::InvalidData
} else if code == Error::TimedOut as _ {
io::ErrorKind::TimedOut
} else if code == Error::WriteZero as _ {
io::ErrorKind::WriteZero
} else if code == Error::Interrupted as _ {
io::ErrorKind::Interrupted
} else if code == Error::Other as _ {
io::ErrorKind::Uncategorized
} else if code == Error::UnexpectedEof as _ {
io::ErrorKind::UnexpectedEof
} else {
io::ErrorKind::Uncategorized
}
}
pub fn abort_internal() -> ! {
abi::usercalls::exit(true)
}

View file

@ -1,25 +1,9 @@
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
use crate::ffi::{OsStr, OsString};
use crate::marker::PhantomData;
use crate::path::{self, PathBuf};
use crate::sys::{decode_error_kind, sgx_ineffective, unsupported};
use crate::sys::{sgx_ineffective, unsupported};
use crate::{fmt, io};
pub fn errno() -> i32 {
RESULT_SUCCESS
}
pub fn error_string(errno: i32) -> String {
if errno == RESULT_SUCCESS {
"operation successful".into()
} else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) {
format!("user-specified error {errno:08x}")
} else {
decode_error_kind(errno).as_str().into()
}
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -38,15 +38,6 @@ pub fn unsupported_err() -> io::Error {
io::Error::UNSUPPORTED_PLATFORM
}
#[inline]
pub fn is_interrupted(code: i32) -> bool {
crate::sys::net::is_interrupted(code)
}
pub fn decode_error_kind(code: i32) -> io::ErrorKind {
error::decode_error_kind(code)
}
#[inline]
pub fn abort_internal() -> ! {
unsafe { libc::abort() }

View file

@ -1,4 +1,4 @@
use super::{error, itron, unsupported};
use super::{itron, unsupported};
use crate::ffi::{OsStr, OsString};
use crate::path::{self, PathBuf};
use crate::{fmt, io};
@ -11,14 +11,6 @@ impl itron::error::ItronError {
}
}
pub fn errno() -> i32 {
0
}
pub fn error_string(errno: i32) -> String {
if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") }
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -38,61 +38,6 @@ pub unsafe fn cleanup() {
// stack_overflow::cleanup();
}
#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
// Note: code below is 1:1 copied from unix/mod.rs
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
libc::ENOTEMPTY => DirectoryNotEmpty,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EACCES | libc::EPERM => PermissionDenied,
// These two constants can have the same value on some systems,
// but different values on others, so we can't use a match
// clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;

View file

@ -7,10 +7,6 @@ use crate::ffi::{OsStr, OsString};
use crate::path::PathBuf;
use crate::{fmt, io, path};
pub fn errno() -> i32 {
unsafe { (*libc::__errno_location()) as i32 }
}
// Hardcoded to return 4096, since `sysconf` is only implemented as a stub.
pub fn page_size() -> usize {
// unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize };
@ -19,10 +15,6 @@ pub fn page_size() -> usize {
// Everything below are stubs and copied from unsupported.rs
pub fn error_string(_errno: i32) -> String {
"error string unimplemented".to_string()
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -83,52 +83,6 @@ pub const fn unsupported_err() -> io::Error {
io::const_error!(io::ErrorKind::Unsupported, "operation not supported on UEFI")
}
pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind {
use r_efi::efi::Status;
match r_efi::efi::Status::from_usize(code) {
Status::ALREADY_STARTED
| Status::COMPROMISED_DATA
| Status::CONNECTION_FIN
| Status::CRC_ERROR
| Status::DEVICE_ERROR
| Status::END_OF_MEDIA
| Status::HTTP_ERROR
| Status::ICMP_ERROR
| Status::INCOMPATIBLE_VERSION
| Status::LOAD_ERROR
| Status::MEDIA_CHANGED
| Status::NO_MAPPING
| Status::NO_MEDIA
| Status::NOT_STARTED
| Status::PROTOCOL_ERROR
| Status::PROTOCOL_UNREACHABLE
| Status::TFTP_ERROR
| Status::VOLUME_CORRUPTED => io::ErrorKind::Other,
Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => io::ErrorKind::InvalidData,
Status::ABORTED => io::ErrorKind::ConnectionAborted,
Status::ACCESS_DENIED => io::ErrorKind::PermissionDenied,
Status::BUFFER_TOO_SMALL => io::ErrorKind::FileTooLarge,
Status::CONNECTION_REFUSED => io::ErrorKind::ConnectionRefused,
Status::CONNECTION_RESET => io::ErrorKind::ConnectionReset,
Status::END_OF_FILE => io::ErrorKind::UnexpectedEof,
Status::HOST_UNREACHABLE => io::ErrorKind::HostUnreachable,
Status::INVALID_PARAMETER => io::ErrorKind::InvalidInput,
Status::IP_ADDRESS_CONFLICT => io::ErrorKind::AddrInUse,
Status::NETWORK_UNREACHABLE => io::ErrorKind::NetworkUnreachable,
Status::NO_RESPONSE => io::ErrorKind::HostUnreachable,
Status::NOT_FOUND => io::ErrorKind::NotFound,
Status::NOT_READY => io::ErrorKind::ResourceBusy,
Status::OUT_OF_RESOURCES => io::ErrorKind::OutOfMemory,
Status::SECURITY_VIOLATION => io::ErrorKind::PermissionDenied,
Status::TIMEOUT => io::ErrorKind::TimedOut,
Status::UNSUPPORTED => io::ErrorKind::Unsupported,
Status::VOLUME_FULL => io::ErrorKind::StorageFull,
Status::WRITE_PROTECTED => io::ErrorKind::ReadOnlyFilesystem,
_ => io::ErrorKind::Uncategorized,
}
}
pub fn abort_internal() -> ! {
if let Some(exit_boot_service_event) =
NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
@ -158,7 +112,3 @@ pub fn abort_internal() -> ! {
extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
uefi::env::disable_boot_services();
}
pub fn is_interrupted(_code: io::RawOsError) -> bool {
false
}

View file

@ -9,59 +9,6 @@ use crate::path::{self, PathBuf};
use crate::ptr::NonNull;
use crate::{fmt, io};
pub fn errno() -> io::RawOsError {
0
}
pub fn error_string(errno: io::RawOsError) -> String {
// Keep the List in Alphabetical Order
// The Messages are taken from UEFI Specification Appendix D - Status Codes
#[rustfmt::skip]
let msg = match r_efi::efi::Status::from_usize(errno) {
Status::ABORTED => "The operation was aborted.",
Status::ACCESS_DENIED => "Access was denied.",
Status::ALREADY_STARTED => "The protocol has already been started.",
Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.",
Status::BUFFER_TOO_SMALL => "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.",
Status::COMPROMISED_DATA => "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.",
Status::CONNECTION_FIN => "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.",
Status::CONNECTION_REFUSED => "The receiving or transmission operation fails because this connection is refused.",
Status::CONNECTION_RESET => "The connect fails because the connection is reset either by instance itself or the communication peer.",
Status::CRC_ERROR => "A CRC error was detected.",
Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.",
Status::END_OF_FILE => "The end of the file was reached.",
Status::END_OF_MEDIA => "Beginning or end of media was reached",
Status::HOST_UNREACHABLE => "The remote host is not reachable.",
Status::HTTP_ERROR => "A HTTP error occurred during the network operation.",
Status::ICMP_ERROR => "An ICMP error occurred during the network operation.",
Status::INCOMPATIBLE_VERSION => "The function encountered an internal version that was incompatible with a version requested by the caller.",
Status::INVALID_LANGUAGE => "The language specified was invalid.",
Status::INVALID_PARAMETER => "A parameter was incorrect.",
Status::IP_ADDRESS_CONFLICT => "There is an address conflict address allocation",
Status::LOAD_ERROR => "The image failed to load.",
Status::MEDIA_CHANGED => "The medium in the device has changed since the last access.",
Status::NETWORK_UNREACHABLE => "The network containing the remote host is not reachable.",
Status::NO_MAPPING => "A mapping to a device does not exist.",
Status::NO_MEDIA => "The device does not contain any medium to perform the operation.",
Status::NO_RESPONSE => "The server was not found or did not respond to the request.",
Status::NOT_FOUND => "The item was not found.",
Status::NOT_READY => "There is no data pending upon return.",
Status::NOT_STARTED => "The protocol has not been started.",
Status::OUT_OF_RESOURCES => "A resource has run out.",
Status::PROTOCOL_ERROR => "A protocol error occurred during the network operation.",
Status::PROTOCOL_UNREACHABLE => "An ICMP protocol unreachable error is received.",
Status::SECURITY_VIOLATION => "The function was not performed due to a security violation.",
Status::TFTP_ERROR => "A TFTP error occurred during the network operation.",
Status::TIMEOUT => "The timeout time expired.",
Status::UNSUPPORTED => "The operation is not supported.",
Status::VOLUME_FULL => "There is no more space on the file system.",
Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.",
Status::WRITE_PROTECTED => "The device cannot be written to.",
_ => return format!("Status: {errno}"),
};
msg.to_owned()
}
pub fn getcwd() -> io::Result<PathBuf> {
match helpers::open_shell() {
Some(shell) => {

View file

@ -86,7 +86,7 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>)
}
};
match (r < 0).then(super::os::errno) {
match (r < 0).then(crate::sys::io::errno) {
Some(libc::ETIMEDOUT) => return false,
Some(libc::EINTR) => continue,
_ => return true,
@ -167,7 +167,7 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>)
)
};
r == 0 || super::os::errno() != libc::ETIMEDOUT
r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT
}
#[cfg(target_os = "openbsd")]
@ -210,7 +210,7 @@ pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>)
libc::umtx_sleep(futex as *const Atomic<u32> as *const i32, expected as i32, timeout_ms)
};
r == 0 || super::os::errno() != libc::ETIMEDOUT
r == 0 || crate::sys::io::errno() != libc::ETIMEDOUT
}
// DragonflyBSD doesn't tell us how many threads are woken up, so this always returns false.

View file

@ -33,7 +33,7 @@ impl PidFd {
match cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })
{
Ok(_) => {}
Err(e) if e.raw_os_error() == Some(libc::EINVAL) => {
Err(e) if matches!(e.raw_os_error(), Some(libc::EINVAL | libc::ENOTTY)) => {
// kernel doesn't support that ioctl, try the glibc helper that looks at procfs
weak!(
fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t;

View file

@ -1,6 +1,5 @@
use super::PidFd as InternalPidFd;
use crate::assert_matches::assert_matches;
use crate::io::ErrorKind;
use crate::os::fd::AsRawFd;
use crate::os::linux::process::{ChildExt, CommandExt as _};
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
@ -62,7 +61,9 @@ fn test_command_pidfd() {
if let Ok(pidfd) = child.pidfd() {
match pidfd.as_inner().pid() {
Ok(pid) => assert_eq!(pid, id),
Err(e) if e.kind() == ErrorKind::InvalidInput => { /* older kernel */ }
Err(e) if matches!(e.raw_os_error(), Some(libc::EINVAL | libc::ENOTTY)) => {
/* older kernel */
}
Err(e) => panic!("unexpected error getting pid from pidfd: {}", e),
}
}

View file

@ -91,7 +91,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
target_vendor = "apple",
)))]
'poll: {
use crate::sys::os::errno;
use crate::sys::io::errno;
let pfds: &mut [_] = &mut [
libc::pollfd { fd: 0, events: 0, revents: 0 },
libc::pollfd { fd: 1, events: 0, revents: 0 },
@ -135,7 +135,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
target_os = "vita",
)))]
{
use crate::sys::os::errno;
use crate::sys::io::errno;
for fd in 0..3 {
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
open_devnull();
@ -224,63 +224,6 @@ pub unsafe fn cleanup() {
#[allow(unused_imports)]
pub use libc::signal;
#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
#[cfg(not(target_os = "aix"))]
libc::ENOTEMPTY => DirectoryNotEmpty,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EINPROGRESS => InProgress,
libc::EOPNOTSUPP => Unsupported,
libc::EACCES | libc::EPERM => PermissionDenied,
// These two constants can have the same value on some systems,
// but different values on others, so we can't use a match
// clause
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;

View file

@ -14,135 +14,8 @@ use crate::sys::cvt;
use crate::sys::helpers::run_path_with_cstr;
use crate::{fmt, io, iter, mem, ptr, slice, str};
const TMPBUF_SZ: usize = 128;
const PATH_SEPARATOR: u8 = b':';
unsafe extern "C" {
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[cfg_attr(
any(
target_os = "linux",
target_os = "emscripten",
target_os = "fuchsia",
target_os = "l4re",
target_os = "hurd",
),
link_name = "__errno_location"
)]
#[cfg_attr(
any(
target_os = "netbsd",
target_os = "openbsd",
target_os = "cygwin",
target_os = "android",
target_os = "redox",
target_os = "nuttx",
target_env = "newlib"
),
link_name = "__errno"
)]
#[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
#[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")]
#[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")]
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
#[cfg_attr(target_os = "aix", link_name = "_Errno")]
// SAFETY: this will always return the same pointer on a given thread.
#[unsafe(ffi_const)]
pub safe fn errno_location() -> *mut c_int;
}
/// Returns the platform-specific value of errno
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[inline]
pub fn errno() -> i32 {
unsafe { (*errno_location()) as i32 }
}
/// Sets the platform-specific value of errno
// needed for readdir and syscall!
#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
#[allow(dead_code)] // but not all target cfgs actually end up using it
#[inline]
pub fn set_errno(e: i32) {
unsafe { *errno_location() = e as c_int }
}
#[cfg(target_os = "vxworks")]
#[inline]
pub fn errno() -> i32 {
unsafe { libc::errnoGet() }
}
#[cfg(target_os = "rtems")]
#[inline]
pub fn errno() -> i32 {
unsafe extern "C" {
#[thread_local]
static _tls_errno: c_int;
}
unsafe { _tls_errno as i32 }
}
#[cfg(target_os = "dragonfly")]
#[inline]
pub fn errno() -> i32 {
unsafe extern "C" {
#[thread_local]
static errno: c_int;
}
unsafe { errno as i32 }
}
#[cfg(target_os = "dragonfly")]
#[allow(dead_code)]
#[inline]
pub fn set_errno(e: i32) {
unsafe extern "C" {
#[thread_local]
static mut errno: c_int;
}
unsafe {
errno = e;
}
}
/// Gets a detailed string description for the given error number.
pub fn error_string(errno: i32) -> String {
unsafe extern "C" {
#[cfg_attr(
all(
any(
target_os = "linux",
target_os = "hurd",
target_env = "newlib",
target_os = "cygwin"
),
not(target_env = "ohos")
),
link_name = "__xpg_strerror_r"
)]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
}
let mut buf = [0 as c_char; TMPBUF_SZ];
let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
let p = p as *const _;
// We can't always expect a UTF-8 environment. When we don't get that luxury,
// it's better to give a low-quality error message than none at all.
String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into()
}
}
#[cfg(target_os = "espidf")]
pub fn getcwd() -> io::Result<PathBuf> {
Ok(PathBuf::from("/"))

View file

@ -29,7 +29,7 @@ use crate::hint::spin_loop;
use crate::ops::Range;
use crate::sync::Mutex;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os::errno_location;
use crate::sys::io::errno_location;
pub struct ThreadInfo {
pub tid: u64,

View file

@ -16,14 +16,6 @@ pub fn unsupported_err() -> std_io::Error {
std_io::Error::UNSUPPORTED_PLATFORM
}
pub fn is_interrupted(_code: i32) -> bool {
false
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}
pub fn abort_internal() -> ! {
core::intrinsics::abort();
}

View file

@ -4,14 +4,6 @@ use crate::marker::PhantomData;
use crate::path::{self, PathBuf};
use crate::{fmt, io};
pub fn errno() -> i32 {
0
}
pub fn error_string(_errno: i32) -> String {
"operation successful".to_string()
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -5,9 +5,7 @@ pub mod time;
#[path = "../unsupported/common.rs"]
mod unsupported_common;
pub use unsupported_common::{
decode_error_kind, init, is_interrupted, unsupported, unsupported_err,
};
pub use unsupported_common::{init, unsupported, unsupported_err};
use crate::arch::global_asm;
use crate::ptr;

View file

@ -2,8 +2,8 @@
#[path = "../unsupported/os.rs"]
mod unsupported_os;
pub use unsupported_os::{
JoinPathsError, SplitPaths, chdir, current_exe, errno, error_string, getcwd, getpid, home_dir,
join_paths, split_paths, temp_dir,
JoinPathsError, SplitPaths, chdir, current_exe, getcwd, getpid, home_dir, join_paths,
split_paths, temp_dir,
};
pub use super::unsupported;

View file

@ -1,63 +1,11 @@
#![forbid(unsafe_op_in_unsafe_fn)]
use crate::io as std_io;
#[inline]
pub fn is_interrupted(errno: i32) -> bool {
errno == libc::EINTR
}
pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
use std_io::ErrorKind::*;
match errno as libc::c_int {
libc::E2BIG => ArgumentListTooLong,
libc::EADDRINUSE => AddrInUse,
libc::EADDRNOTAVAIL => AddrNotAvailable,
libc::EBUSY => ResourceBusy,
libc::ECONNABORTED => ConnectionAborted,
libc::ECONNREFUSED => ConnectionRefused,
libc::ECONNRESET => ConnectionReset,
libc::EDEADLK => Deadlock,
libc::EDQUOT => QuotaExceeded,
libc::EEXIST => AlreadyExists,
libc::EFBIG => FileTooLarge,
libc::EHOSTUNREACH => HostUnreachable,
libc::EINTR => Interrupted,
libc::EINVAL => InvalidInput,
libc::EISDIR => IsADirectory,
libc::ELOOP => FilesystemLoop,
libc::ENOENT => NotFound,
libc::ENOMEM => OutOfMemory,
libc::ENOSPC => StorageFull,
libc::ENOSYS => Unsupported,
libc::EMLINK => TooManyLinks,
libc::ENAMETOOLONG => InvalidFilename,
libc::ENETDOWN => NetworkDown,
libc::ENETUNREACH => NetworkUnreachable,
libc::ENOTCONN => NotConnected,
libc::ENOTDIR => NotADirectory,
libc::EPIPE => BrokenPipe,
libc::EROFS => ReadOnlyFilesystem,
libc::ESPIPE => NotSeekable,
libc::ESTALE => StaleNetworkFileHandle,
libc::ETIMEDOUT => TimedOut,
libc::ETXTBSY => ExecutableFileBusy,
libc::EXDEV => CrossesDevices,
libc::EINPROGRESS => InProgress,
libc::EOPNOTSUPP => Unsupported,
libc::EACCES | libc::EPERM => PermissionDenied,
libc::EWOULDBLOCK => WouldBlock,
_ => Uncategorized,
}
}
pub fn abort_internal() -> ! {
unsafe { libc::abort() }
}
#[inline]
#[cfg(target_env = "p1")]
pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error {
std_io::Error::from_raw_os_error(err.raw().into())
pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error {
crate::io::Error::from_raw_os_error(err.raw().into())
}

View file

@ -26,9 +26,9 @@ mod helpers;
// import conflict rules. If we glob export `helpers` and `common` together,
// then the compiler complains about conflicts.
pub(crate) use helpers::abort_internal;
#[cfg(target_env = "p1")]
pub(crate) use helpers::err2io;
pub(crate) use helpers::{abort_internal, decode_error_kind, is_interrupted};
#[cfg(not(target_env = "p1"))]
pub use os::IsMinusOne;
pub use os::{cvt, cvt_r};

View file

@ -6,7 +6,7 @@ use crate::os::wasi::prelude::*;
use crate::path::{self, PathBuf};
use crate::sys::helpers::run_path_with_cstr;
use crate::sys::unsupported;
use crate::{fmt, io, str};
use crate::{fmt, io};
// Add a few symbols not in upstream `libc` just yet.
pub mod libc {
@ -19,34 +19,6 @@ pub mod libc {
}
}
unsafe extern "C" {
#[thread_local]
#[link_name = "errno"]
static mut libc_errno: libc::c_int;
}
pub fn errno() -> i32 {
unsafe { libc_errno as i32 }
}
pub fn set_errno(val: i32) {
unsafe {
libc_errno = val;
}
}
pub fn error_string(errno: i32) -> String {
let mut buf = [0 as libc::c_char; 1024];
let p = buf.as_mut_ptr();
unsafe {
if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
}
}
pub fn getcwd() -> io::Result<PathBuf> {
let mut buf = Vec::with_capacity(512);
loop {

View file

@ -60,84 +60,6 @@ pub unsafe fn cleanup() {
winsock::cleanup();
}
#[inline]
pub fn is_interrupted(_errno: i32) -> bool {
false
}
pub fn decode_error_kind(errno: i32) -> io::ErrorKind {
use io::ErrorKind::*;
match errno as u32 {
c::ERROR_ACCESS_DENIED => return PermissionDenied,
c::ERROR_ALREADY_EXISTS => return AlreadyExists,
c::ERROR_FILE_EXISTS => return AlreadyExists,
c::ERROR_BROKEN_PIPE => return BrokenPipe,
c::ERROR_FILE_NOT_FOUND
| c::ERROR_PATH_NOT_FOUND
| c::ERROR_INVALID_DRIVE
| c::ERROR_BAD_NETPATH
| c::ERROR_BAD_NET_NAME => return NotFound,
c::ERROR_NO_DATA => return BrokenPipe,
c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename,
c::ERROR_INVALID_PARAMETER => return InvalidInput,
c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
c::ERROR_SEM_TIMEOUT
| c::WAIT_TIMEOUT
| c::ERROR_DRIVER_CANCEL_TIMEOUT
| c::ERROR_OPERATION_ABORTED
| c::ERROR_SERVICE_REQUEST_TIMEOUT
| c::ERROR_COUNTER_TIMEOUT
| c::ERROR_TIMEOUT
| c::ERROR_RESOURCE_CALL_TIMED_OUT
| c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
| c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
| c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
| c::ERROR_DS_TIMELIMIT_EXCEEDED
| c::DNS_ERROR_RECORD_TIMED_OUT
| c::ERROR_IPSEC_IKE_TIMED_OUT
| c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
| c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
c::ERROR_DIRECTORY => return NotADirectory,
c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded,
c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
c::ERROR_BUSY => return ResourceBusy,
c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename,
c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop,
_ => {}
}
match errno {
c::WSAEACCES => PermissionDenied,
c::WSAEADDRINUSE => AddrInUse,
c::WSAEADDRNOTAVAIL => AddrNotAvailable,
c::WSAECONNABORTED => ConnectionAborted,
c::WSAECONNREFUSED => ConnectionRefused,
c::WSAECONNRESET => ConnectionReset,
c::WSAEINVAL => InvalidInput,
c::WSAENOTCONN => NotConnected,
c::WSAEWOULDBLOCK => WouldBlock,
c::WSAETIMEDOUT => TimedOut,
c::WSAEHOSTUNREACH => HostUnreachable,
c::WSAENETDOWN => NetworkDown,
c::WSAENETUNREACH => NetworkUnreachable,
c::WSAEDQUOT => QuotaExceeded,
_ => Uncategorized,
}
}
pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option<usize> {
let ptr = haystack.as_ptr();
let mut start = haystack;

View file

@ -15,66 +15,6 @@ use crate::path::{self, PathBuf};
use crate::sys::pal::{c, cvt};
use crate::{fmt, io, ptr};
pub fn errno() -> i32 {
api::get_last_error().code as i32
}
/// Gets a detailed string description for the given error number.
pub fn error_string(mut errnum: i32) -> String {
let mut buf = [0 as c::WCHAR; 2048];
unsafe {
let mut module = ptr::null_mut();
let mut flags = 0;
// NTSTATUS errors may be encoded as HRESULT, which may returned from
// GetLastError. For more information about Windows error codes, see
// `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
// format according to https://support.microsoft.com/en-us/help/259693
const NTDLL_DLL: &[u16] = &[
'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
'L' as _, 0,
];
module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
if !module.is_null() {
errnum ^= c::FACILITY_NT_BIT as i32;
flags = c::FORMAT_MESSAGE_FROM_HMODULE;
}
}
let res = c::FormatMessageW(
flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
module,
errnum as u32,
0,
buf.as_mut_ptr(),
buf.len() as u32,
ptr::null(),
) as usize;
if res == 0 {
// Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId,
let fm_err = errno();
return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
}
match String::from_utf16(&buf[..res]) {
Ok(mut msg) => {
// Trim trailing CRLF inserted by FormatMessageW
let len = msg.trim_end().len();
msg.truncate(len);
msg
}
Err(..) => format!(
"OS Error {} (FormatMessageW() returned \
invalid UTF-16)",
errnum
),
}
}
}
pub struct SplitPaths<'a> {
data: EncodeWide<'a>,
must_yield: bool,

View file

@ -1,7 +1,6 @@
use super::unsupported;
use crate::ffi::{OsStr, OsString};
use crate::marker::PhantomData;
use crate::os::xous::ffi::Error as XousError;
use crate::path::{self, PathBuf};
use crate::sync::atomic::{Atomic, AtomicPtr, Ordering};
use crate::{fmt, io};
@ -63,14 +62,6 @@ mod c_compat {
}
}
pub fn errno() -> i32 {
0
}
pub fn error_string(errno: i32) -> String {
Into::<XousError>::into(errno).to_string()
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -33,14 +33,6 @@ pub fn unsupported_err() -> std_io::Error {
std_io::Error::UNSUPPORTED_PLATFORM
}
pub fn is_interrupted(_code: i32) -> bool {
false
}
pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
crate::io::ErrorKind::Uncategorized
}
pub fn abort_internal() -> ! {
core::intrinsics::abort();
}

View file

@ -4,14 +4,6 @@ use crate::marker::PhantomData;
use crate::path::{self, PathBuf};
use crate::{fmt, io};
pub fn errno() -> i32 {
0
}
pub fn error_string(_errno: i32) -> String {
"operation successful".to_string()
}
pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
}

View file

@ -8,8 +8,8 @@ use crate::num::{NonZero, NonZeroI32};
use crate::path::Path;
use crate::process::StdioPipes;
use crate::sys::fs::File;
use crate::sys::io::error_string;
use crate::sys::pal::helpers;
use crate::sys::pal::os::error_string;
use crate::sys::unsupported;
use crate::{fmt, io};

View file

@ -61,7 +61,7 @@ cfg_select! {
let bit = (signum - 1) as usize;
if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
crate::sys::pal::os::set_errno(libc::EINVAL);
crate::sys::io::set_errno(libc::EINVAL);
return -1;
}
let raw = slice::from_raw_parts_mut(

View file

@ -194,7 +194,7 @@ impl Command {
// See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
#[cfg(target_os = "nto")]
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
use crate::sys::os::errno;
use crate::sys::io::errno;
let mut delay = MIN_FORKSPAWN_SLEEP;

View file

@ -66,7 +66,7 @@ use crate::os::fd::AsRawFd;
use crate::sync::OnceLock;
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crate::sync::atomic::{Atomic, AtomicBool};
use crate::sys::pal::os::errno;
use crate::sys::io::errno;
use crate::sys::pal::weak::syscall;
fn getrandom(mut bytes: &mut [u8], insecure: bool) {

View file

@ -1,6 +1,6 @@
use crate::cell::UnsafeCell;
use crate::sys::c;
use crate::sys::sync::{Mutex, mutex};
use crate::sys::{c, os};
use crate::time::Duration;
pub struct Condvar {
@ -30,7 +30,7 @@ impl Condvar {
0,
);
if r == 0 {
debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
debug_assert_eq!(crate::sys::io::errno() as usize, c::ERROR_TIMEOUT as usize);
false
} else {
true

View file

@ -14,10 +14,9 @@ use crate::num::NonZero;
use crate::sys::weak::dlsym;
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
use crate::sys::weak::weak;
use crate::sys::{os, stack_overflow};
use crate::thread::ThreadInit;
use crate::time::Duration;
use crate::{cmp, io, ptr};
use crate::{cmp, io, ptr, sys};
#[cfg(not(any(
target_os = "l4re",
target_os = "vxworks",
@ -77,7 +76,7 @@ impl Thread {
// multiple of the system page size. Because it's definitely
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
// Round up to the nearest page and try again.
let page_size = os::page_size();
let page_size = sys::os::page_size();
let stack_size =
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
@ -114,7 +113,7 @@ impl Thread {
// Now that the thread information is set, set up our stack
// overflow handler.
let _handler = stack_overflow::Handler::new();
let _handler = sys::stack_overflow::Handler::new();
rust_start();
}
@ -536,7 +535,7 @@ pub fn sleep(dur: Duration) {
secs -= ts.tv_sec as u64;
let ts_ptr = &raw mut ts;
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
assert_eq!(os::errno(), libc::EINTR);
assert_eq!(sys::io::errno(), libc::EINTR);
secs += ts.tv_sec as u64;
nsecs = ts.tv_nsec;
} else {

View file

@ -297,14 +297,15 @@ pub(crate) fn create_config(
override_queries: Some(|_sess, providers| {
// We do not register late module lints, so this only runs `MissingDoc`.
// Most lints will require typechecking, so just don't run them.
providers.lint_mod = |tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc);
providers.queries.lint_mod =
|tcx, module_def_id| late_lint_mod(tcx, module_def_id, MissingDoc);
// hack so that `used_trait_imports` won't try to call typeck
providers.used_trait_imports = |_, _| {
providers.queries.used_trait_imports = |_, _| {
static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default);
&EMPTY_SET
};
// In case typeck does end up being called, don't ICE in case there were name resolution errors
providers.typeck = move |tcx, def_id| {
providers.queries.typeck = move |tcx, def_id| {
// Closures' tables come from their outermost function,
// as they are part of the same "inference environment".
// This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`)
@ -316,7 +317,7 @@ pub(crate) fn create_config(
let body = tcx.hir_body_owned_by(def_id);
debug!("visiting body for {def_id:?}");
EmitIgnoredResolutionErrors::new(tcx).visit_body(body);
(rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id)
(rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.typeck)(tcx, def_id)
};
}),
extra_symbols: Vec::new(),

View file

@ -305,7 +305,7 @@ impl rustc_driver::Callbacks for MiriDepCompilerCalls {
config.override_queries = Some(|_, local_providers| {
// We need to add #[used] symbols to exported_symbols for `lookup_link_section`.
// FIXME handle this somehow in rustc itself to avoid this hack.
local_providers.exported_non_generic_symbols = |tcx, LocalCrate| {
local_providers.queries.exported_non_generic_symbols = |tcx, LocalCrate| {
let reachable_set = tcx
.with_stable_hashing_context(|hcx| tcx.reachable_set(()).to_sorted(&hcx, true));
tcx.arena.alloc_from_iter(

View file

@ -1,6 +1,5 @@
//@ should-fail
//@ known-bug: #49892
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
//! FIXME(#49892)
//! Test that the derived implementation of `PartialEq` for `Option` is not fully
//! optimized by LLVM. If this starts passing, the test and manual impl should
//! be removed.
@ -18,7 +17,7 @@ pub enum Option<T> {
#[no_mangle]
pub fn non_zero_eq(l: Option<NonZero<u32>>, r: Option<NonZero<u32>>) -> bool {
// CHECK: start:
// CHECK-NEXT: icmp eq i32
// CHECK-NEXT: ret i1
// COMMENTEDCHECK-NEXT: icmp eq i32
// COMMENTEDCHECK-NEXT: ret i1
l == r
}

View file

@ -1,9 +1,10 @@
error[E0277]: the trait bound `T: Step` is not satisfied
error[E0277]: `std::ops::Range<T>` is not an iterator
--> missing-bound.rs:2:14
|
2 | for _ in t {}
| ^ the trait `Step` is not implemented for `T`
| ^ `Range<T>` is not an iterator
|
= note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait
= note: required for `std::ops::Range<T>` to implement `Iterator`
= note: required for `std::ops::Range<T>` to implement `IntoIterator`

View file

@ -114,7 +114,7 @@ impl rustc_driver::Callbacks for CompilerCalls {
}
fn override_queries(_session: &Session, local: &mut Providers) {
local.mir_borrowck = mir_borrowck;
local.queries.mir_borrowck = mir_borrowck;
}
// Since mir_borrowck does not have access to any other state, we need to use a
@ -142,8 +142,8 @@ fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProvidedValue<'t
}
});
let mut providers = Providers::default();
rustc_borrowck::provide(&mut providers);
let original_mir_borrowck = providers.mir_borrowck;
rustc_borrowck::provide(&mut providers.queries);
let original_mir_borrowck = providers.queries.mir_borrowck;
original_mir_borrowck(tcx, def_id)
}

View file

@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
LL | type Result = NotAValidResultType;
| ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `VisitorResult` is not implemented for `NotAValidResultType`
help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType`
--> $DIR/rustc-dev-remap.rs:LL:COL
|
LL | struct NotAValidResultType;

View file

@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
LL | type Result = NotAValidResultType;
| ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `VisitorResult` is not implemented for `NotAValidResultType`
help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType`
--> $DIR/rustc-dev-remap.rs:LL:COL
|
LL | struct NotAValidResultType;

View file

@ -7,7 +7,7 @@ LL | #[derive(Diagnostic)]
LL | arg: NotIntoDiagArg,
| ^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
--> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
|
LL | struct NotIntoDiagArg;
@ -29,7 +29,7 @@ LL | #[derive(Subdiagnostic)]
LL | arg: NotIntoDiagArg,
| ^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg`
--> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
|
LL | struct NotIntoDiagArg;

View file

@ -657,7 +657,7 @@ LL | #[derive(Diagnostic)]
LL | other: Hello,
| ^^^^^ unsatisfied trait bound
|
help: the trait `IntoDiagArg` is not implemented for `Hello`
help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello`
--> $DIR/diagnostic-derive.rs:40:1
|
LL | struct Hello {}

View file

@ -2,7 +2,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
--> $DIR/issue-22565-rust-call.rs:3:1
|
LL | extern "rust-call" fn b(_i: i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Tuple` is not implemented for `i32`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
error: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/issue-22565-rust-call.rs:17:5
@ -32,7 +32,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup
--> $DIR/issue-22565-rust-call.rs:27:7
|
LL | b(10);
| ^^ the trait `std::marker::Tuple` is not implemented for `i32`
| ^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32`
error: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/issue-22565-rust-call.rs:29:5

View file

@ -2,7 +2,7 @@ error[E0277]: the trait bound `impl Future<Output = ()>: Coroutine<_>` is not sa
--> $DIR/coroutine-not-future.rs:36:21
|
LL | takes_coroutine(async_fn());
| --------------- ^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future<Output = ()>`
| --------------- ^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future<Output = ()>`
| |
| required by a bound introduced by this call
|
@ -16,7 +16,7 @@ error[E0277]: the trait bound `impl Future<Output = ()>: Coroutine<_>` is not sa
--> $DIR/coroutine-not-future.rs:38:21
|
LL | takes_coroutine(returns_async_block());
| --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future<Output = ()>`
| --------------- ^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future<Output = ()>`
| |
| required by a bound introduced by this call
|
@ -30,7 +30,7 @@ error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:40:21:
--> $DIR/coroutine-not-future.rs:40:21
|
LL | takes_coroutine(async {});
| --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}`
| --------------- ^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}`
| |
| required by a bound introduced by this call
|

View file

@ -4,7 +4,7 @@ use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
struct T; //~ HELP the trait `Try` is not implemented for `T`
struct T; //~ HELP the nightly-only, unstable trait `Try` is not implemented for `T`
struct Tuple(i32);
@ -41,7 +41,7 @@ async fn foo() -> Result<(), ()> {
async fn bar() -> Result<(), ()> {
foo()?; //~ ERROR the `?` operator can only be applied to values that implement `Try`
//~^ NOTE the `?` operator cannot be applied to type `impl Future<Output = Result<(), ()>>`
//~| HELP the trait `Try` is not implemented for `impl Future<Output = Result<(), ()>>`
//~| HELP the nightly-only, unstable trait `Try` is not implemented for `impl Future<Output = Result<(), ()>>`
//~| HELP consider `await`ing on the `Future`
//~| NOTE in this expansion of desugaring of operator `?`
//~| NOTE in this expansion of desugaring of operator `?`

View file

@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
LL | foo()?;
| ^^^^^^ the `?` operator cannot be applied to type `impl Future<Output = Result<(), ()>>`
|
= help: the trait `Try` is not implemented for `impl Future<Output = Result<(), ()>>`
= help: the nightly-only, unstable trait `Try` is not implemented for `impl Future<Output = Result<(), ()>>`
help: consider `await`ing on the `Future`
|
LL | foo().await?;
@ -16,7 +16,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
LL | t?;
| ^^ the `?` operator cannot be applied to type `T`
|
help: the trait `Try` is not implemented for `T`
help: the nightly-only, unstable trait `Try` is not implemented for `T`
--> $DIR/issue-61076.rs:7:1
|
LL | struct T;

Some files were not shown because too many files have changed in this diff Show more