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) {
|
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> {
|
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provide(&self, providers: &mut Providers) {
|
fn provide(&self, providers: &mut Providers) {
|
||||||
providers.global_backend_features =
|
providers.queries.global_backend_features =
|
||||||
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, false)
|
|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) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
providers.reachable_non_generics = reachable_non_generics_provider;
|
providers.queries.reachable_non_generics = reachable_non_generics_provider;
|
||||||
providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
|
providers.queries.is_reachable_non_generic = is_reachable_non_generic_provider_local;
|
||||||
providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
|
providers.queries.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
|
||||||
providers.exported_generic_symbols = exported_generic_symbols_provider_local;
|
providers.queries.exported_generic_symbols = exported_generic_symbols_provider_local;
|
||||||
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
|
providers.queries.upstream_monomorphizations = upstream_monomorphizations_provider;
|
||||||
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
|
providers.queries.is_unreachable_local_definition = is_unreachable_local_definition_provider;
|
||||||
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
|
providers.queries.upstream_drop_glue_for = upstream_drop_glue_for_provider;
|
||||||
providers.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider;
|
providers.queries.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider;
|
||||||
providers.wasm_import_module_map = wasm_import_module_map;
|
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.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
|
||||||
providers.extern_queries.upstream_monomorphizations_for =
|
providers.extern_queries.upstream_monomorphizations_for =
|
||||||
upstream_monomorphizations_for_provider;
|
upstream_monomorphizations_for_provider;
|
||||||
|
|
|
||||||
|
|
@ -266,9 +266,9 @@ pub enum CodegenErrors {
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
crate::back::symbol_export::provide(providers);
|
crate::back::symbol_export::provide(providers);
|
||||||
crate::base::provide(providers);
|
crate::base::provide(&mut providers.queries);
|
||||||
crate::target_features::provide(providers);
|
crate::target_features::provide(&mut providers.queries);
|
||||||
crate::codegen_attrs::provide(providers);
|
crate::codegen_attrs::provide(&mut providers.queries);
|
||||||
providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![];
|
providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -833,12 +833,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
|
|
||||||
// const-eval of `panic_display` assumes the argument is `&&str`
|
// const-eval of `panic_display` assumes the argument is `&&str`
|
||||||
if tcx.is_lang_item(callee, LangItem::PanicDisplay) {
|
if tcx.is_lang_item(callee, LangItem::PanicDisplay) {
|
||||||
match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
|
if let ty::Ref(_, ty, _) =
|
||||||
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
|
args[0].node.ty(&self.ccx.body.local_decls, tcx).kind()
|
||||||
{}
|
&& let ty::Ref(_, ty, _) = ty.kind()
|
||||||
_ => {
|
&& ty.is_str()
|
||||||
self.check_op(ops::PanicNonStr);
|
{
|
||||||
}
|
} else {
|
||||||
|
self.check_op(ops::PanicNonStr);
|
||||||
}
|
}
|
||||||
// Allow this call, skip all the checks below.
|
// Allow this call, skip all the checks below.
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -30,20 +30,20 @@ pub use self::errors::ReportErrorExt;
|
||||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
const_eval::provide(providers);
|
const_eval::provide(&mut providers.queries);
|
||||||
providers.tag_for_variant = const_eval::tag_for_variant_provider;
|
providers.queries.tag_for_variant = const_eval::tag_for_variant_provider;
|
||||||
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
|
providers.queries.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.queries.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
|
||||||
providers.eval_static_initializer = const_eval::eval_static_initializer_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.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)
|
const_eval::eval_to_valtree(tcx, typing_env, value)
|
||||||
};
|
};
|
||||||
providers.hooks.try_destructure_mir_constant_for_user_output =
|
providers.hooks.try_destructure_mir_constant_for_user_output =
|
||||||
const_eval::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);
|
|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)
|
util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
|
||||||
};
|
};
|
||||||
providers.hooks.validate_scalar_in_layout =
|
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(|| {
|
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
|
||||||
let providers = &mut Providers::default();
|
let providers = &mut Providers::default();
|
||||||
providers.analysis = analysis;
|
providers.queries.analysis = analysis;
|
||||||
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
|
providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir;
|
||||||
providers.resolver_for_lowering_raw = resolver_for_lowering_raw;
|
providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw;
|
||||||
providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
|
providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..];
|
||||||
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
|
providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
|
||||||
providers.early_lint_checks = early_lint_checks;
|
providers.queries.early_lint_checks = early_lint_checks;
|
||||||
providers.env_var_os = env_var_os;
|
providers.queries.env_var_os = env_var_os;
|
||||||
limits::provide(providers);
|
limits::provide(&mut providers.queries);
|
||||||
proc_macro_decls::provide(providers);
|
proc_macro_decls::provide(&mut providers.queries);
|
||||||
rustc_const_eval::provide(providers);
|
rustc_const_eval::provide(providers);
|
||||||
rustc_middle::hir::provide(providers);
|
rustc_middle::hir::provide(&mut providers.queries);
|
||||||
rustc_borrowck::provide(providers);
|
rustc_borrowck::provide(&mut providers.queries);
|
||||||
rustc_incremental::provide(providers);
|
rustc_incremental::provide(providers);
|
||||||
rustc_mir_build::provide(providers);
|
rustc_mir_build::provide(providers);
|
||||||
rustc_mir_transform::provide(providers);
|
rustc_mir_transform::provide(providers);
|
||||||
rustc_monomorphize::provide(providers);
|
rustc_monomorphize::provide(providers);
|
||||||
rustc_privacy::provide(providers);
|
rustc_privacy::provide(&mut providers.queries);
|
||||||
rustc_query_impl::provide(providers);
|
rustc_query_impl::provide(providers);
|
||||||
rustc_resolve::provide(providers);
|
rustc_resolve::provide(&mut providers.queries);
|
||||||
rustc_hir_analysis::provide(providers);
|
rustc_hir_analysis::provide(&mut providers.queries);
|
||||||
rustc_hir_typeck::provide(providers);
|
rustc_hir_typeck::provide(&mut providers.queries);
|
||||||
ty::provide(providers);
|
ty::provide(&mut providers.queries);
|
||||||
traits::provide(providers);
|
traits::provide(&mut providers.queries);
|
||||||
solve::provide(providers);
|
solve::provide(&mut providers.queries);
|
||||||
rustc_passes::provide(providers);
|
rustc_passes::provide(&mut providers.queries);
|
||||||
rustc_traits::provide(providers);
|
rustc_traits::provide(&mut providers.queries);
|
||||||
rustc_ty_utils::provide(providers);
|
rustc_ty_utils::provide(&mut providers.queries);
|
||||||
rustc_metadata::provide(providers);
|
rustc_metadata::provide(providers);
|
||||||
rustc_lint::provide(providers);
|
rustc_lint::provide(&mut providers.queries);
|
||||||
rustc_symbol_mangling::provide(providers);
|
rustc_symbol_mangling::provide(&mut providers.queries);
|
||||||
rustc_codegen_ssa::provide(providers);
|
rustc_codegen_ssa::provide(providers);
|
||||||
*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
|
// `build_script_build`) to try to figure out if we are building a Cargo build script
|
||||||
|
|
||||||
let unescaped = &inst(EscapeQuotes::No);
|
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)
|
lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped)
|
||||||
} else {
|
} else {
|
||||||
lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))
|
lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,9 @@ fn check_int_to_ptr_transmute<'tcx>(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// bail-out if the argument is literal 0 as we have other lints for those cases
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
// bail-out if the inner type is a ZST
|
// bail-out if the inner type is a ZST
|
||||||
|
|
|
||||||
|
|
@ -585,6 +585,6 @@ const SYMBOL_OFFSET: u8 = 1;
|
||||||
const SYMBOL_PREDEFINED: u8 = 2;
|
const SYMBOL_PREDEFINED: u8 = 2;
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
encoder::provide(providers);
|
encoder::provide(&mut providers.queries);
|
||||||
decoder::provide(providers);
|
decoder::provide(providers);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1871,13 +1871,16 @@ fn pretty_print_const_value_tcx<'tcx>(
|
||||||
let u8_type = tcx.types.u8;
|
let u8_type = tcx.types.u8;
|
||||||
match (ct, ty.kind()) {
|
match (ct, ty.kind()) {
|
||||||
// Byte/string slices, printed as (byte) string literals.
|
// 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) {
|
if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
|
||||||
fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
|
fmt.write_str(&format!("{:?}", String::from_utf8_lossy(data)))?;
|
||||||
return Ok(());
|
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) {
|
if let Some(data) = ct.try_get_slice_bytes_for_diagnostics(tcx) {
|
||||||
pretty_print_byte_str(fmt, data)?;
|
pretty_print_byte_str(fmt, data)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,3 @@ pub struct Providers {
|
||||||
pub extern_queries: crate::query::ExternProviders,
|
pub extern_queries: crate::query::ExternProviders,
|
||||||
pub hooks: crate::hooks::Providers,
|
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" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
providers.check_match = thir::pattern::check_match;
|
providers.queries.check_match = thir::pattern::check_match;
|
||||||
providers.lit_to_const = thir::constant::lit_to_const;
|
providers.queries.lit_to_const = thir::constant::lit_to_const;
|
||||||
providers.closure_saved_names_of_captured_variables =
|
providers.queries.closure_saved_names_of_captured_variables =
|
||||||
builder::closure_saved_names_of_captured_variables;
|
builder::closure_saved_names_of_captured_variables;
|
||||||
providers.check_unsafety = check_unsafety::check_unsafety;
|
providers.queries.check_unsafety = check_unsafety::check_unsafety;
|
||||||
providers.check_tail_calls = check_tail_calls::check_tail_calls;
|
providers.queries.check_tail_calls = check_tail_calls::check_tail_calls;
|
||||||
providers.thir_body = thir::cx::thir_body;
|
providers.queries.thir_body = thir::cx::thir_body;
|
||||||
providers.hooks.build_mir_inner_impl = builder::build_mir_inner_impl;
|
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) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
coverage::query::provide(providers);
|
coverage::query::provide(providers);
|
||||||
ffi_unwind_calls::provide(providers);
|
ffi_unwind_calls::provide(&mut providers.queries);
|
||||||
shim::provide(providers);
|
shim::provide(&mut providers.queries);
|
||||||
cross_crate_inline::provide(providers);
|
cross_crate_inline::provide(&mut providers.queries);
|
||||||
providers.queries = query::Providers {
|
providers.queries = query::Providers {
|
||||||
mir_keys,
|
mir_keys,
|
||||||
mir_built,
|
mir_built,
|
||||||
|
|
|
||||||
|
|
@ -1825,5 +1825,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
|
||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
providers.hooks.should_codegen_locally = should_codegen_locally;
|
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) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
partitioning::provide(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) {
|
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);
|
|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(())
|
tcx.collect_and_partition_mono_items(())
|
||||||
.codegen_units
|
.codegen_units
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -1326,7 +1326,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||||
.unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
|
.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 {
|
match instance.def {
|
||||||
// "Normal" functions size estimate: the number of
|
// "Normal" functions size estimate: the number of
|
||||||
// statements, plus one for the terminator.
|
// 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.
|
// 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);
|
self.check_for_misspelled_kw(&mut err, &expected);
|
||||||
}
|
}
|
||||||
Err(err)
|
Err(err)
|
||||||
|
|
|
||||||
|
|
@ -1203,10 +1203,9 @@ impl<'a> Parser<'a> {
|
||||||
let mut token = Token::dummy();
|
let mut token = Token::dummy();
|
||||||
while i < dist {
|
while i < dist {
|
||||||
token = cursor.next().0;
|
token = cursor.next().0;
|
||||||
if matches!(
|
if let token::OpenInvisible(origin) | token::CloseInvisible(origin) = token.kind
|
||||||
token.kind,
|
&& origin.skip()
|
||||||
token::OpenInvisible(origin) | token::CloseInvisible(origin) if origin.skip()
|
{
|
||||||
) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
use rustc_middle::util::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
|
||||||
pub mod abi_test;
|
pub mod abi_test;
|
||||||
mod check_attr;
|
mod check_attr;
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
/// and report an error in case of a collision.
|
/// and report an error in case of a collision.
|
||||||
pub(crate) fn plant_decl_into_local_module(
|
pub(crate) fn plant_decl_into_local_module(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent: Module<'ra>,
|
|
||||||
ident: Macros20NormalizedIdent,
|
ident: Macros20NormalizedIdent,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
decl: Decl<'ra>,
|
decl: Decl<'ra>,
|
||||||
) {
|
) {
|
||||||
if let Err(old_decl) = self.try_plant_decl_into_local_module(parent, ident, ns, decl, false)
|
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);
|
||||||
self.report_conflict(parent, ident.0, ns, old_decl, decl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,9 +68,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
expn_id: LocalExpnId,
|
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);
|
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.
|
/// 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),
|
vis: CmCell::new(vis),
|
||||||
span,
|
span,
|
||||||
expansion,
|
expansion,
|
||||||
|
parent_module: Some(parent),
|
||||||
});
|
});
|
||||||
// Even if underscore names cannot be looked up, we still need to add them to modules,
|
// 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
|
// 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 ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
|
||||||
let span = child_span(self, reexport_chain, res);
|
let span = child_span(self, reexport_chain, res);
|
||||||
let res = res.expect_non_local();
|
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.
|
// Record primary definitions.
|
||||||
|
|
@ -844,7 +843,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
ident,
|
ident,
|
||||||
local_def_id,
|
local_def_id,
|
||||||
vis,
|
vis,
|
||||||
parent,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -976,10 +974,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
local_def_id: LocalDefId,
|
local_def_id: LocalDefId,
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
parent: Module<'ra>,
|
|
||||||
) {
|
) {
|
||||||
let sp = item.span;
|
let sp = item.span;
|
||||||
let parent_scope = self.parent_scope;
|
let parent_scope = self.parent_scope;
|
||||||
|
let parent = parent_scope.module;
|
||||||
let expansion = parent_scope.expansion;
|
let expansion = parent_scope.expansion;
|
||||||
|
|
||||||
let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower {
|
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 {
|
let import = self.r.arenas.alloc_import(ImportData {
|
||||||
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
|
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
|
||||||
root_id: item.id,
|
root_id: item.id,
|
||||||
parent_scope: self.parent_scope,
|
parent_scope,
|
||||||
imported_module: CmCell::new(module),
|
imported_module: CmCell::new(module),
|
||||||
has_attributes: !item.attrs.is_empty(),
|
has_attributes: !item.attrs.is_empty(),
|
||||||
use_span_with_attributes: item.span_with_attributes(),
|
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.
|
/// Constructs the reduced graph for one foreign item.
|
||||||
|
|
@ -1300,14 +1298,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
Visibility::Restricted(CRATE_DEF_ID)
|
Visibility::Restricted(CRATE_DEF_ID)
|
||||||
};
|
};
|
||||||
let decl = self.r.arenas.new_def_decl(res, vis.to_def_id(), span, expansion);
|
let decl = self.r.arenas.new_def_decl(
|
||||||
self.r.set_decl_parent_module(decl, parent_scope.module);
|
res,
|
||||||
|
vis.to_def_id(),
|
||||||
|
span,
|
||||||
|
expansion,
|
||||||
|
Some(parent_scope.module),
|
||||||
|
);
|
||||||
self.r.all_macro_rules.insert(ident.name);
|
self.r.all_macro_rules.insert(ident.name);
|
||||||
if is_macro_export {
|
if is_macro_export {
|
||||||
let import = self.r.arenas.alloc_import(ImportData {
|
let import = self.r.arenas.alloc_import(ImportData {
|
||||||
kind: ImportKind::MacroExport,
|
kind: ImportKind::MacroExport,
|
||||||
root_id: item.id,
|
root_id: item.id,
|
||||||
parent_scope: self.parent_scope,
|
parent_scope: ParentScope { module: self.r.graph_root, ..parent_scope },
|
||||||
imported_module: CmCell::new(None),
|
imported_module: CmCell::new(None),
|
||||||
has_attributes: false,
|
has_attributes: false,
|
||||||
use_span_with_attributes: span,
|
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);
|
self.r.import_use_map.insert(import, Used::Other);
|
||||||
let import_decl = self.r.new_import_decl(decl, import);
|
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 {
|
} else {
|
||||||
self.r.check_reserved_macro_name(ident.0, res);
|
self.r.check_reserved_macro_name(ident.0, res);
|
||||||
self.insert_unused_macro(ident.0, def_id, item.id);
|
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(
|
pub(crate) fn report_conflict(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent: Module<'_>,
|
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
new_binding: Decl<'ra>,
|
new_binding: Decl<'ra>,
|
||||||
|
|
@ -218,13 +217,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
) {
|
) {
|
||||||
// Error on the second of two conflicting names
|
// Error on the second of two conflicting names
|
||||||
if old_binding.span.lo() > new_binding.span.lo() {
|
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
|
// Avoid using TyCtxt::def_kind_descr in the resolver, because it
|
||||||
// indirectly *calls* the resolver, and would cause a query cycle.
|
// 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",
|
ModuleKind::Block => "block",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2034,15 +2033,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously"))
|
help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope {
|
if kind != AmbiguityKind::GlobVsGlob {
|
||||||
if module == self.graph_root {
|
if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope {
|
||||||
help_msgs.push(format!(
|
if module == self.graph_root {
|
||||||
"use `crate::{ident}` to refer to this {thing} unambiguously"
|
help_msgs.push(format!(
|
||||||
));
|
"use `crate::{ident}` to refer to this {thing} unambiguously"
|
||||||
} else if module != self.empty_module && module.is_normal() {
|
));
|
||||||
help_msgs.push(format!(
|
} else if module.is_normal() {
|
||||||
"use `self::{ident}` to refer to this {thing} unambiguously"
|
help_msgs.push(format!(
|
||||||
));
|
"use `self::{ident}` to refer to this {thing} unambiguously"
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -867,6 +867,19 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg {
|
||||||
pub applicability: Applicability,
|
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)]
|
#[derive(Subdiagnostic)]
|
||||||
#[suggestion(
|
#[suggestion(
|
||||||
resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg,
|
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,
|
span: import.span,
|
||||||
vis: CmCell::new(vis),
|
vis: CmCell::new(vis),
|
||||||
expansion: import.parent_scope.expansion,
|
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.
|
/// and return existing declaration if there is a collision.
|
||||||
pub(crate) fn try_plant_decl_into_local_module(
|
pub(crate) fn try_plant_decl_into_local_module(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: Module<'ra>,
|
|
||||||
ident: Macros20NormalizedIdent,
|
ident: Macros20NormalizedIdent,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
decl: Decl<'ra>,
|
decl: Decl<'ra>,
|
||||||
warn_ambiguity: bool,
|
warn_ambiguity: bool,
|
||||||
) -> Result<(), Decl<'ra>> {
|
) -> Result<(), Decl<'ra>> {
|
||||||
|
let module = decl.parent_module.unwrap();
|
||||||
let res = decl.res();
|
let res = decl.res();
|
||||||
self.check_reserved_macro_name(ident.0, 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,
|
// 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
|
// because they can be fetched by glob imports from those modules, and bring traits
|
||||||
// into scope both directly and through glob imports.
|
// 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) {
|
if self.is_accessible_from(binding.vis(), scope) {
|
||||||
let import_decl = self.new_import_decl(binding, *import);
|
let import_decl = self.new_import_decl(binding, *import);
|
||||||
let _ = self.try_plant_decl_into_local_module(
|
let _ = self.try_plant_decl_into_local_module(
|
||||||
import.parent_scope.module,
|
|
||||||
ident,
|
ident,
|
||||||
key.ns,
|
key.ns,
|
||||||
import_decl,
|
import_decl,
|
||||||
|
|
@ -535,7 +534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
self.per_ns(|this, ns| {
|
self.per_ns(|this, ns| {
|
||||||
let module = import.parent_scope.module;
|
let module = import.parent_scope.module;
|
||||||
let ident = Macros20NormalizedIdent::new(target);
|
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.
|
// Don't remove underscores from `single_imports`, they were never added.
|
||||||
if target.name != kw::Underscore {
|
if target.name != kw::Underscore {
|
||||||
let key = BindingKey::new(ident, ns);
|
let key = BindingKey::new(ident, ns);
|
||||||
|
|
@ -916,7 +915,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
// We need the `target`, `source` can be extracted.
|
// We need the `target`, `source` can be extracted.
|
||||||
let import_decl = this.new_import_decl(binding, import);
|
let import_decl = this.new_import_decl(binding, import);
|
||||||
this.get_mut_unchecked().plant_decl_into_local_module(
|
this.get_mut_unchecked().plant_decl_into_local_module(
|
||||||
parent,
|
|
||||||
Macros20NormalizedIdent::new(target),
|
Macros20NormalizedIdent::new(target),
|
||||||
ns,
|
ns,
|
||||||
import_decl,
|
import_decl,
|
||||||
|
|
@ -1542,7 +1540,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
.and_then(|r| r.binding())
|
.and_then(|r| r.binding())
|
||||||
.is_some_and(|binding| binding.warn_ambiguity_recursive());
|
.is_some_and(|binding| binding.warn_ambiguity_recursive());
|
||||||
let _ = self.try_plant_decl_into_local_module(
|
let _ = self.try_plant_decl_into_local_module(
|
||||||
import.parent_scope.module,
|
|
||||||
key.ident,
|
key.ident,
|
||||||
key.ns,
|
key.ns,
|
||||||
import_decl,
|
import_decl,
|
||||||
|
|
|
||||||
|
|
@ -414,6 +414,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
|
|
||||||
/// Handles error reporting for `smart_resolve_path_fragment` function.
|
/// 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.
|
/// 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(
|
pub(crate) fn smart_resolve_report_errors(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &[Segment],
|
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);
|
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);
|
self.explain_functions_in_pattern(&mut err, res, source);
|
||||||
|
|
||||||
if self.suggest_pattern_match_with_let(&mut err, source, span) {
|
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<'_>,
|
err: &mut Diag<'_>,
|
||||||
res: Option<Res>,
|
res: Option<Res>,
|
||||||
source: PathSource<'_, '_, '_>,
|
source: PathSource<'_, '_, '_>,
|
||||||
|
path: &[Segment],
|
||||||
|
following_seg: Option<&Segment>,
|
||||||
span: Span,
|
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 };
|
let PathSource::Trait(_) = source else { return };
|
||||||
|
|
||||||
// We don't include `DefKind::Str` and `DefKind::AssocTy` as they can't be reached here anyway.
|
// 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::metadata::{AmbigModChild, ModChild, Reexport};
|
||||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::span_bug;
|
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools,
|
self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools,
|
||||||
ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
|
ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
|
||||||
|
|
@ -812,6 +811,7 @@ struct DeclData<'ra> {
|
||||||
expansion: LocalExpnId,
|
expansion: LocalExpnId,
|
||||||
span: Span,
|
span: Span,
|
||||||
vis: CmCell<Visibility<DefId>>,
|
vis: CmCell<Visibility<DefId>>,
|
||||||
|
parent_module: Option<Module<'ra>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All name declarations are unique and allocated on a same arena,
|
/// All name declarations are unique and allocated on a same arena,
|
||||||
|
|
@ -922,7 +922,6 @@ struct AmbiguityError<'ra> {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
b1: Decl<'ra>,
|
b1: Decl<'ra>,
|
||||||
b2: Decl<'ra>,
|
b2: Decl<'ra>,
|
||||||
// `empty_module` in module scope serves as an unknown module here.
|
|
||||||
scope1: Scope<'ra>,
|
scope1: Scope<'ra>,
|
||||||
scope2: Scope<'ra>,
|
scope2: Scope<'ra>,
|
||||||
warning: Option<AmbiguityWarning>,
|
warning: Option<AmbiguityWarning>,
|
||||||
|
|
@ -1186,7 +1185,6 @@ pub struct Resolver<'ra, 'tcx> {
|
||||||
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
|
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
|
||||||
/// Lazily populated cache of modules loaded from external crates.
|
/// Lazily populated cache of modules loaded from external crates.
|
||||||
extern_module_map: CacheRefCell<FxIndexMap<DefId, Module<'ra>>>,
|
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.
|
/// Maps glob imports to the names of items actually imported.
|
||||||
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
|
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
|
||||||
|
|
@ -1349,6 +1347,7 @@ impl<'ra> ResolverArenas<'ra> {
|
||||||
vis: Visibility<DefId>,
|
vis: Visibility<DefId>,
|
||||||
span: Span,
|
span: Span,
|
||||||
expansion: LocalExpnId,
|
expansion: LocalExpnId,
|
||||||
|
parent_module: Option<Module<'ra>>,
|
||||||
) -> Decl<'ra> {
|
) -> Decl<'ra> {
|
||||||
self.alloc_decl(DeclData {
|
self.alloc_decl(DeclData {
|
||||||
kind: DeclKind::Def(res),
|
kind: DeclKind::Def(res),
|
||||||
|
|
@ -1357,11 +1356,12 @@ impl<'ra> ResolverArenas<'ra> {
|
||||||
vis: CmCell::new(vis),
|
vis: CmCell::new(vis),
|
||||||
span,
|
span,
|
||||||
expansion,
|
expansion,
|
||||||
|
parent_module,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_pub_def_decl(&'ra self, res: Res, span: Span, expn_id: LocalExpnId) -> Decl<'ra> {
|
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(
|
fn new_module(
|
||||||
|
|
@ -1616,7 +1616,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
local_module_map,
|
local_module_map,
|
||||||
extern_module_map: Default::default(),
|
extern_module_map: Default::default(),
|
||||||
block_map: Default::default(),
|
block_map: Default::default(),
|
||||||
decl_parent_modules: FxHashMap::default(),
|
|
||||||
ast_transform_scopes: FxHashMap::default(),
|
ast_transform_scopes: FxHashMap::default(),
|
||||||
|
|
||||||
glob_map: Default::default(),
|
glob_map: Default::default(),
|
||||||
|
|
@ -2071,8 +2070,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
ident,
|
ident,
|
||||||
b1: used_decl,
|
b1: used_decl,
|
||||||
b2,
|
b2,
|
||||||
scope1: Scope::ModuleGlobs(self.empty_module, None),
|
scope1: Scope::ModuleGlobs(used_decl.parent_module.unwrap(), None),
|
||||||
scope2: Scope::ModuleGlobs(self.empty_module, None),
|
scope2: Scope::ModuleGlobs(b2.parent_module.unwrap(), None),
|
||||||
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
|
warning: if warn_ambiguity { Some(AmbiguityWarning::GlobImport) } else { None },
|
||||||
};
|
};
|
||||||
if !self.matches_previous_ambiguity_error(&ambiguity_error) {
|
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)
|
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(
|
fn disambiguate_macro_rules_vs_modularized(
|
||||||
&self,
|
&self,
|
||||||
macro_rules: Decl<'ra>,
|
macro_rules: Decl<'ra>,
|
||||||
|
|
@ -2254,13 +2245,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
// is disambiguated to mitigate regressions from macro modularization.
|
// is disambiguated to mitigate regressions from macro modularization.
|
||||||
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
|
// 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
|
// `resolve_ident_in_scope_set` which will always refer to a local binding from an
|
||||||
// import or macro definition
|
// import or macro definition.
|
||||||
let macro_rules = &self.decl_parent_modules[¯o_rules];
|
let macro_rules = macro_rules.parent_module.unwrap();
|
||||||
let modularized = &self.decl_parent_modules[&modularized];
|
let modularized = modularized.parent_module.unwrap();
|
||||||
macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
|
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>(
|
fn extern_prelude_get_item<'r>(
|
||||||
|
|
|
||||||
|
|
@ -681,7 +681,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
// Ambiguous predicates should never error
|
// Ambiguous predicates should never error
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
// We never return Err when proving UnstableFeature goal.
|
// We never return Err when proving UnstableFeature goal.
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature{ .. })
|
| ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })
|
||||||
| ty::PredicateKind::NormalizesTo { .. }
|
| ty::PredicateKind::NormalizesTo { .. }
|
||||||
| ty::PredicateKind::AliasRelate { .. }
|
| ty::PredicateKind::AliasRelate { .. }
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
|
||||||
|
|
|
||||||
|
|
@ -4759,7 +4759,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
// slices of `element_ty` with `mutability`.
|
// slices of `element_ty` with `mutability`.
|
||||||
let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
|
let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
|
||||||
ty::RawPtr(t, m) | ty::Ref(_, t, m) => {
|
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)
|
&& m == mutability.unwrap_or(m)
|
||||||
{
|
{
|
||||||
// Use the candidate's mutability going forward.
|
// 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() {
|
if let ty::PredicatePolarity::Positive = trait_predicate.polarity() {
|
||||||
format!(
|
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(),
|
trait_predicate.print_modifiers_and_trait_path(),
|
||||||
tcx.short_string(trait_predicate.self_ty().skip_binder(), long_ty_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")]
|
#[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>`.
|
/// Creates an empty `BinaryHeap<T>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> BinaryHeap<T> {
|
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.
|
/// Creates an empty `BinaryHeap` as a max-heap.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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.
|
/// Creates an empty `BinaryHeap` as a max-heap, using `A` as allocator.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # 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> {
|
pub fn with_capacity_in(capacity: usize, alloc: A) -> BinaryHeap<T, A> {
|
||||||
BinaryHeap { data: Vec::with_capacity_in(capacity, alloc) }
|
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
|
/// Returns a mutable reference to the greatest item in the binary heap, or
|
||||||
/// `None` if it is empty.
|
/// `None` if it is empty.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -1143,11 +1143,12 @@ impl char {
|
||||||
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
|
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
/// `'ſt'` (U+FB05) is a single Unicode code point (a ligature) that maps to "ST" in uppercase.
|
||||||
///
|
///
|
||||||
/// As an iterator:
|
/// As an iterator:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// for c in 'ß'.to_uppercase() {
|
/// for c in 'ſt'.to_uppercase() {
|
||||||
/// print!("{c}");
|
/// print!("{c}");
|
||||||
/// }
|
/// }
|
||||||
/// println!();
|
/// println!();
|
||||||
|
|
@ -1156,13 +1157,13 @@ impl char {
|
||||||
/// Using `println!` directly:
|
/// Using `println!` directly:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// println!("{}", 'ß'.to_uppercase());
|
/// println!("{}", 'ſt'.to_uppercase());
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Both are equivalent to:
|
/// Both are equivalent to:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// println!("SS");
|
/// println!("ST");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
|
/// 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");
|
/// assert_eq!('c'.to_uppercase().to_string(), "C");
|
||||||
///
|
///
|
||||||
/// // Sometimes the result is more than one character:
|
/// // 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
|
/// // Characters that do not have both uppercase and lowercase
|
||||||
/// // convert into themselves.
|
/// // 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 *successor* operation moves towards values that compare greater.
|
||||||
/// The *predecessor* operation moves towards values that compare lesser.
|
/// The *predecessor* operation moves towards values that compare lesser.
|
||||||
#[rustc_diagnostic_item = "range_step"]
|
#[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")]
|
#[unstable(feature = "step_trait", issue = "42168")]
|
||||||
pub trait Step: Clone + PartialOrd + Sized {
|
pub trait Step: Clone + PartialOrd + Sized {
|
||||||
/// Returns the bounds on the number of *successor* steps required to get from `start` to `end`
|
/// Returns the bounds on the number of *successor* steps required to get from `start` to `end`
|
||||||
|
|
|
||||||
|
|
@ -653,7 +653,7 @@ impl Error {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn last_os_error() -> Error {
|
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.
|
/// Creates a new instance of an [`Error`] from a particular OS error code.
|
||||||
|
|
@ -1004,7 +1004,7 @@ impl Error {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn kind(&self) -> ErrorKind {
|
pub fn kind(&self) -> ErrorKind {
|
||||||
match self.repr.data() {
|
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::Custom(c) => c.kind,
|
||||||
ErrorData::Simple(kind) => kind,
|
ErrorData::Simple(kind) => kind,
|
||||||
ErrorData::SimpleMessage(m) => m.kind,
|
ErrorData::SimpleMessage(m) => m.kind,
|
||||||
|
|
@ -1014,7 +1014,7 @@ impl Error {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_interrupted(&self) -> bool {
|
pub(crate) fn is_interrupted(&self) -> bool {
|
||||||
match self.repr.data() {
|
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::Custom(c) => c.kind == ErrorKind::Interrupted,
|
||||||
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
|
ErrorData::Simple(kind) => kind == ErrorKind::Interrupted,
|
||||||
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
|
ErrorData::SimpleMessage(m) => m.kind == ErrorKind::Interrupted,
|
||||||
|
|
@ -1028,8 +1028,8 @@ impl fmt::Debug for Repr {
|
||||||
ErrorData::Os(code) => fmt
|
ErrorData::Os(code) => fmt
|
||||||
.debug_struct("Os")
|
.debug_struct("Os")
|
||||||
.field("code", &code)
|
.field("code", &code)
|
||||||
.field("kind", &sys::decode_error_kind(code))
|
.field("kind", &sys::io::decode_error_kind(code))
|
||||||
.field("message", &sys::os::error_string(code))
|
.field("message", &sys::io::error_string(code))
|
||||||
.finish(),
|
.finish(),
|
||||||
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
|
ErrorData::Custom(c) => fmt::Debug::fmt(&c, fmt),
|
||||||
ErrorData::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
|
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 {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.repr.data() {
|
match self.repr.data() {
|
||||||
ErrorData::Os(code) => {
|
ErrorData::Os(code) => {
|
||||||
let detail = sys::os::error_string(code);
|
let detail = sys::io::error_string(code);
|
||||||
write!(fmt, "{detail} (os error {code})")
|
write!(fmt, "{detail} (os error {code})")
|
||||||
}
|
}
|
||||||
ErrorData::Custom(ref c) => c.error.fmt(fmt),
|
ErrorData::Custom(ref c) => c.error.fmt(fmt),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
|
use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
|
||||||
use crate::assert_matches::assert_matches;
|
use crate::assert_matches::assert_matches;
|
||||||
use crate::sys::decode_error_kind;
|
use crate::sys::io::{decode_error_kind, error_string};
|
||||||
use crate::sys::os::error_string;
|
|
||||||
use crate::{error, fmt};
|
use crate::{error, fmt};
|
||||||
|
|
||||||
#[test]
|
#[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,
|
val_ptr: *mut r_efi::efi::Char16,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let shell = helpers::open_shell().ok_or(unsupported_err())?;
|
let shell = helpers::open_shell().ok_or(unsupported_err())?;
|
||||||
let r =
|
let volatile = r_efi::efi::Boolean::TRUE;
|
||||||
unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, r_efi::efi::Boolean::FALSE) };
|
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(()) }
|
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
|
// lifetime of the thread. Additionally, accesses to `errno` are
|
||||||
// async-signal-safe, so this function is available in all imaginable
|
// async-signal-safe, so this function is available in all imaginable
|
||||||
// circumstances.
|
// 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) {
|
match EXITING_THREAD_ID.compare_exchange(ptr::null_mut(), this_thread_id, Acquire, Relaxed) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// This is the first thread to call `unique_thread_exit`,
|
// This is the first thread to call `unique_thread_exit`,
|
||||||
|
|
|
||||||
|
|
@ -850,7 +850,7 @@ impl Iterator for ReadDir {
|
||||||
target_os = "wasi",
|
target_os = "wasi",
|
||||||
))]
|
))]
|
||||||
fn next(&mut self) -> Option<io::Result<DirEntry>> {
|
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 {
|
if self.end_of_stream {
|
||||||
return None;
|
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.
|
/// The downside is that it costs an extra syscall, so we only do it for debug.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
|
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
|
// this is similar to assert_unsafe_precondition!() but it doesn't require const
|
||||||
if core::ub_checks::check_library_ub() {
|
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)]
|
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
|
||||||
mod io_slice {
|
mod io_slice {
|
||||||
cfg_select! {
|
cfg_select! {
|
||||||
any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty", target_os = "wasi") => {
|
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;
|
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 io_slice::{IoSlice, IoSliceMut};
|
||||||
pub use is_terminal::is_terminal;
|
pub use is_terminal::is_terminal;
|
||||||
pub use kernel_copy::{CopyState, kernel_copy};
|
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
|
// Bare metal platforms usually have very small amounts of RAM
|
||||||
// (in the order of hundreds of KB)
|
// (in the order of hundreds of KB)
|
||||||
pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
|
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 {
|
loop {
|
||||||
let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) };
|
let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) };
|
||||||
if result.is_minus_one() {
|
if result.is_minus_one() {
|
||||||
let err = crate::sys::os::errno();
|
let err = crate::sys::io::errno();
|
||||||
match err {
|
match err {
|
||||||
libc::EINTR => continue,
|
libc::EINTR => continue,
|
||||||
libc::EISCONN => return Ok(()),
|
libc::EISCONN => return Ok(()),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::ffi::OsString;
|
use crate::ffi::OsString;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::os::unix::ffi::OsStringExt;
|
use crate::os::unix::ffi::OsStringExt;
|
||||||
use crate::sys::pal::os::errno;
|
use crate::sys::io::errno;
|
||||||
|
|
||||||
pub fn hostname() -> io::Result<OsString> {
|
pub fn hostname() -> io::Result<OsString> {
|
||||||
// Query the system for the maximum host name length.
|
// 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)]
|
#[doc(hidden)]
|
||||||
pub trait IsNegative {
|
pub trait IsNegative {
|
||||||
fn is_negative(&self) -> bool;
|
fn is_negative(&self) -> bool;
|
||||||
|
|
@ -131,12 +105,7 @@ impl IsNegative for i32 {
|
||||||
impl_is_negative! { i8 i16 i64 isize }
|
impl_is_negative! { i8 i16 i64 isize }
|
||||||
|
|
||||||
pub fn cvt<T: IsNegative>(t: T) -> io::Result<T> {
|
pub fn cvt<T: IsNegative>(t: T) -> io::Result<T> {
|
||||||
if t.is_negative() {
|
if t.is_negative() { Err(io::Error::from_raw_os_error(t.negate())) } else { Ok(t) }
|
||||||
let e = decode_error_kind(t.negate());
|
|
||||||
Err(io::Error::from(e))
|
|
||||||
} else {
|
|
||||||
Ok(t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cvt_r<T, F>(mut f: F) -> io::Result<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::sys::unsupported;
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
Ok(PathBuf::from("/"))
|
Ok(PathBuf::from("/"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,45 +44,6 @@ pub fn unsupported_err() -> io::Error {
|
||||||
io::Error::UNSUPPORTED_PLATFORM
|
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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
core::intrinsics::abort();
|
core::intrinsics::abort();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,37 +4,8 @@ use crate::ffi::{OsStr, OsString};
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::os::motor::ffi::OsStrExt;
|
use crate::os::motor::ffi::OsStrExt;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::sys::io::RawOsError;
|
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
moto_rt::fs::getcwd().map(PathBuf::from).map_err(map_motor_error)
|
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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
abi::usercalls::exit(true)
|
abi::usercalls::exit(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,9 @@
|
||||||
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
|
|
||||||
|
|
||||||
use crate::ffi::{OsStr, OsString};
|
use crate::ffi::{OsStr, OsString};
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::sys::{decode_error_kind, sgx_ineffective, unsupported};
|
use crate::sys::{sgx_ineffective, unsupported};
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,15 +38,6 @@ pub fn unsupported_err() -> io::Error {
|
||||||
io::Error::UNSUPPORTED_PLATFORM
|
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]
|
#[inline]
|
||||||
pub fn abort_internal() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
unsafe { libc::abort() }
|
unsafe { libc::abort() }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{error, itron, unsupported};
|
use super::{itron, unsupported};
|
||||||
use crate::ffi::{OsStr, OsString};
|
use crate::ffi::{OsStr, OsString};
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,61 +38,6 @@ pub unsafe fn cleanup() {
|
||||||
// stack_overflow::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)]
|
#[doc(hidden)]
|
||||||
pub trait IsMinusOne {
|
pub trait IsMinusOne {
|
||||||
fn is_minus_one(&self) -> bool;
|
fn is_minus_one(&self) -> bool;
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,6 @@ use crate::ffi::{OsStr, OsString};
|
||||||
use crate::path::PathBuf;
|
use crate::path::PathBuf;
|
||||||
use crate::{fmt, io, path};
|
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.
|
// Hardcoded to return 4096, since `sysconf` is only implemented as a stub.
|
||||||
pub fn page_size() -> usize {
|
pub fn page_size() -> usize {
|
||||||
// unsafe { libc::sysconf(libc::_SC_PAGESIZE) as 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
|
// 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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,52 +83,6 @@ pub const fn unsupported_err() -> io::Error {
|
||||||
io::const_error!(io::ErrorKind::Unsupported, "operation not supported on UEFI")
|
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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
if let Some(exit_boot_service_event) =
|
if let Some(exit_boot_service_event) =
|
||||||
NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
|
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) {
|
extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
|
||||||
uefi::env::disable_boot_services();
|
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::ptr::NonNull;
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
match helpers::open_shell() {
|
match helpers::open_shell() {
|
||||||
Some(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::ETIMEDOUT) => return false,
|
||||||
Some(libc::EINTR) => continue,
|
Some(libc::EINTR) => continue,
|
||||||
_ => return true,
|
_ => 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")]
|
#[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)
|
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.
|
// 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) })
|
match cvt(unsafe { libc::ioctl(self.0.as_raw_fd(), libc::PIDFD_GET_INFO, &mut pidfd_info) })
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
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
|
// kernel doesn't support that ioctl, try the glibc helper that looks at procfs
|
||||||
weak!(
|
weak!(
|
||||||
fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t;
|
fn pidfd_getpid(pidfd: RawFd) -> libc::pid_t;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use super::PidFd as InternalPidFd;
|
use super::PidFd as InternalPidFd;
|
||||||
use crate::assert_matches::assert_matches;
|
use crate::assert_matches::assert_matches;
|
||||||
use crate::io::ErrorKind;
|
|
||||||
use crate::os::fd::AsRawFd;
|
use crate::os::fd::AsRawFd;
|
||||||
use crate::os::linux::process::{ChildExt, CommandExt as _};
|
use crate::os::linux::process::{ChildExt, CommandExt as _};
|
||||||
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
|
use crate::os::unix::process::{CommandExt as _, ExitStatusExt};
|
||||||
|
|
@ -62,7 +61,9 @@ fn test_command_pidfd() {
|
||||||
if let Ok(pidfd) = child.pidfd() {
|
if let Ok(pidfd) = child.pidfd() {
|
||||||
match pidfd.as_inner().pid() {
|
match pidfd.as_inner().pid() {
|
||||||
Ok(pid) => assert_eq!(pid, id),
|
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),
|
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",
|
target_vendor = "apple",
|
||||||
)))]
|
)))]
|
||||||
'poll: {
|
'poll: {
|
||||||
use crate::sys::os::errno;
|
use crate::sys::io::errno;
|
||||||
let pfds: &mut [_] = &mut [
|
let pfds: &mut [_] = &mut [
|
||||||
libc::pollfd { fd: 0, events: 0, revents: 0 },
|
libc::pollfd { fd: 0, events: 0, revents: 0 },
|
||||||
libc::pollfd { fd: 1, 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",
|
target_os = "vita",
|
||||||
)))]
|
)))]
|
||||||
{
|
{
|
||||||
use crate::sys::os::errno;
|
use crate::sys::io::errno;
|
||||||
for fd in 0..3 {
|
for fd in 0..3 {
|
||||||
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
|
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
|
||||||
open_devnull();
|
open_devnull();
|
||||||
|
|
@ -224,63 +224,6 @@ pub unsafe fn cleanup() {
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub use libc::signal;
|
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)]
|
#[doc(hidden)]
|
||||||
pub trait IsMinusOne {
|
pub trait IsMinusOne {
|
||||||
fn is_minus_one(&self) -> bool;
|
fn is_minus_one(&self) -> bool;
|
||||||
|
|
|
||||||
|
|
@ -14,135 +14,8 @@ use crate::sys::cvt;
|
||||||
use crate::sys::helpers::run_path_with_cstr;
|
use crate::sys::helpers::run_path_with_cstr;
|
||||||
use crate::{fmt, io, iter, mem, ptr, slice, str};
|
use crate::{fmt, io, iter, mem, ptr, slice, str};
|
||||||
|
|
||||||
const TMPBUF_SZ: usize = 128;
|
|
||||||
|
|
||||||
const PATH_SEPARATOR: u8 = b':';
|
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")]
|
#[cfg(target_os = "espidf")]
|
||||||
pub fn getcwd() -> io::Result<PathBuf> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
Ok(PathBuf::from("/"))
|
Ok(PathBuf::from("/"))
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ use crate::hint::spin_loop;
|
||||||
use crate::ops::Range;
|
use crate::ops::Range;
|
||||||
use crate::sync::Mutex;
|
use crate::sync::Mutex;
|
||||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use crate::sys::os::errno_location;
|
use crate::sys::io::errno_location;
|
||||||
|
|
||||||
pub struct ThreadInfo {
|
pub struct ThreadInfo {
|
||||||
pub tid: u64,
|
pub tid: u64,
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,6 @@ pub fn unsupported_err() -> std_io::Error {
|
||||||
std_io::Error::UNSUPPORTED_PLATFORM
|
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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
core::intrinsics::abort();
|
core::intrinsics::abort();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,6 @@ use crate::marker::PhantomData;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ pub mod time;
|
||||||
#[path = "../unsupported/common.rs"]
|
#[path = "../unsupported/common.rs"]
|
||||||
mod unsupported_common;
|
mod unsupported_common;
|
||||||
|
|
||||||
pub use unsupported_common::{
|
pub use unsupported_common::{init, unsupported, unsupported_err};
|
||||||
decode_error_kind, init, is_interrupted, unsupported, unsupported_err,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::arch::global_asm;
|
use crate::arch::global_asm;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
#[path = "../unsupported/os.rs"]
|
#[path = "../unsupported/os.rs"]
|
||||||
mod unsupported_os;
|
mod unsupported_os;
|
||||||
pub use unsupported_os::{
|
pub use unsupported_os::{
|
||||||
JoinPathsError, SplitPaths, chdir, current_exe, errno, error_string, getcwd, getpid, home_dir,
|
JoinPathsError, SplitPaths, chdir, current_exe, getcwd, getpid, home_dir, join_paths,
|
||||||
join_paths, split_paths, temp_dir,
|
split_paths, temp_dir,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use super::unsupported;
|
pub use super::unsupported;
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,11 @@
|
||||||
#![forbid(unsafe_op_in_unsafe_fn)]
|
#![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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
unsafe { libc::abort() }
|
unsafe { libc::abort() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(target_env = "p1")]
|
#[cfg(target_env = "p1")]
|
||||||
pub(crate) fn err2io(err: wasi::Errno) -> std_io::Error {
|
pub(crate) fn err2io(err: wasi::Errno) -> crate::io::Error {
|
||||||
std_io::Error::from_raw_os_error(err.raw().into())
|
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,
|
// import conflict rules. If we glob export `helpers` and `common` together,
|
||||||
// then the compiler complains about conflicts.
|
// then the compiler complains about conflicts.
|
||||||
|
|
||||||
|
pub(crate) use helpers::abort_internal;
|
||||||
#[cfg(target_env = "p1")]
|
#[cfg(target_env = "p1")]
|
||||||
pub(crate) use helpers::err2io;
|
pub(crate) use helpers::err2io;
|
||||||
pub(crate) use helpers::{abort_internal, decode_error_kind, is_interrupted};
|
|
||||||
#[cfg(not(target_env = "p1"))]
|
#[cfg(not(target_env = "p1"))]
|
||||||
pub use os::IsMinusOne;
|
pub use os::IsMinusOne;
|
||||||
pub use os::{cvt, cvt_r};
|
pub use os::{cvt, cvt_r};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::os::wasi::prelude::*;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::sys::helpers::run_path_with_cstr;
|
use crate::sys::helpers::run_path_with_cstr;
|
||||||
use crate::sys::unsupported;
|
use crate::sys::unsupported;
|
||||||
use crate::{fmt, io, str};
|
use crate::{fmt, io};
|
||||||
|
|
||||||
// Add a few symbols not in upstream `libc` just yet.
|
// Add a few symbols not in upstream `libc` just yet.
|
||||||
pub mod libc {
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
let mut buf = Vec::with_capacity(512);
|
let mut buf = Vec::with_capacity(512);
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
|
|
@ -60,84 +60,6 @@ pub unsafe fn cleanup() {
|
||||||
winsock::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> {
|
pub fn unrolled_find_u16s(needle: u16, haystack: &[u16]) -> Option<usize> {
|
||||||
let ptr = haystack.as_ptr();
|
let ptr = haystack.as_ptr();
|
||||||
let mut start = haystack;
|
let mut start = haystack;
|
||||||
|
|
|
||||||
|
|
@ -15,66 +15,6 @@ use crate::path::{self, PathBuf};
|
||||||
use crate::sys::pal::{c, cvt};
|
use crate::sys::pal::{c, cvt};
|
||||||
use crate::{fmt, io, ptr};
|
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> {
|
pub struct SplitPaths<'a> {
|
||||||
data: EncodeWide<'a>,
|
data: EncodeWide<'a>,
|
||||||
must_yield: bool,
|
must_yield: bool,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use super::unsupported;
|
use super::unsupported;
|
||||||
use crate::ffi::{OsStr, OsString};
|
use crate::ffi::{OsStr, OsString};
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
use crate::os::xous::ffi::Error as XousError;
|
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::sync::atomic::{Atomic, AtomicPtr, Ordering};
|
use crate::sync::atomic::{Atomic, AtomicPtr, Ordering};
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,6 @@ pub fn unsupported_err() -> std_io::Error {
|
||||||
std_io::Error::UNSUPPORTED_PLATFORM
|
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() -> ! {
|
pub fn abort_internal() -> ! {
|
||||||
core::intrinsics::abort();
|
core::intrinsics::abort();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,6 @@ use crate::marker::PhantomData;
|
||||||
use crate::path::{self, PathBuf};
|
use crate::path::{self, PathBuf};
|
||||||
use crate::{fmt, io};
|
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> {
|
pub fn getcwd() -> io::Result<PathBuf> {
|
||||||
unsupported()
|
unsupported()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use crate::num::{NonZero, NonZeroI32};
|
||||||
use crate::path::Path;
|
use crate::path::Path;
|
||||||
use crate::process::StdioPipes;
|
use crate::process::StdioPipes;
|
||||||
use crate::sys::fs::File;
|
use crate::sys::fs::File;
|
||||||
|
use crate::sys::io::error_string;
|
||||||
use crate::sys::pal::helpers;
|
use crate::sys::pal::helpers;
|
||||||
use crate::sys::pal::os::error_string;
|
|
||||||
use crate::sys::unsupported;
|
use crate::sys::unsupported;
|
||||||
use crate::{fmt, io};
|
use crate::{fmt, io};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ cfg_select! {
|
||||||
|
|
||||||
let bit = (signum - 1) as usize;
|
let bit = (signum - 1) as usize;
|
||||||
if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
let raw = slice::from_raw_parts_mut(
|
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
|
// See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
|
||||||
#[cfg(target_os = "nto")]
|
#[cfg(target_os = "nto")]
|
||||||
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
|
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;
|
let mut delay = MIN_FORKSPAWN_SLEEP;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ use crate::os::fd::AsRawFd;
|
||||||
use crate::sync::OnceLock;
|
use crate::sync::OnceLock;
|
||||||
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||||
use crate::sync::atomic::{Atomic, AtomicBool};
|
use crate::sync::atomic::{Atomic, AtomicBool};
|
||||||
use crate::sys::pal::os::errno;
|
use crate::sys::io::errno;
|
||||||
use crate::sys::pal::weak::syscall;
|
use crate::sys::pal::weak::syscall;
|
||||||
|
|
||||||
fn getrandom(mut bytes: &mut [u8], insecure: bool) {
|
fn getrandom(mut bytes: &mut [u8], insecure: bool) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::cell::UnsafeCell;
|
use crate::cell::UnsafeCell;
|
||||||
|
use crate::sys::c;
|
||||||
use crate::sys::sync::{Mutex, mutex};
|
use crate::sys::sync::{Mutex, mutex};
|
||||||
use crate::sys::{c, os};
|
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
|
|
||||||
pub struct Condvar {
|
pub struct Condvar {
|
||||||
|
|
@ -30,7 +30,7 @@ impl Condvar {
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
if r == 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
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,9 @@ use crate::num::NonZero;
|
||||||
use crate::sys::weak::dlsym;
|
use crate::sys::weak::dlsym;
|
||||||
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
|
#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
|
||||||
use crate::sys::weak::weak;
|
use crate::sys::weak::weak;
|
||||||
use crate::sys::{os, stack_overflow};
|
|
||||||
use crate::thread::ThreadInit;
|
use crate::thread::ThreadInit;
|
||||||
use crate::time::Duration;
|
use crate::time::Duration;
|
||||||
use crate::{cmp, io, ptr};
|
use crate::{cmp, io, ptr, sys};
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "vxworks",
|
target_os = "vxworks",
|
||||||
|
|
@ -77,7 +76,7 @@ impl Thread {
|
||||||
// multiple of the system page size. Because it's definitely
|
// multiple of the system page size. Because it's definitely
|
||||||
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
// >= PTHREAD_STACK_MIN, it must be an alignment issue.
|
||||||
// Round up to the nearest page and try again.
|
// 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 =
|
let stack_size =
|
||||||
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
|
(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
|
// Now that the thread information is set, set up our stack
|
||||||
// overflow handler.
|
// overflow handler.
|
||||||
let _handler = stack_overflow::Handler::new();
|
let _handler = sys::stack_overflow::Handler::new();
|
||||||
|
|
||||||
rust_start();
|
rust_start();
|
||||||
}
|
}
|
||||||
|
|
@ -536,7 +535,7 @@ pub fn sleep(dur: Duration) {
|
||||||
secs -= ts.tv_sec as u64;
|
secs -= ts.tv_sec as u64;
|
||||||
let ts_ptr = &raw mut ts;
|
let ts_ptr = &raw mut ts;
|
||||||
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
|
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;
|
secs += ts.tv_sec as u64;
|
||||||
nsecs = ts.tv_nsec;
|
nsecs = ts.tv_nsec;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -297,14 +297,15 @@ pub(crate) fn create_config(
|
||||||
override_queries: Some(|_sess, providers| {
|
override_queries: Some(|_sess, providers| {
|
||||||
// We do not register late module lints, so this only runs `MissingDoc`.
|
// We do not register late module lints, so this only runs `MissingDoc`.
|
||||||
// Most lints will require typechecking, so just don't run them.
|
// 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
|
// 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);
|
static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default);
|
||||||
&EMPTY_SET
|
&EMPTY_SET
|
||||||
};
|
};
|
||||||
// In case typeck does end up being called, don't ICE in case there were name resolution errors
|
// 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,
|
// Closures' tables come from their outermost function,
|
||||||
// as they are part of the same "inference environment".
|
// as they are part of the same "inference environment".
|
||||||
// This avoids emitting errors for the parent twice (see similar code in `typeck_with_fallback`)
|
// 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);
|
let body = tcx.hir_body_owned_by(def_id);
|
||||||
debug!("visiting body for {def_id:?}");
|
debug!("visiting body for {def_id:?}");
|
||||||
EmitIgnoredResolutionErrors::new(tcx).visit_body(body);
|
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(),
|
extra_symbols: Vec::new(),
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ impl rustc_driver::Callbacks for MiriDepCompilerCalls {
|
||||||
config.override_queries = Some(|_, local_providers| {
|
config.override_queries = Some(|_, local_providers| {
|
||||||
// We need to add #[used] symbols to exported_symbols for `lookup_link_section`.
|
// We need to add #[used] symbols to exported_symbols for `lookup_link_section`.
|
||||||
// FIXME handle this somehow in rustc itself to avoid this hack.
|
// 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
|
let reachable_set = tcx
|
||||||
.with_stable_hashing_context(|hcx| tcx.reachable_set(()).to_sorted(&hcx, true));
|
.with_stable_hashing_context(|hcx| tcx.reachable_set(()).to_sorted(&hcx, true));
|
||||||
tcx.arena.alloc_from_iter(
|
tcx.arena.alloc_from_iter(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
//@ should-fail
|
//@ known-bug: #49892
|
||||||
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||||
//! FIXME(#49892)
|
|
||||||
//! Test that the derived implementation of `PartialEq` for `Option` is not fully
|
//! 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
|
//! optimized by LLVM. If this starts passing, the test and manual impl should
|
||||||
//! be removed.
|
//! be removed.
|
||||||
|
|
@ -18,7 +17,7 @@ pub enum Option<T> {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn non_zero_eq(l: Option<NonZero<u32>>, r: Option<NonZero<u32>>) -> bool {
|
pub fn non_zero_eq(l: Option<NonZero<u32>>, r: Option<NonZero<u32>>) -> bool {
|
||||||
// CHECK: start:
|
// CHECK: start:
|
||||||
// CHECK-NEXT: icmp eq i32
|
// COMMENTEDCHECK-NEXT: icmp eq i32
|
||||||
// CHECK-NEXT: ret i1
|
// COMMENTEDCHECK-NEXT: ret i1
|
||||||
l == r
|
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
|
--> missing-bound.rs:2:14
|
||||||
|
|
|
|
||||||
2 | for _ in t {}
|
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 `Iterator`
|
||||||
= note: required for `std::ops::Range<T>` to implement `IntoIterator`
|
= 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) {
|
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
|
// 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();
|
let mut providers = Providers::default();
|
||||||
rustc_borrowck::provide(&mut providers);
|
rustc_borrowck::provide(&mut providers.queries);
|
||||||
let original_mir_borrowck = providers.mir_borrowck;
|
let original_mir_borrowck = providers.queries.mir_borrowck;
|
||||||
original_mir_borrowck(tcx, def_id)
|
original_mir_borrowck(tcx, def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
|
||||||
LL | type Result = NotAValidResultType;
|
LL | type Result = NotAValidResultType;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
| ^^^^^^^^^^^^^^^^^^^ 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
|
--> $DIR/rustc-dev-remap.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | struct NotAValidResultType;
|
LL | struct NotAValidResultType;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf
|
||||||
LL | type Result = NotAValidResultType;
|
LL | type Result = NotAValidResultType;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
| ^^^^^^^^^^^^^^^^^^^ 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
|
--> $DIR/rustc-dev-remap.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | struct NotAValidResultType;
|
LL | struct NotAValidResultType;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ LL | #[derive(Diagnostic)]
|
||||||
LL | arg: NotIntoDiagArg,
|
LL | arg: NotIntoDiagArg,
|
||||||
| ^^^^^^^^^^^^^^ unsatisfied trait bound
|
| ^^^^^^^^^^^^^^ 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
|
--> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
|
||||||
|
|
|
|
||||||
LL | struct NotIntoDiagArg;
|
LL | struct NotIntoDiagArg;
|
||||||
|
|
@ -29,7 +29,7 @@ LL | #[derive(Subdiagnostic)]
|
||||||
LL | arg: NotIntoDiagArg,
|
LL | arg: NotIntoDiagArg,
|
||||||
| ^^^^^^^^^^^^^^ unsatisfied trait bound
|
| ^^^^^^^^^^^^^^ 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
|
--> $DIR/diagnostic-derive-doc-comment-field.rs:28:1
|
||||||
|
|
|
|
||||||
LL | struct NotIntoDiagArg;
|
LL | struct NotIntoDiagArg;
|
||||||
|
|
|
||||||
|
|
@ -657,7 +657,7 @@ LL | #[derive(Diagnostic)]
|
||||||
LL | other: Hello,
|
LL | other: Hello,
|
||||||
| ^^^^^ unsatisfied trait bound
|
| ^^^^^ 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
|
--> $DIR/diagnostic-derive.rs:40:1
|
||||||
|
|
|
|
||||||
LL | struct Hello {}
|
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
|
--> $DIR/issue-22565-rust-call.rs:3:1
|
||||||
|
|
|
|
||||||
LL | extern "rust-call" fn b(_i: i32) {}
|
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
|
error: functions with the "rust-call" ABI must take a single non-self tuple argument
|
||||||
--> $DIR/issue-22565-rust-call.rs:17:5
|
--> $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
|
--> $DIR/issue-22565-rust-call.rs:27:7
|
||||||
|
|
|
|
||||||
LL | b(10);
|
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
|
error: functions with the "rust-call" ABI must take a single non-self tuple argument
|
||||||
--> $DIR/issue-22565-rust-call.rs:29:5
|
--> $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
|
--> $DIR/coroutine-not-future.rs:36:21
|
||||||
|
|
|
|
||||||
LL | takes_coroutine(async_fn());
|
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
|
| 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
|
--> $DIR/coroutine-not-future.rs:38:21
|
||||||
|
|
|
|
||||||
LL | takes_coroutine(returns_async_block());
|
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
|
| 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
|
--> $DIR/coroutine-not-future.rs:40:21
|
||||||
|
|
|
|
||||||
LL | takes_coroutine(async {});
|
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
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use core::future::Future;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
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);
|
struct Tuple(i32);
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ async fn foo() -> Result<(), ()> {
|
||||||
async fn bar() -> Result<(), ()> {
|
async fn bar() -> Result<(), ()> {
|
||||||
foo()?; //~ ERROR the `?` operator can only be applied to values that implement `Try`
|
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<(), ()>>`
|
//~^ 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`
|
//~| HELP consider `await`ing on the `Future`
|
||||||
//~| NOTE in this expansion of desugaring of operator `?`
|
//~| NOTE in this expansion of desugaring of operator `?`
|
||||||
//~| 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()?;
|
LL | foo()?;
|
||||||
| ^^^^^^ the `?` operator cannot be applied to type `impl Future<Output = Result<(), ()>>`
|
| ^^^^^^ 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`
|
help: consider `await`ing on the `Future`
|
||||||
|
|
|
|
||||||
LL | foo().await?;
|
LL | foo().await?;
|
||||||
|
|
@ -16,7 +16,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try
|
||||||
LL | t?;
|
LL | t?;
|
||||||
| ^^ the `?` operator cannot be applied to type `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
|
--> $DIR/issue-61076.rs:7:1
|
||||||
|
|
|
|
||||||
LL | struct T;
|
LL | struct T;
|
||||||
|
|
|
||||||
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