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:
commit
8c52f735ab
150 changed files with 1254 additions and 1143 deletions
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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![];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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[¯o_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>(
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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 'ſt'.to_uppercase() {
|
||||
/// print!("{c}");
|
||||
/// }
|
||||
/// println!();
|
||||
|
|
@ -1156,13 +1157,13 @@ impl char {
|
|||
/// Using `println!` directly:
|
||||
///
|
||||
/// ```
|
||||
/// println!("{}", 'ß'.to_uppercase());
|
||||
/// println!("{}", 'ſt'.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.
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
4
library/std/src/sys/env/uefi.rs
vendored
4
library/std/src/sys/env/uefi.rs
vendored
|
|
@ -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(()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
15
library/std/src/sys/io/error/generic.rs
Normal file
15
library/std/src/sys/io/error/generic.rs
Normal 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()
|
||||
}
|
||||
35
library/std/src/sys/io/error/hermit.rs
Normal file
35
library/std/src/sys/io/error/hermit.rs
Normal 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()
|
||||
}
|
||||
55
library/std/src/sys/io/error/mod.rs
Normal file
55
library/std/src/sys/io/error/mod.rs
Normal 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,
|
||||
};
|
||||
67
library/std/src/sys/io/error/motor.rs
Normal file
67
library/std/src/sys/io/error/motor.rs
Normal 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)
|
||||
}
|
||||
65
library/std/src/sys/io/error/sgx.rs
Normal file
65
library/std/src/sys/io/error/sgx.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
19
library/std/src/sys/io/error/solid.rs
Normal file
19
library/std/src/sys/io/error/solid.rs
Normal 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}") }
|
||||
}
|
||||
64
library/std/src/sys/io/error/teeos.rs
Normal file
64
library/std/src/sys/io/error/teeos.rs
Normal 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()
|
||||
}
|
||||
104
library/std/src/sys/io/error/uefi.rs
Normal file
104
library/std/src/sys/io/error/uefi.rs
Normal 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()
|
||||
}
|
||||
186
library/std/src/sys/io/error/unix.rs
Normal file
186
library/std/src/sys/io/error/unix.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
80
library/std/src/sys/io/error/wasi.rs
Normal file
80
library/std/src/sys/io/error/wasi.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
140
library/std/src/sys/io/error/windows.rs
Normal file
140
library/std/src/sys/io/error/windows.rs
Normal 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
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
17
library/std/src/sys/io/error/xous.rs
Normal file
17
library/std/src/sys/io/error/xous.rs
Normal 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()
|
||||
}
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(()),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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("/"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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("/"))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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 `?`
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
|
|||
LL | test()?;
|
||||
| ^^^^^^^ the `?` operator cannot be applied to type `impl Future<Output = ()>`
|
||||
|
|
||||
= help: the trait `Try` is not implemented for `impl Future<Output = ()>`
|
||||
= help: the nightly-only, unstable trait `Try` is not implemented for `impl Future<Output = ()>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
--> $DIR/issue-84841.rs:9:11
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue