Auto merge of #138595 - jhpratt:rollup-09pvfzu, r=jhpratt
Rollup of 9 pull requests Successful merges: - #136355 (Add `*_value` methods to proc_macro lib) - #137621 (Add std support to cygwin target) - #137793 (Stablize anonymous pipe) - #138341 (std: Mention clone-on-write mutation in Arc<T>) - #138517 (Improve upvar analysis for deref of child capture) - #138584 (Update Rust Foundation links in Readme) - #138586 (Document `#![register_tool]`) - #138590 (Flatten and simplify some control flow 🫓) - #138592 (update change entry for #137147) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9c67cecd12
88 changed files with 1025 additions and 341 deletions
17
Cargo.lock
17
Cargo.lock
|
@ -2082,6 +2082,13 @@ version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "literal-escaper"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"rustc-std-workspace-std 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lld-wrapper"
|
name = "lld-wrapper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3148,6 +3155,12 @@ version = "1.0.1"
|
||||||
name = "rustc-std-workspace-std"
|
name = "rustc-std-workspace-std"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-std-workspace-std"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aba676a20abe46e5b0f1b0deae474aaaf31407e6c71147159890574599da04ef"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_abi"
|
name = "rustc_abi"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
@ -3186,6 +3199,7 @@ name = "rustc_ast"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"literal-escaper",
|
||||||
"memchr",
|
"memchr",
|
||||||
"rustc_ast_ir",
|
"rustc_ast_ir",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
|
@ -3895,6 +3909,7 @@ name = "rustc_lexer"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"expect-test",
|
"expect-test",
|
||||||
|
"literal-escaper",
|
||||||
"memchr",
|
"memchr",
|
||||||
"unicode-properties",
|
"unicode-properties",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
|
@ -4157,6 +4172,7 @@ name = "rustc_parse"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"literal-escaper",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_ast_pretty",
|
"rustc_ast_pretty",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
|
@ -4179,6 +4195,7 @@ dependencies = [
|
||||||
name = "rustc_parse_format"
|
name = "rustc_parse_format"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"literal-escaper",
|
||||||
"rustc_index",
|
"rustc_index",
|
||||||
"rustc_lexer",
|
"rustc_lexer",
|
||||||
]
|
]
|
||||||
|
|
|
@ -67,11 +67,11 @@ See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
|
||||||
trademarks and logos (the "Rust Trademarks").
|
trademarks and logos (the "Rust Trademarks").
|
||||||
|
|
||||||
If you want to use these names or brands, please read the
|
If you want to use these names or brands, please read the
|
||||||
[media guide][media-guide].
|
[Rust language trademark policy][trademark-policy].
|
||||||
|
|
||||||
Third-party logos may be subject to third-party copyrights and trademarks. See
|
Third-party logos may be subject to third-party copyrights and trademarks. See
|
||||||
[Licenses][policies-licenses] for details.
|
[Licenses][policies-licenses] for details.
|
||||||
|
|
||||||
[rust-foundation]: https://foundation.rust-lang.org/
|
[rust-foundation]: https://rustfoundation.org/
|
||||||
[media-guide]: https://foundation.rust-lang.org/policies/logo-policy-and-media-guide/
|
[trademark-policy]: https://rustfoundation.org/policy/rust-trademark-policy/
|
||||||
[policies-licenses]: https://www.rust-lang.org/policies/licenses
|
[policies-licenses]: https://www.rust-lang.org/policies/licenses
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2024"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
|
literal-escaper = { path = "../../library/literal-escaper" }
|
||||||
memchr = "2.7.4"
|
memchr = "2.7.4"
|
||||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::{ascii, fmt, str};
|
use std::{ascii, fmt, str};
|
||||||
|
|
||||||
use rustc_lexer::unescape::{
|
use literal_escaper::{
|
||||||
MixedUnit, Mode, byte_from_char, unescape_byte, unescape_char, unescape_mixed, unescape_unicode,
|
MixedUnit, Mode, byte_from_char, unescape_byte, unescape_char, unescape_mixed, unescape_unicode,
|
||||||
};
|
};
|
||||||
use rustc_span::{Span, Symbol, kw, sym};
|
use rustc_span::{Span, Symbol, kw, sym};
|
||||||
|
|
|
@ -2479,20 +2479,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||||
let body = self.body;
|
let body = self.body;
|
||||||
for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
|
for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
|
||||||
let local_decl = &body.local_decls[local];
|
let local_decl = &body.local_decls[local];
|
||||||
let lint_root = match &body.source_scopes[local_decl.source_info.scope].local_data {
|
let ClearCrossCrate::Set(SourceScopeLocalData { lint_root, .. }) =
|
||||||
ClearCrossCrate::Set(data) => data.lint_root,
|
body.source_scopes[local_decl.source_info.scope].local_data
|
||||||
_ => continue,
|
else {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Skip over locals that begin with an underscore or have no name
|
// Skip over locals that begin with an underscore or have no name
|
||||||
match self.local_names[local] {
|
if self.local_names[local].is_none_or(|name| name.as_str().starts_with('_')) {
|
||||||
Some(name) => {
|
|
||||||
if name.as_str().starts_with('_') {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
None => continue,
|
|
||||||
}
|
|
||||||
|
|
||||||
let span = local_decl.source_info.span;
|
let span = local_decl.source_info.span;
|
||||||
if span.desugaring_kind().is_some() {
|
if span.desugaring_kind().is_some() {
|
||||||
|
|
|
@ -153,10 +153,9 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `#[link_section]` is missing, then nothing to verify
|
// If `#[link_section]` is missing, then nothing to verify
|
||||||
let attrs = tcx.codegen_fn_attrs(id);
|
let Some(link_section) = tcx.codegen_fn_attrs(id).link_section else {
|
||||||
if attrs.link_section.is_none() {
|
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
// For the wasm32 target statics with `#[link_section]` other than `.init_array`
|
// For the wasm32 target statics with `#[link_section]` other than `.init_array`
|
||||||
// are placed into custom sections of the final output file, but this isn't like
|
// are placed into custom sections of the final output file, but this isn't like
|
||||||
|
@ -182,11 +181,8 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef
|
||||||
// continue to work, but would no longer be necessary.
|
// continue to work, but would no longer be necessary.
|
||||||
|
|
||||||
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
|
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
|
||||||
&& alloc.inner().provenance().ptrs().len() != 0
|
&& !alloc.inner().provenance().ptrs().is_empty()
|
||||||
&& attrs
|
&& !link_section.as_str().starts_with(".init_array")
|
||||||
.link_section
|
|
||||||
.map(|link_section| !link_section.as_str().starts_with(".init_array"))
|
|
||||||
.unwrap()
|
|
||||||
{
|
{
|
||||||
let msg = "statics with a custom `#[link_section]` must be a \
|
let msg = "statics with a custom `#[link_section]` must be a \
|
||||||
simple list of bytes on the wasm target with no \
|
simple list of bytes on the wasm target with no \
|
||||||
|
|
|
@ -1532,10 +1532,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if self.may_coerce(blk_ty, *elem_ty)
|
if self.may_coerce(blk_ty, *elem_ty)
|
||||||
&& blk.stmts.is_empty()
|
&& blk.stmts.is_empty()
|
||||||
&& blk.rules == hir::BlockCheckMode::DefaultBlock
|
&& blk.rules == hir::BlockCheckMode::DefaultBlock
|
||||||
|
&& let source_map = self.tcx.sess.source_map()
|
||||||
|
&& let Ok(snippet) = source_map.span_to_snippet(blk.span)
|
||||||
|
&& snippet.starts_with('{')
|
||||||
|
&& snippet.ends_with('}')
|
||||||
{
|
{
|
||||||
let source_map = self.tcx.sess.source_map();
|
|
||||||
if let Ok(snippet) = source_map.span_to_snippet(blk.span) {
|
|
||||||
if snippet.starts_with('{') && snippet.ends_with('}') {
|
|
||||||
diag.multipart_suggestion_verbose(
|
diag.multipart_suggestion_verbose(
|
||||||
"to create an array, use square brackets instead of curly braces",
|
"to create an array, use square brackets instead of curly braces",
|
||||||
vec![
|
vec![
|
||||||
|
@ -1557,8 +1558,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self, err))]
|
#[instrument(skip(self, err))]
|
||||||
pub(crate) fn suggest_floating_point_literal(
|
pub(crate) fn suggest_floating_point_literal(
|
||||||
|
|
|
@ -1862,8 +1862,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
///
|
///
|
||||||
/// (1.) Are we borrowing data owned by the parent closure? We can determine if
|
/// (1.) Are we borrowing data owned by the parent closure? We can determine if
|
||||||
/// that is the case by checking if the parent capture is by move, EXCEPT if we
|
/// that is the case by checking if the parent capture is by move, EXCEPT if we
|
||||||
/// apply a deref projection, which means we're reborrowing a reference that we
|
/// apply a deref projection of an immutable reference, reborrows of immutable
|
||||||
/// captured by move.
|
/// references which aren't restricted to the LUB of the lifetimes of the deref
|
||||||
|
/// chain. This is why `&'short mut &'long T` can be reborrowed as `&'long T`.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let x = &1i32; // Let's call this lifetime `'1`.
|
/// let x = &1i32; // Let's call this lifetime `'1`.
|
||||||
|
@ -1902,10 +1903,22 @@ fn should_reborrow_from_env_of_parent_coroutine_closure<'tcx>(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// (1.)
|
// (1.)
|
||||||
(!parent_capture.is_by_ref()
|
(!parent_capture.is_by_ref()
|
||||||
&& !matches!(
|
// This is just inlined `place.deref_tys()` but truncated to just
|
||||||
child_capture.place.projections.get(parent_capture.place.projections.len()),
|
// the child projections. Namely, look for a `&T` deref, since we
|
||||||
Some(Projection { kind: ProjectionKind::Deref, .. })
|
// can always extend `&'short mut &'long T` to `&'long T`.
|
||||||
))
|
&& !child_capture
|
||||||
|
.place
|
||||||
|
.projections
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.skip(parent_capture.place.projections.len())
|
||||||
|
.any(|(idx, proj)| {
|
||||||
|
matches!(proj.kind, ProjectionKind::Deref)
|
||||||
|
&& matches!(
|
||||||
|
child_capture.place.ty_before_projection(idx).kind(),
|
||||||
|
ty::Ref(.., ty::Mutability::Not)
|
||||||
|
)
|
||||||
|
}))
|
||||||
// (2.)
|
// (2.)
|
||||||
|| matches!(child_capture.info.capture_kind, UpvarCapture::ByRef(ty::BorrowKind::Mutable))
|
|| matches!(child_capture.info.capture_kind, UpvarCapture::ByRef(ty::BorrowKind::Mutable))
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ Rust lexer used by rustc. No stability guarantees are provided.
|
||||||
[dependencies]
|
[dependencies]
|
||||||
memchr = "2.7.4"
|
memchr = "2.7.4"
|
||||||
unicode-xid = "0.2.0"
|
unicode-xid = "0.2.0"
|
||||||
|
literal-escaper = { path = "../../library/literal-escaper" }
|
||||||
|
|
||||||
[dependencies.unicode-properties]
|
[dependencies.unicode-properties]
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -26,11 +26,13 @@
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
mod cursor;
|
mod cursor;
|
||||||
pub mod unescape;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
// FIXME: This is needed for rust-analyzer. Remove this dependency once rust-analyzer uses
|
||||||
|
// `literal-escaper`.
|
||||||
|
pub use literal_escaper as unescape;
|
||||||
use unicode_properties::UnicodeEmoji;
|
use unicode_properties::UnicodeEmoji;
|
||||||
pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION;
|
pub use unicode_xid::UNICODE_VERSION as UNICODE_XID_VERSION;
|
||||||
|
|
||||||
|
|
|
@ -843,9 +843,8 @@ fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if attr.path().starts_with(&[sym::diagnostic]) && attr.path().len() == 2 {
|
} else if let &[sym::diagnostic, seg] = &*attr.path() {
|
||||||
should_encode =
|
should_encode = rustc_feature::is_stable_diagnostic_attribute(seg, state.features);
|
||||||
rustc_feature::is_stable_diagnostic_attribute(attr.path()[1], state.features);
|
|
||||||
} else {
|
} else {
|
||||||
should_encode = true;
|
should_encode = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,22 +641,20 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Alias(Projection, AliasTy { def_id, .. }) => {
|
Alias(Projection, AliasTy { def_id, .. })
|
||||||
if self.tcx.def_kind(def_id) != DefKind::AssocTy {
|
if self.tcx.def_kind(def_id) != DefKind::AssocTy =>
|
||||||
|
{
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Param(param) => {
|
|
||||||
// FIXME: It would be nice to make this not use string manipulation,
|
// FIXME: It would be nice to make this not use string manipulation,
|
||||||
// but it's pretty hard to do this, since `ty::ParamTy` is missing
|
// but it's pretty hard to do this, since `ty::ParamTy` is missing
|
||||||
// sufficient info to determine if it is synthetic, and we don't
|
// sufficient info to determine if it is synthetic, and we don't
|
||||||
// always have a convenient way of getting `ty::Generics` at the call
|
// always have a convenient way of getting `ty::Generics` at the call
|
||||||
// sites we invoke `IsSuggestable::is_suggestable`.
|
// sites we invoke `IsSuggestable::is_suggestable`.
|
||||||
if param.name.as_str().starts_with("impl ") {
|
Param(param) if param.name.as_str().starts_with("impl ") => {
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -733,19 +731,15 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Param(param) => {
|
|
||||||
// FIXME: It would be nice to make this not use string manipulation,
|
// FIXME: It would be nice to make this not use string manipulation,
|
||||||
// but it's pretty hard to do this, since `ty::ParamTy` is missing
|
// but it's pretty hard to do this, since `ty::ParamTy` is missing
|
||||||
// sufficient info to determine if it is synthetic, and we don't
|
// sufficient info to determine if it is synthetic, and we don't
|
||||||
// always have a convenient way of getting `ty::Generics` at the call
|
// always have a convenient way of getting `ty::Generics` at the call
|
||||||
// sites we invoke `IsSuggestable::is_suggestable`.
|
// sites we invoke `IsSuggestable::is_suggestable`.
|
||||||
if param.name.as_str().starts_with("impl ") {
|
Param(param) if param.name.as_str().starts_with("impl ") => {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
t
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => t,
|
_ => t,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2024"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
|
literal-escaper = { path = "../../library/literal-escaper" }
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
|
use literal_escaper::{self, EscapeError, Mode};
|
||||||
use rustc_ast::ast::{self, AttrStyle};
|
use rustc_ast::ast::{self, AttrStyle};
|
||||||
use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind};
|
use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::util::unicode::contains_text_flow_control_chars;
|
use rustc_ast::util::unicode::contains_text_flow_control_chars;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, StashKey};
|
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, StashKey};
|
||||||
use rustc_lexer::unescape::{self, EscapeError, Mode};
|
|
||||||
use rustc_lexer::{Base, Cursor, DocStyle, LiteralKind, RawStrError};
|
use rustc_lexer::{Base, Cursor, DocStyle, LiteralKind, RawStrError};
|
||||||
use rustc_session::lint::BuiltinLintDiag;
|
use rustc_session::lint::BuiltinLintDiag;
|
||||||
use rustc_session::lint::builtin::{
|
use rustc_session::lint::builtin::{
|
||||||
|
@ -970,7 +970,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
postfix_len: u32,
|
postfix_len: u32,
|
||||||
) -> (token::LitKind, Symbol) {
|
) -> (token::LitKind, Symbol) {
|
||||||
self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
|
self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
|
||||||
unescape::unescape_unicode(src, mode, &mut |span, result| {
|
literal_escaper::unescape_unicode(src, mode, &mut |span, result| {
|
||||||
callback(span, result.map(drop))
|
callback(span, result.map(drop))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -986,7 +986,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
|
||||||
postfix_len: u32,
|
postfix_len: u32,
|
||||||
) -> (token::LitKind, Symbol) {
|
) -> (token::LitKind, Symbol) {
|
||||||
self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
|
self.cook_common(kind, mode, start, end, prefix_len, postfix_len, |src, mode, callback| {
|
||||||
unescape::unescape_mixed(src, mode, &mut |span, result| {
|
literal_escaper::unescape_mixed(src, mode, &mut |span, result| {
|
||||||
callback(span, result.map(drop))
|
callback(span, result.map(drop))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
|
use literal_escaper::{EscapeError, Mode};
|
||||||
use rustc_errors::{Applicability, DiagCtxtHandle, ErrorGuaranteed};
|
use rustc_errors::{Applicability, DiagCtxtHandle, ErrorGuaranteed};
|
||||||
use rustc_lexer::unescape::{EscapeError, Mode};
|
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use core::ops::{Bound, ControlFlow};
|
||||||
use ast::mut_visit::{self, MutVisitor};
|
use ast::mut_visit::{self, MutVisitor};
|
||||||
use ast::token::{IdentIsRaw, MetaVarKind};
|
use ast::token::{IdentIsRaw, MetaVarKind};
|
||||||
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
|
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered};
|
||||||
|
use literal_escaper::unescape_char;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::TokenTree;
|
use rustc_ast::tokenstream::TokenTree;
|
||||||
|
@ -21,7 +22,6 @@ use rustc_ast::{
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic};
|
use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic};
|
||||||
use rustc_lexer::unescape::unescape_char;
|
|
||||||
use rustc_macros::Subdiagnostic;
|
use rustc_macros::Subdiagnostic;
|
||||||
use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error};
|
use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error};
|
||||||
use rustc_session::lint::BuiltinLintDiag;
|
use rustc_session::lint::BuiltinLintDiag;
|
||||||
|
|
|
@ -5,6 +5,7 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
|
literal-escaper = { path = "../../library/literal-escaper" }
|
||||||
rustc_index = { path = "../rustc_index", default-features = false }
|
rustc_index = { path = "../rustc_index", default-features = false }
|
||||||
rustc_lexer = { path = "../rustc_lexer" }
|
rustc_lexer = { path = "../rustc_lexer" }
|
||||||
# tidy-alphabetical-end
|
# tidy-alphabetical-end
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
pub use Alignment::*;
|
pub use Alignment::*;
|
||||||
pub use Count::*;
|
pub use Count::*;
|
||||||
pub use Position::*;
|
pub use Position::*;
|
||||||
use rustc_lexer::unescape;
|
|
||||||
|
|
||||||
// Note: copied from rustc_span
|
// Note: copied from rustc_span
|
||||||
/// Range inside of a `Span` used for diagnostics when we only have access to relative positions.
|
/// Range inside of a `Span` used for diagnostics when we only have access to relative positions.
|
||||||
|
@ -1094,12 +1093,14 @@ fn find_width_map_from_snippet(
|
||||||
fn unescape_string(string: &str) -> Option<String> {
|
fn unescape_string(string: &str) -> Option<String> {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
let mut ok = true;
|
let mut ok = true;
|
||||||
unescape::unescape_unicode(string, unescape::Mode::Str, &mut |_, unescaped_char| {
|
literal_escaper::unescape_unicode(
|
||||||
match unescaped_char {
|
string,
|
||||||
|
literal_escaper::Mode::Str,
|
||||||
|
&mut |_, unescaped_char| match unescaped_char {
|
||||||
Ok(c) => buf.push(c),
|
Ok(c) => buf.push(c),
|
||||||
Err(_) => ok = false,
|
Err(_) => ok = false,
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
|
|
||||||
ok.then_some(buf)
|
ok.then_some(buf)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1132,7 +1132,7 @@ impl<'tcx> DeadVisitor<'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dead_codes.sort_by_key(|v| v.level);
|
dead_codes.sort_by_key(|v| v.level);
|
||||||
for group in dead_codes[..].chunk_by(|a, b| a.level == b.level) {
|
for group in dead_codes.chunk_by(|a, b| a.level == b.level) {
|
||||||
self.lint_at_single_level(&group, participle, Some(def_id), report_on);
|
self.lint_at_single_level(&group, participle, Some(def_id), report_on);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub(crate) fn target() -> Target {
|
||||||
description: Some("64-bit x86 Cygwin".into()),
|
description: Some("64-bit x86 Cygwin".into()),
|
||||||
tier: Some(3),
|
tier: Some(3),
|
||||||
host_tools: Some(false),
|
host_tools: Some(false),
|
||||||
std: None,
|
std: Some(true),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,6 +165,13 @@ dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "literal-escaper"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"rustc-std-workspace-std",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
|
@ -236,6 +243,7 @@ name = "proc_macro"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core",
|
"core",
|
||||||
|
"literal-escaper",
|
||||||
"std",
|
"std",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ members = [
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude = [
|
exclude = [
|
||||||
|
"literal-escaper",
|
||||||
# stdarch has its own Cargo workspace
|
# stdarch has its own Cargo workspace
|
||||||
"stdarch",
|
"stdarch",
|
||||||
"windows_targets"
|
"windows_targets"
|
||||||
|
|
|
@ -84,9 +84,29 @@ macro_rules! acquire {
|
||||||
///
|
///
|
||||||
/// Shared references in Rust disallow mutation by default, and `Arc` is no
|
/// Shared references in Rust disallow mutation by default, and `Arc` is no
|
||||||
/// exception: you cannot generally obtain a mutable reference to something
|
/// exception: you cannot generally obtain a mutable reference to something
|
||||||
/// inside an `Arc`. If you need to mutate through an `Arc`, use
|
/// inside an `Arc`. If you do need to mutate through an `Arc`, you have several options:
|
||||||
/// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic]
|
///
|
||||||
/// types.
|
/// 1. Use interior mutability with synchronization primitives like [`Mutex`][mutex],
|
||||||
|
/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types.
|
||||||
|
///
|
||||||
|
/// 2. Use clone-on-write semantics with [`Arc::make_mut`] which provides efficient mutation
|
||||||
|
/// without requiring interior mutability. This approach clones the data only when
|
||||||
|
/// needed (when there are multiple references) and can be more efficient when mutations
|
||||||
|
/// are infrequent.
|
||||||
|
///
|
||||||
|
/// 3. Use [`Arc::get_mut`] when you know your `Arc` is not shared (has a reference count of 1),
|
||||||
|
/// which provides direct mutable access to the inner value without any cloning.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::sync::Arc;
|
||||||
|
///
|
||||||
|
/// let mut data = Arc::new(vec![1, 2, 3]);
|
||||||
|
///
|
||||||
|
/// // This will clone the vector only if there are other references to it
|
||||||
|
/// Arc::make_mut(&mut data).push(4);
|
||||||
|
///
|
||||||
|
/// assert_eq!(*data, vec![1, 2, 3, 4]);
|
||||||
|
/// ```
|
||||||
///
|
///
|
||||||
/// **Note**: This type is only available on platforms that support atomic
|
/// **Note**: This type is only available on platforms that support atomic
|
||||||
/// loads and stores of pointers, which includes all platforms that support
|
/// loads and stores of pointers, which includes all platforms that support
|
||||||
|
|
10
library/literal-escaper/Cargo.toml
Normal file
10
library/literal-escaper/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "literal-escaper"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
std = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-std' }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
rustc-dep-of-std = ["dep:std"]
|
4
library/literal-escaper/README.md
Normal file
4
library/literal-escaper/README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# literal-escaper
|
||||||
|
|
||||||
|
This crate provides code to unescape string literals. It is used by `rustc_lexer`
|
||||||
|
and `proc_macro`.
|
|
@ -4,6 +4,7 @@ version = "0.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
literal-escaper = { path = "../literal-escaper", features = ["rustc-dep-of-std"] }
|
||||||
std = { path = "../std" }
|
std = { path = "../std" }
|
||||||
# Workaround: when documenting this crate rustdoc will try to load crate named
|
# Workaround: when documenting this crate rustdoc will try to load crate named
|
||||||
# `core` when resolving doc links. Without this line a different `core` will be
|
# `core` when resolving doc links. Without this line a different `core` will be
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#![feature(restricted_std)]
|
#![feature(restricted_std)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
|
#![feature(stmt_expr_attributes)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![deny(ffi_unwind_calls)]
|
#![deny(ffi_unwind_calls)]
|
||||||
|
@ -51,11 +52,24 @@ use std::{error, fmt};
|
||||||
|
|
||||||
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
||||||
pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
||||||
|
#[unstable(feature = "proc_macro_value", issue = "136652")]
|
||||||
|
pub use literal_escaper::EscapeError;
|
||||||
|
use literal_escaper::{MixedUnit, Mode, byte_from_char, unescape_mixed, unescape_unicode};
|
||||||
#[unstable(feature = "proc_macro_totokens", issue = "130977")]
|
#[unstable(feature = "proc_macro_totokens", issue = "130977")]
|
||||||
pub use to_tokens::ToTokens;
|
pub use to_tokens::ToTokens;
|
||||||
|
|
||||||
use crate::escape::{EscapeOptions, escape_bytes};
|
use crate::escape::{EscapeOptions, escape_bytes};
|
||||||
|
|
||||||
|
/// Errors returned when trying to retrieve a literal unescaped value.
|
||||||
|
#[unstable(feature = "proc_macro_value", issue = "136652")]
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum ConversionErrorKind {
|
||||||
|
/// The literal failed to be escaped, take a look at [`EscapeError`] for more information.
|
||||||
|
FailedToUnescape(EscapeError),
|
||||||
|
/// Trying to convert a literal with the wrong type.
|
||||||
|
InvalidLiteralKind,
|
||||||
|
}
|
||||||
|
|
||||||
/// Determines whether proc_macro has been made accessible to the currently
|
/// Determines whether proc_macro has been made accessible to the currently
|
||||||
/// running program.
|
/// running program.
|
||||||
///
|
///
|
||||||
|
@ -1451,6 +1465,107 @@ impl Literal {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the unescaped string value if the current literal is a string or a string literal.
|
||||||
|
#[unstable(feature = "proc_macro_value", issue = "136652")]
|
||||||
|
pub fn str_value(&self) -> Result<String, ConversionErrorKind> {
|
||||||
|
self.0.symbol.with(|symbol| match self.0.kind {
|
||||||
|
bridge::LitKind::Str => {
|
||||||
|
if symbol.contains('\\') {
|
||||||
|
let mut buf = String::with_capacity(symbol.len());
|
||||||
|
let mut error = None;
|
||||||
|
// Force-inlining here is aggressive but the closure is
|
||||||
|
// called on every char in the string, so it can be hot in
|
||||||
|
// programs with many long strings containing escapes.
|
||||||
|
unescape_unicode(
|
||||||
|
symbol,
|
||||||
|
Mode::Str,
|
||||||
|
&mut #[inline(always)]
|
||||||
|
|_, c| match c {
|
||||||
|
Ok(c) => buf.push(c),
|
||||||
|
Err(err) => {
|
||||||
|
if err.is_fatal() {
|
||||||
|
error = Some(ConversionErrorKind::FailedToUnescape(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if let Some(error) = error { Err(error) } else { Ok(buf) }
|
||||||
|
} else {
|
||||||
|
Ok(symbol.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridge::LitKind::StrRaw(_) => Ok(symbol.to_string()),
|
||||||
|
_ => Err(ConversionErrorKind::InvalidLiteralKind),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the unescaped string value if the current literal is a c-string or a c-string
|
||||||
|
/// literal.
|
||||||
|
#[unstable(feature = "proc_macro_value", issue = "136652")]
|
||||||
|
pub fn cstr_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
|
||||||
|
self.0.symbol.with(|symbol| match self.0.kind {
|
||||||
|
bridge::LitKind::CStr => {
|
||||||
|
let mut error = None;
|
||||||
|
let mut buf = Vec::with_capacity(symbol.len());
|
||||||
|
|
||||||
|
unescape_mixed(symbol, Mode::CStr, &mut |_span, c| match c {
|
||||||
|
Ok(MixedUnit::Char(c)) => {
|
||||||
|
buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
|
||||||
|
}
|
||||||
|
Ok(MixedUnit::HighByte(b)) => buf.push(b),
|
||||||
|
Err(err) => {
|
||||||
|
if err.is_fatal() {
|
||||||
|
error = Some(ConversionErrorKind::FailedToUnescape(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let Some(error) = error {
|
||||||
|
Err(error)
|
||||||
|
} else {
|
||||||
|
buf.push(0);
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridge::LitKind::CStrRaw(_) => {
|
||||||
|
// Raw strings have no escapes so we can convert the symbol
|
||||||
|
// directly to a `Lrc<u8>` after appending the terminating NUL
|
||||||
|
// char.
|
||||||
|
let mut buf = symbol.to_owned().into_bytes();
|
||||||
|
buf.push(0);
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
_ => Err(ConversionErrorKind::InvalidLiteralKind),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the unescaped string value if the current literal is a byte string or a byte string
|
||||||
|
/// literal.
|
||||||
|
#[unstable(feature = "proc_macro_value", issue = "136652")]
|
||||||
|
pub fn byte_str_value(&self) -> Result<Vec<u8>, ConversionErrorKind> {
|
||||||
|
self.0.symbol.with(|symbol| match self.0.kind {
|
||||||
|
bridge::LitKind::ByteStr => {
|
||||||
|
let mut buf = Vec::with_capacity(symbol.len());
|
||||||
|
let mut error = None;
|
||||||
|
|
||||||
|
unescape_unicode(symbol, Mode::ByteStr, &mut |_, c| match c {
|
||||||
|
Ok(c) => buf.push(byte_from_char(c)),
|
||||||
|
Err(err) => {
|
||||||
|
if err.is_fatal() {
|
||||||
|
error = Some(ConversionErrorKind::FailedToUnescape(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let Some(error) = error { Err(error) } else { Ok(buf) }
|
||||||
|
}
|
||||||
|
bridge::LitKind::ByteStrRaw(_) => {
|
||||||
|
// Raw strings have no escapes so we can convert the symbol
|
||||||
|
// directly to a `Lrc<u8>`.
|
||||||
|
Ok(symbol.to_owned().into_bytes())
|
||||||
|
}
|
||||||
|
_ => Err(ConversionErrorKind::InvalidLiteralKind),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a single literal from its stringified representation.
|
/// Parse a single literal from its stringified representation.
|
||||||
|
|
|
@ -62,6 +62,7 @@ fn main() {
|
||||||
|| target_os == "zkvm"
|
|| target_os == "zkvm"
|
||||||
|| target_os == "rtems"
|
|| target_os == "rtems"
|
||||||
|| target_os == "nuttx"
|
|| target_os == "nuttx"
|
||||||
|
|| target_os == "cygwin"
|
||||||
|
|
||||||
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|
||||||
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
|
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
|
||||||
|
|
|
@ -310,7 +310,7 @@ pub use self::error::RawOsError;
|
||||||
pub use self::error::SimpleMessage;
|
pub use self::error::SimpleMessage;
|
||||||
#[unstable(feature = "io_const_error", issue = "133448")]
|
#[unstable(feature = "io_const_error", issue = "133448")]
|
||||||
pub use self::error::const_error;
|
pub use self::error::const_error;
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub use self::pipe::{PipeReader, PipeWriter, pipe};
|
pub use self::pipe::{PipeReader, PipeWriter, pipe};
|
||||||
#[stable(feature = "is_terminal", since = "1.70.0")]
|
#[stable(feature = "is_terminal", since = "1.70.0")]
|
||||||
pub use self::stdio::IsTerminal;
|
pub use self::stdio::IsTerminal;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
|
use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
|
||||||
|
use crate::sys_common::{FromInner, IntoInner};
|
||||||
|
|
||||||
/// Create an anonymous pipe.
|
/// Create an anonymous pipe.
|
||||||
///
|
///
|
||||||
|
@ -40,7 +41,6 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(anonymous_pipe)]
|
|
||||||
/// # #[cfg(miri)] fn main() {}
|
/// # #[cfg(miri)] fn main() {}
|
||||||
/// # #[cfg(not(miri))]
|
/// # #[cfg(not(miri))]
|
||||||
/// # fn main() -> std::io::Result<()> {
|
/// # fn main() -> std::io::Result<()> {
|
||||||
|
@ -67,29 +67,52 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
|
||||||
/// ```
|
/// ```
|
||||||
/// [changes]: io#platform-specific-behavior
|
/// [changes]: io#platform-specific-behavior
|
||||||
/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html
|
/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
|
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
|
||||||
pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer)))
|
pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read end of an anonymous pipe.
|
/// Read end of an anonymous pipe.
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PipeReader(pub(crate) AnonPipe);
|
pub struct PipeReader(pub(crate) AnonPipe);
|
||||||
|
|
||||||
/// Write end of an anonymous pipe.
|
/// Write end of an anonymous pipe.
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PipeWriter(pub(crate) AnonPipe);
|
pub struct PipeWriter(pub(crate) AnonPipe);
|
||||||
|
|
||||||
|
impl FromInner<AnonPipe> for PipeReader {
|
||||||
|
fn from_inner(inner: AnonPipe) -> Self {
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoInner<AnonPipe> for PipeReader {
|
||||||
|
fn into_inner(self) -> AnonPipe {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromInner<AnonPipe> for PipeWriter {
|
||||||
|
fn from_inner(inner: AnonPipe) -> Self {
|
||||||
|
Self(inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoInner<AnonPipe> for PipeWriter {
|
||||||
|
fn into_inner(self) -> AnonPipe {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PipeReader {
|
impl PipeReader {
|
||||||
/// Create a new [`PipeReader`] instance that shares the same underlying file description.
|
/// Create a new [`PipeReader`] instance that shares the same underlying file description.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(anonymous_pipe)]
|
|
||||||
/// # #[cfg(miri)] fn main() {}
|
/// # #[cfg(miri)] fn main() {}
|
||||||
/// # #[cfg(not(miri))]
|
/// # #[cfg(not(miri))]
|
||||||
/// # fn main() -> std::io::Result<()> {
|
/// # fn main() -> std::io::Result<()> {
|
||||||
|
@ -137,7 +160,7 @@ impl PipeReader {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub fn try_clone(&self) -> io::Result<Self> {
|
pub fn try_clone(&self) -> io::Result<Self> {
|
||||||
self.0.try_clone().map(Self)
|
self.0.try_clone().map(Self)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +172,6 @@ impl PipeWriter {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(anonymous_pipe)]
|
|
||||||
/// # #[cfg(miri)] fn main() {}
|
/// # #[cfg(miri)] fn main() {}
|
||||||
/// # #[cfg(not(miri))]
|
/// # #[cfg(not(miri))]
|
||||||
/// # fn main() -> std::io::Result<()> {
|
/// # fn main() -> std::io::Result<()> {
|
||||||
|
@ -177,13 +199,13 @@ impl PipeWriter {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
pub fn try_clone(&self) -> io::Result<Self> {
|
pub fn try_clone(&self) -> io::Result<Self> {
|
||||||
self.0.try_clone().map(Self)
|
self.0.try_clone().map(Self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
impl io::Read for &PipeReader {
|
impl io::Read for &PipeReader {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
self.0.read(buf)
|
||||||
|
@ -203,7 +225,7 @@ impl io::Read for &PipeReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
impl io::Read for PipeReader {
|
impl io::Read for PipeReader {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
self.0.read(buf)
|
||||||
|
@ -223,7 +245,7 @@ impl io::Read for PipeReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
impl io::Write for &PipeWriter {
|
impl io::Write for &PipeWriter {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
self.0.write(buf)
|
||||||
|
@ -241,7 +263,7 @@ impl io::Write for &PipeWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
impl io::Write for PipeWriter {
|
impl io::Write for PipeWriter {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
self.0.write(buf)
|
||||||
|
|
102
library/std/src/os/cygwin/fs.rs
Normal file
102
library/std/src/os/cygwin/fs.rs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#![stable(feature = "metadata_ext", since = "1.1.0")]
|
||||||
|
use crate::fs::Metadata;
|
||||||
|
use crate::sys_common::AsInner;
|
||||||
|
/// OS-specific extensions to [`fs::Metadata`].
|
||||||
|
///
|
||||||
|
/// [`fs::Metadata`]: crate::fs::Metadata
|
||||||
|
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||||
|
pub trait MetadataExt {
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_dev(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_ino(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_mode(&self) -> u32;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_nlink(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_uid(&self) -> u32;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_gid(&self) -> u32;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_rdev(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_size(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_atime(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_atime_nsec(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_mtime(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_mtime_nsec(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_ctime(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_ctime_nsec(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_blksize(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_blocks(&self) -> u64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_birthtime(&self) -> i64;
|
||||||
|
#[stable(feature = "metadata_ext2", since = "1.8.0")]
|
||||||
|
fn st_birthtime_nsec(&self) -> i64;
|
||||||
|
}
|
||||||
|
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||||
|
impl MetadataExt for Metadata {
|
||||||
|
fn st_dev(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_dev as u64
|
||||||
|
}
|
||||||
|
fn st_ino(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_ino as u64
|
||||||
|
}
|
||||||
|
fn st_mode(&self) -> u32 {
|
||||||
|
self.as_inner().as_inner().st_mode as u32
|
||||||
|
}
|
||||||
|
fn st_nlink(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_nlink as u64
|
||||||
|
}
|
||||||
|
fn st_uid(&self) -> u32 {
|
||||||
|
self.as_inner().as_inner().st_uid as u32
|
||||||
|
}
|
||||||
|
fn st_gid(&self) -> u32 {
|
||||||
|
self.as_inner().as_inner().st_gid as u32
|
||||||
|
}
|
||||||
|
fn st_rdev(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_rdev as u64
|
||||||
|
}
|
||||||
|
fn st_size(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_size as u64
|
||||||
|
}
|
||||||
|
fn st_atime(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_atime as i64
|
||||||
|
}
|
||||||
|
fn st_atime_nsec(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_atime_nsec as i64
|
||||||
|
}
|
||||||
|
fn st_mtime(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_mtime as i64
|
||||||
|
}
|
||||||
|
fn st_mtime_nsec(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_mtime_nsec as i64
|
||||||
|
}
|
||||||
|
fn st_ctime(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_ctime as i64
|
||||||
|
}
|
||||||
|
fn st_ctime_nsec(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_ctime_nsec as i64
|
||||||
|
}
|
||||||
|
fn st_blksize(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_blksize as u64
|
||||||
|
}
|
||||||
|
fn st_blocks(&self) -> u64 {
|
||||||
|
self.as_inner().as_inner().st_blocks as u64
|
||||||
|
}
|
||||||
|
fn st_birthtime(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_birthtime as i64
|
||||||
|
}
|
||||||
|
fn st_birthtime_nsec(&self) -> i64 {
|
||||||
|
self.as_inner().as_inner().st_birthtime_nsec as i64
|
||||||
|
}
|
||||||
|
}
|
4
library/std/src/os/cygwin/mod.rs
Normal file
4
library/std/src/os/cygwin/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
//! Cygwin-specific definitions
|
||||||
|
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
|
pub mod fs;
|
||||||
|
pub(crate) mod raw;
|
4
library/std/src/os/cygwin/raw.rs
Normal file
4
library/std/src/os/cygwin/raw.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
//! Cygwin-specific raw type definitions.
|
||||||
|
|
||||||
|
#[stable(feature = "raw_ext", since = "1.1.0")]
|
||||||
|
pub use libc::{blkcnt_t, blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t, pthread_t, time_t};
|
|
@ -15,8 +15,9 @@ use crate::mem::ManuallyDrop;
|
||||||
target_os = "trusty"
|
target_os = "trusty"
|
||||||
)))]
|
)))]
|
||||||
use crate::sys::cvt;
|
use crate::sys::cvt;
|
||||||
|
use crate::sys_common::FromInner;
|
||||||
#[cfg(not(target_os = "trusty"))]
|
#[cfg(not(target_os = "trusty"))]
|
||||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
use crate::sys_common::{AsInner, IntoInner};
|
||||||
use crate::{fmt, io};
|
use crate::{fmt, io};
|
||||||
|
|
||||||
type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
|
type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
|
||||||
|
@ -504,3 +505,45 @@ impl<'a> AsFd for io::StderrLock<'a> {
|
||||||
unsafe { BorrowedFd::borrow_raw(2) }
|
unsafe { BorrowedFd::borrow_raw(2) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsFd for io::PipeReader {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
self.0.as_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeReader> for OwnedFd {
|
||||||
|
fn from(pipe: io::PipeReader) -> Self {
|
||||||
|
pipe.0.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsFd for io::PipeWriter {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
self.0.as_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeWriter> for OwnedFd {
|
||||||
|
fn from(pipe: io::PipeWriter) -> Self {
|
||||||
|
pipe.0.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<OwnedFd> for io::PipeReader {
|
||||||
|
fn from(owned_fd: OwnedFd) -> Self {
|
||||||
|
Self(FromInner::from_inner(owned_fd))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<OwnedFd> for io::PipeWriter {
|
||||||
|
fn from(owned_fd: OwnedFd) -> Self {
|
||||||
|
Self(FromInner::from_inner(owned_fd))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::os::unix::io::AsFd;
|
||||||
use crate::os::unix::io::OwnedFd;
|
use crate::os::unix::io::OwnedFd;
|
||||||
#[cfg(target_os = "wasi")]
|
#[cfg(target_os = "wasi")]
|
||||||
use crate::os::wasi::io::OwnedFd;
|
use crate::os::wasi::io::OwnedFd;
|
||||||
|
use crate::sys_common::FromInner;
|
||||||
#[cfg(not(target_os = "trusty"))]
|
#[cfg(not(target_os = "trusty"))]
|
||||||
use crate::sys_common::{AsInner, IntoInner};
|
use crate::sys_common::{AsInner, IntoInner};
|
||||||
|
|
||||||
|
@ -284,3 +285,45 @@ impl<T: AsRawFd> AsRawFd for Box<T> {
|
||||||
(**self).as_raw_fd()
|
(**self).as_raw_fd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsRawFd for io::PipeReader {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.0.as_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl FromRawFd for io::PipeReader {
|
||||||
|
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
||||||
|
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl IntoRawFd for io::PipeReader {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self.0.into_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsRawFd for io::PipeWriter {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.0.as_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl FromRawFd for io::PipeWriter {
|
||||||
|
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
||||||
|
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl IntoRawFd for io::PipeWriter {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self.0.into_raw_fd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -125,6 +125,8 @@ pub mod windows;
|
||||||
pub mod aix;
|
pub mod aix;
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub mod android;
|
pub mod android;
|
||||||
|
#[cfg(target_os = "cygwin")]
|
||||||
|
pub mod cygwin;
|
||||||
#[cfg(target_os = "dragonfly")]
|
#[cfg(target_os = "dragonfly")]
|
||||||
pub mod dragonfly;
|
pub mod dragonfly;
|
||||||
#[cfg(target_os = "emscripten")]
|
#[cfg(target_os = "emscripten")]
|
||||||
|
|
|
@ -41,6 +41,8 @@ mod platform {
|
||||||
pub use crate::os::aix::*;
|
pub use crate::os::aix::*;
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub use crate::os::android::*;
|
pub use crate::os::android::*;
|
||||||
|
#[cfg(target_os = "cygwin")]
|
||||||
|
pub use crate::os::cygwin::*;
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
pub use crate::os::darwin::*;
|
pub use crate::os::darwin::*;
|
||||||
#[cfg(target_os = "dragonfly")]
|
#[cfg(target_os = "dragonfly")]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
target_os = "illumos",
|
target_os = "illumos",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
|
target_os = "cygwin"
|
||||||
))]
|
))]
|
||||||
use libc::MSG_NOSIGNAL;
|
use libc::MSG_NOSIGNAL;
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ use crate::{fmt, io};
|
||||||
target_os = "illumos",
|
target_os = "illumos",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
|
target_os = "cygwin"
|
||||||
)))]
|
)))]
|
||||||
const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
|
const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ mod tests;
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin"
|
||||||
))]
|
))]
|
||||||
mod ucred;
|
mod ucred;
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ pub use self::stream::*;
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
))]
|
))]
|
||||||
#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
|
#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
|
||||||
pub use self::ucred::*;
|
pub use self::ucred::*;
|
||||||
|
|
|
@ -10,6 +10,7 @@ use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_wi
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin"
|
||||||
))]
|
))]
|
||||||
use super::{UCred, peer_cred};
|
use super::{UCred, peer_cred};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
|
@ -231,6 +232,7 @@ impl UnixStream {
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin"
|
||||||
))]
|
))]
|
||||||
pub fn peer_cred(&self) -> io::Result<UCred> {
|
pub fn peer_cred(&self) -> io::Result<UCred> {
|
||||||
peer_cred(self)
|
peer_cred(self)
|
||||||
|
|
|
@ -33,10 +33,10 @@ pub(super) use self::impl_apple::peer_cred;
|
||||||
target_os = "nto"
|
target_os = "nto"
|
||||||
))]
|
))]
|
||||||
pub(super) use self::impl_bsd::peer_cred;
|
pub(super) use self::impl_bsd::peer_cred;
|
||||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
|
||||||
pub(super) use self::impl_linux::peer_cred;
|
pub(super) use self::impl_linux::peer_cred;
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin"))]
|
||||||
mod impl_linux {
|
mod impl_linux {
|
||||||
use libc::{SO_PEERCRED, SOL_SOCKET, c_void, getsockopt, socklen_t, ucred};
|
use libc::{SO_PEERCRED, SOL_SOCKET, c_void, getsockopt, socklen_t, ucred};
|
||||||
|
|
||||||
|
|
|
@ -660,3 +660,45 @@ impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
|
||||||
join_handle.into_inner().into_handle().into_inner()
|
join_handle.into_inner().into_handle().into_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsHandle for io::PipeReader {
|
||||||
|
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||||
|
self.0.as_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeReader> for OwnedHandle {
|
||||||
|
fn from(pipe: io::PipeReader) -> Self {
|
||||||
|
pipe.into_inner().into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsHandle for io::PipeWriter {
|
||||||
|
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||||
|
self.0.as_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeWriter> for OwnedHandle {
|
||||||
|
fn from(pipe: io::PipeWriter) -> Self {
|
||||||
|
pipe.into_inner().into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<OwnedHandle> for io::PipeReader {
|
||||||
|
fn from(owned_handle: OwnedHandle) -> Self {
|
||||||
|
Self::from_inner(FromInner::from_inner(owned_handle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<OwnedHandle> for io::PipeWriter {
|
||||||
|
fn from(owned_handle: OwnedHandle) -> Self {
|
||||||
|
Self::from_inner(FromInner::from_inner(owned_handle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -310,3 +310,45 @@ impl IntoRawSocket for net::UdpSocket {
|
||||||
self.into_inner().into_socket().into_inner().into_raw_socket()
|
self.into_inner().into_socket().into_inner().into_raw_socket()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsRawHandle for io::PipeReader {
|
||||||
|
fn as_raw_handle(&self) -> RawHandle {
|
||||||
|
self.0.as_raw_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl FromRawHandle for io::PipeReader {
|
||||||
|
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
||||||
|
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl IntoRawHandle for io::PipeReader {
|
||||||
|
fn into_raw_handle(self) -> RawHandle {
|
||||||
|
self.0.into_raw_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl AsRawHandle for io::PipeWriter {
|
||||||
|
fn as_raw_handle(&self) -> RawHandle {
|
||||||
|
self.0.as_raw_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl FromRawHandle for io::PipeWriter {
|
||||||
|
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
||||||
|
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl IntoRawHandle for io::PipeWriter {
|
||||||
|
fn into_raw_handle(self) -> RawHandle {
|
||||||
|
self.0.into_raw_handle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1659,6 +1659,20 @@ impl From<io::Stderr> for Stdio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeWriter> for Stdio {
|
||||||
|
fn from(pipe: io::PipeWriter) -> Self {
|
||||||
|
Stdio::from_inner(pipe.into_inner().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl From<io::PipeReader> for Stdio {
|
||||||
|
fn from(pipe: io::PipeReader) -> Self {
|
||||||
|
Stdio::from_inner(pipe.into_inner().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes the result of a process after it has terminated.
|
/// Describes the result of a process after it has terminated.
|
||||||
///
|
///
|
||||||
/// This `struct` is used to represent the exit status or other termination of a child process.
|
/// This `struct` is used to represent the exit status or other termination of a child process.
|
||||||
|
|
|
@ -37,7 +37,7 @@ use crate::sys::random as sys;
|
||||||
/// Solaris | [`arc4random_buf`](https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html)
|
/// Solaris | [`arc4random_buf`](https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html)
|
||||||
/// Vita | `arc4random_buf`
|
/// Vita | `arc4random_buf`
|
||||||
/// Hermit | `read_entropy`
|
/// Hermit | `read_entropy`
|
||||||
/// Horizon | `getrandom` shim
|
/// Horizon, Cygwin | `getrandom`
|
||||||
/// AIX, Hurd, L4Re, QNX | `/dev/urandom`
|
/// AIX, Hurd, L4Re, QNX | `/dev/urandom`
|
||||||
/// Redox | `/scheme/rand`
|
/// Redox | `/scheme/rand`
|
||||||
/// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html)
|
/// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use crate::io::{self, PipeReader, PipeWriter};
|
use crate::io;
|
||||||
use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
|
||||||
use crate::process::Stdio;
|
|
||||||
use crate::sys::fd::FileDesc;
|
use crate::sys::fd::FileDesc;
|
||||||
use crate::sys::pipe::anon_pipe;
|
use crate::sys::pipe::anon_pipe;
|
||||||
use crate::sys_common::{FromInner, IntoInner};
|
use crate::sys_common::IntoInner;
|
||||||
|
|
||||||
pub type AnonPipe = FileDesc;
|
pub type AnonPipe = FileDesc;
|
||||||
|
|
||||||
|
@ -11,91 +9,3 @@ pub type AnonPipe = FileDesc;
|
||||||
pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||||
anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner()))
|
anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsFd for PipeReader {
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
|
||||||
self.0.as_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsRawFd for PipeReader {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.0.as_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeReader> for OwnedFd {
|
|
||||||
fn from(pipe: PipeReader) -> Self {
|
|
||||||
FileDesc::into_inner(pipe.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl FromRawFd for PipeReader {
|
|
||||||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
|
||||||
unsafe { Self(FileDesc::from_raw_fd(raw_fd)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl IntoRawFd for PipeReader {
|
|
||||||
fn into_raw_fd(self) -> RawFd {
|
|
||||||
self.0.into_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeReader> for Stdio {
|
|
||||||
fn from(pipe: PipeReader) -> Self {
|
|
||||||
Self::from(OwnedFd::from(pipe))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsFd for PipeWriter {
|
|
||||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
|
||||||
self.0.as_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsRawFd for PipeWriter {
|
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
|
||||||
self.0.as_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeWriter> for OwnedFd {
|
|
||||||
fn from(pipe: PipeWriter) -> Self {
|
|
||||||
FileDesc::into_inner(pipe.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl FromRawFd for PipeWriter {
|
|
||||||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
|
||||||
unsafe { Self(FileDesc::from_raw_fd(raw_fd)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl IntoRawFd for PipeWriter {
|
|
||||||
fn into_raw_fd(self) -> RawFd {
|
|
||||||
self.0.into_raw_fd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeWriter> for Stdio {
|
|
||||||
fn from(pipe: PipeWriter) -> Self {
|
|
||||||
Self::from(OwnedFd::from(pipe))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<OwnedFd> for PipeReader {
|
|
||||||
fn from(owned_fd: OwnedFd) -> Self {
|
|
||||||
Self(FileDesc::from_inner(owned_fd))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<OwnedFd> for PipeWriter {
|
|
||||||
fn from(owned_fd: OwnedFd) -> Self {
|
|
||||||
Self(FileDesc::from_inner(owned_fd))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,22 +1,7 @@
|
||||||
use crate::io::{self, PipeReader, PipeWriter};
|
use crate::io;
|
||||||
use crate::process::Stdio;
|
|
||||||
pub use crate::sys::pipe::AnonPipe;
|
pub use crate::sys::pipe::AnonPipe;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||||
Err(io::Error::UNSUPPORTED_PLATFORM)
|
Err(io::Error::UNSUPPORTED_PLATFORM)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeReader> for Stdio {
|
|
||||||
fn from(pipe: PipeReader) -> Self {
|
|
||||||
pipe.0.diverge()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeWriter> for Stdio {
|
|
||||||
fn from(pipe: PipeWriter) -> Self {
|
|
||||||
pipe.0.diverge()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
use crate::io::{self, PipeReader, PipeWriter};
|
use crate::os::windows::io::FromRawHandle;
|
||||||
use crate::os::windows::io::{
|
|
||||||
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
|
|
||||||
};
|
|
||||||
use crate::process::Stdio;
|
|
||||||
use crate::ptr;
|
|
||||||
use crate::sys::c;
|
use crate::sys::c;
|
||||||
use crate::sys::handle::Handle;
|
use crate::sys::handle::Handle;
|
||||||
use crate::sys_common::{FromInner, IntoInner};
|
use crate::{io, ptr};
|
||||||
|
|
||||||
pub type AnonPipe = Handle;
|
pub type AnonPipe = Handle;
|
||||||
|
|
||||||
|
@ -22,95 +17,3 @@ pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||||
unsafe { Ok((Handle::from_raw_handle(read_pipe), Handle::from_raw_handle(write_pipe))) }
|
unsafe { Ok((Handle::from_raw_handle(read_pipe), Handle::from_raw_handle(write_pipe))) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsHandle for PipeReader {
|
|
||||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
|
||||||
self.0.as_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsRawHandle for PipeReader {
|
|
||||||
fn as_raw_handle(&self) -> RawHandle {
|
|
||||||
self.0.as_raw_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl FromRawHandle for PipeReader {
|
|
||||||
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
|
||||||
unsafe { Self(Handle::from_raw_handle(raw_handle)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl IntoRawHandle for PipeReader {
|
|
||||||
fn into_raw_handle(self) -> RawHandle {
|
|
||||||
self.0.into_raw_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeReader> for OwnedHandle {
|
|
||||||
fn from(pipe: PipeReader) -> Self {
|
|
||||||
Handle::into_inner(pipe.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeReader> for Stdio {
|
|
||||||
fn from(pipe: PipeReader) -> Self {
|
|
||||||
Self::from(OwnedHandle::from(pipe))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsHandle for PipeWriter {
|
|
||||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
|
||||||
self.0.as_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl AsRawHandle for PipeWriter {
|
|
||||||
fn as_raw_handle(&self) -> RawHandle {
|
|
||||||
self.0.as_raw_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl FromRawHandle for PipeWriter {
|
|
||||||
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
|
||||||
unsafe { Self(Handle::from_raw_handle(raw_handle)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl IntoRawHandle for PipeWriter {
|
|
||||||
fn into_raw_handle(self) -> RawHandle {
|
|
||||||
self.0.into_raw_handle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeWriter> for OwnedHandle {
|
|
||||||
fn from(pipe: PipeWriter) -> Self {
|
|
||||||
Handle::into_inner(pipe.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<PipeWriter> for Stdio {
|
|
||||||
fn from(pipe: PipeWriter) -> Self {
|
|
||||||
Self::from(OwnedHandle::from(pipe))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<OwnedHandle> for PipeReader {
|
|
||||||
fn from(owned_handle: OwnedHandle) -> Self {
|
|
||||||
Self(Handle::from_inner(owned_handle))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
|
||||||
impl From<OwnedHandle> for PipeWriter {
|
|
||||||
fn from(owned_handle: OwnedHandle) -> Self {
|
|
||||||
Self(Handle::from_inner(owned_handle))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -543,7 +543,12 @@ impl FileAttr {
|
||||||
SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
|
SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "freebsd", target_os = "openbsd", target_vendor = "apple"))]
|
#[cfg(any(
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "openbsd",
|
||||||
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
|
))]
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)
|
SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)
|
||||||
}
|
}
|
||||||
|
@ -553,6 +558,7 @@ impl FileAttr {
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "vita",
|
target_os = "vita",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
)))]
|
)))]
|
||||||
pub fn created(&self) -> io::Result<SystemTime> {
|
pub fn created(&self) -> io::Result<SystemTime> {
|
||||||
cfg_has_statx! {
|
cfg_has_statx! {
|
||||||
|
@ -960,6 +966,7 @@ impl DirEntry {
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
|
@ -1220,6 +1227,7 @@ impl File {
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
@ -1234,6 +1242,7 @@ impl File {
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
|
|
|
@ -59,7 +59,8 @@ cfg_if::cfg_if! {
|
||||||
target_os = "dragonfly", target_os = "freebsd",
|
target_os = "dragonfly", target_os = "freebsd",
|
||||||
target_os = "openbsd", target_os = "netbsd",
|
target_os = "openbsd", target_os = "netbsd",
|
||||||
target_os = "solaris", target_os = "illumos",
|
target_os = "solaris", target_os = "illumos",
|
||||||
target_os = "haiku", target_os = "nto"))] {
|
target_os = "haiku", target_os = "nto",
|
||||||
|
target_os = "cygwin"))] {
|
||||||
use libc::MSG_NOSIGNAL;
|
use libc::MSG_NOSIGNAL;
|
||||||
} else {
|
} else {
|
||||||
const MSG_NOSIGNAL: c_int = 0x0;
|
const MSG_NOSIGNAL: c_int = 0x0;
|
||||||
|
|
|
@ -81,6 +81,7 @@ impl Socket {
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
))] {
|
))] {
|
||||||
|
@ -128,6 +129,7 @@ impl Socket {
|
||||||
target_os = "hurd",
|
target_os = "hurd",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
))] {
|
))] {
|
||||||
// Like above, set cloexec atomically
|
// Like above, set cloexec atomically
|
||||||
|
@ -257,6 +259,7 @@ impl Socket {
|
||||||
target_os = "hurd",
|
target_os = "hurd",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
))] {
|
))] {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?;
|
let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?;
|
||||||
|
@ -421,6 +424,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "cygwin"))]
|
||||||
pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
|
pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
|
||||||
let linger = libc::linger {
|
let linger = libc::linger {
|
||||||
l_onoff: linger.is_some() as libc::c_int,
|
l_onoff: linger.is_some() as libc::c_int,
|
||||||
|
@ -430,6 +434,16 @@ impl Socket {
|
||||||
setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger)
|
setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "cygwin")]
|
||||||
|
pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
|
||||||
|
let linger = libc::linger {
|
||||||
|
l_onoff: linger.is_some() as libc::c_ushort,
|
||||||
|
l_linger: linger.unwrap_or_default().as_secs() as libc::c_ushort,
|
||||||
|
};
|
||||||
|
|
||||||
|
setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn linger(&self) -> io::Result<Option<Duration>> {
|
pub fn linger(&self) -> io::Result<Option<Duration>> {
|
||||||
let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?;
|
let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ impl DoubleEndedIterator for Args {
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "solaris",
|
target_os = "solaris",
|
||||||
target_os = "illumos",
|
target_os = "illumos",
|
||||||
target_os = "emscripten",
|
target_os = "emscripten",
|
||||||
|
|
|
@ -108,6 +108,17 @@ pub mod os {
|
||||||
pub const EXE_EXTENSION: &str = "";
|
pub const EXE_EXTENSION: &str = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "cygwin")]
|
||||||
|
pub mod os {
|
||||||
|
pub const FAMILY: &str = "unix";
|
||||||
|
pub const OS: &str = "cygwin";
|
||||||
|
pub const DLL_PREFIX: &str = "";
|
||||||
|
pub const DLL_SUFFIX: &str = ".dll";
|
||||||
|
pub const DLL_EXTENSION: &str = "dll";
|
||||||
|
pub const EXE_SUFFIX: &str = ".exe";
|
||||||
|
pub const EXE_EXTENSION: &str = "exe";
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub mod os {
|
pub mod os {
|
||||||
pub const FAMILY: &str = "unix";
|
pub const FAMILY: &str = "unix";
|
||||||
|
|
|
@ -47,6 +47,7 @@ const READ_LIMIT: usize = if cfg!(target_vendor = "apple") {
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
))]
|
))]
|
||||||
const fn max_iov() -> usize {
|
const fn max_iov() -> usize {
|
||||||
libc::IOV_MAX as usize
|
libc::IOV_MAX as usize
|
||||||
|
@ -74,6 +75,7 @@ const fn max_iov() -> usize {
|
||||||
target_os = "horizon",
|
target_os = "horizon",
|
||||||
target_os = "vita",
|
target_os = "vita",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
)))]
|
)))]
|
||||||
const fn max_iov() -> usize {
|
const fn max_iov() -> usize {
|
||||||
16 // The minimum value required by POSIX.
|
16 // The minimum value required by POSIX.
|
||||||
|
@ -503,6 +505,7 @@ impl FileDesc {
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "redox",
|
target_os = "redox",
|
||||||
target_os = "vxworks",
|
target_os = "vxworks",
|
||||||
|
@ -525,6 +528,7 @@ impl FileDesc {
|
||||||
target_os = "fuchsia",
|
target_os = "fuchsia",
|
||||||
target_os = "l4re",
|
target_os = "l4re",
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "haiku",
|
target_os = "haiku",
|
||||||
target_os = "redox",
|
target_os = "redox",
|
||||||
target_os = "vxworks",
|
target_os = "vxworks",
|
||||||
|
|
|
@ -380,7 +380,7 @@ cfg_if::cfg_if! {
|
||||||
#[link(name = "pthread")]
|
#[link(name = "pthread")]
|
||||||
#[link(name = "rt")]
|
#[link(name = "rt")]
|
||||||
unsafe extern "C" {}
|
unsafe extern "C" {}
|
||||||
} else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] {
|
} else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd", target_os = "cygwin"))] {
|
||||||
#[link(name = "pthread")]
|
#[link(name = "pthread")]
|
||||||
unsafe extern "C" {}
|
unsafe extern "C" {}
|
||||||
} else if #[cfg(target_os = "solaris")] {
|
} else if #[cfg(target_os = "solaris")] {
|
||||||
|
|
|
@ -46,6 +46,7 @@ unsafe extern "C" {
|
||||||
any(
|
any(
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "redox",
|
target_os = "redox",
|
||||||
target_os = "nuttx",
|
target_os = "nuttx",
|
||||||
|
@ -118,7 +119,12 @@ pub fn error_string(errno: i32) -> String {
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
all(
|
all(
|
||||||
any(target_os = "linux", target_os = "hurd", target_env = "newlib"),
|
any(
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "hurd",
|
||||||
|
target_env = "newlib",
|
||||||
|
target_os = "cygwin"
|
||||||
|
),
|
||||||
not(target_env = "ohos")
|
not(target_env = "ohos")
|
||||||
),
|
),
|
||||||
link_name = "__xpg_strerror_r"
|
link_name = "__xpg_strerror_r"
|
||||||
|
@ -395,6 +401,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "hurd",
|
target_os = "hurd",
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "nuttx",
|
target_os = "nuttx",
|
||||||
|
|
|
@ -27,6 +27,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "netbsd",
|
target_os = "netbsd",
|
||||||
target_os = "openbsd",
|
target_os = "openbsd",
|
||||||
|
target_os = "cygwin",
|
||||||
target_os = "redox"
|
target_os = "redox"
|
||||||
))] {
|
))] {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -489,6 +489,12 @@ impl From<AnonPipe> for Stdio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FileDesc> for Stdio {
|
||||||
|
fn from(fd: FileDesc) -> Stdio {
|
||||||
|
Stdio::Fd(fd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<File> for Stdio {
|
impl From<File> for Stdio {
|
||||||
fn from(file: File) -> Stdio {
|
fn from(file: File) -> Stdio {
|
||||||
Stdio::Fd(file.into_inner())
|
Stdio::Fd(file.into_inner())
|
||||||
|
|
|
@ -1157,7 +1157,7 @@ fn signal_string(signal: i32) -> &'static str {
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
libc::SIGSTKFLT => " (SIGSTKFLT)",
|
libc::SIGSTKFLT => " (SIGSTKFLT)",
|
||||||
#[cfg(any(target_os = "linux", target_os = "nto"))]
|
#[cfg(any(target_os = "linux", target_os = "nto", target_os = "cygwin"))]
|
||||||
libc::SIGPWR => " (SIGPWR)",
|
libc::SIGPWR => " (SIGPWR)",
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
|
@ -1166,6 +1166,7 @@ fn signal_string(signal: i32) -> &'static str {
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
target_os = "nto",
|
target_os = "nto",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
))]
|
))]
|
||||||
libc::SIGEMT => " (SIGEMT)",
|
libc::SIGEMT => " (SIGEMT)",
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
|
|
|
@ -137,7 +137,8 @@ impl Thread {
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
target_os = "nuttx"
|
target_os = "nuttx",
|
||||||
|
target_os = "cygwin"
|
||||||
))]
|
))]
|
||||||
pub fn set_name(name: &CStr) {
|
pub fn set_name(name: &CStr) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -365,6 +366,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "aix",
|
target_os = "aix",
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
|
target_os = "cygwin",
|
||||||
))] {
|
))] {
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
|
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
|
||||||
|
use crate::sys_common::{FromInner, IntoInner};
|
||||||
|
|
||||||
pub struct AnonPipe(!);
|
pub struct AnonPipe(!);
|
||||||
|
|
||||||
|
@ -54,3 +55,53 @@ impl AnonPipe {
|
||||||
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
|
pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
|
||||||
match p1.0 {}
|
match p1.0 {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromInner<!> for AnonPipe {
|
||||||
|
fn from_inner(inner: !) -> Self {
|
||||||
|
inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoInner<!> for AnonPipe {
|
||||||
|
fn into_inner(self) -> ! {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
|
||||||
|
mod unix_traits {
|
||||||
|
use super::AnonPipe;
|
||||||
|
use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||||
|
use crate::sys_common::FromInner;
|
||||||
|
|
||||||
|
impl AsRawFd for AnonPipe {
|
||||||
|
#[inline]
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsFd for AnonPipe {
|
||||||
|
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoRawFd for AnonPipe {
|
||||||
|
fn into_raw_fd(self) -> RawFd {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRawFd for AnonPipe {
|
||||||
|
unsafe fn from_raw_fd(_: RawFd) -> Self {
|
||||||
|
panic!("creating pipe on this platform is unsupported!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromInner<OwnedFd> for AnonPipe {
|
||||||
|
fn from_inner(_: OwnedFd) -> Self {
|
||||||
|
panic!("creating pipe on this platform is unsupported!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -621,6 +621,12 @@ impl From<AnonPipe> for Stdio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Handle> for Stdio {
|
||||||
|
fn from(pipe: Handle) -> Stdio {
|
||||||
|
Stdio::Handle(pipe)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<File> for Stdio {
|
impl From<File> for Stdio {
|
||||||
fn from(file: File) -> Stdio {
|
fn from(file: File) -> Stdio {
|
||||||
Stdio::Handle(file.into_inner())
|
Stdio::Handle(file.into_inner())
|
||||||
|
|
|
@ -248,7 +248,10 @@ cfg_if::cfg_if! {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
|
if #[cfg(any(
|
||||||
|
all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"),
|
||||||
|
target_os = "cygwin",
|
||||||
|
))] {
|
||||||
/// personality fn called by [Windows Structured Exception Handling][windows-eh]
|
/// personality fn called by [Windows Structured Exception Handling][windows-eh]
|
||||||
///
|
///
|
||||||
/// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH,
|
/// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH,
|
||||||
|
|
|
@ -35,10 +35,10 @@ cfg_if::cfg_if! {
|
||||||
} else if #[cfg(target_os = "hermit")] {
|
} else if #[cfg(target_os = "hermit")] {
|
||||||
mod hermit;
|
mod hermit;
|
||||||
pub use hermit::fill_bytes;
|
pub use hermit::fill_bytes;
|
||||||
} else if #[cfg(target_os = "horizon")] {
|
} else if #[cfg(any(target_os = "horizon", target_os = "cygwin"))] {
|
||||||
// FIXME: add arc4random_buf to shim-3ds
|
// FIXME(horizon): add arc4random_buf to shim-3ds
|
||||||
mod horizon;
|
mod getrandom;
|
||||||
pub use horizon::fill_bytes;
|
pub use getrandom::fill_bytes;
|
||||||
} else if #[cfg(any(
|
} else if #[cfg(any(
|
||||||
target_os = "aix",
|
target_os = "aix",
|
||||||
target_os = "hurd",
|
target_os = "hurd",
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![feature(anonymous_pipe)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(all(not(miri), any(unix, windows), not(target_os = "emscripten")))]
|
#[cfg(all(not(miri), any(unix, windows), not(target_os = "emscripten")))]
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,10 +27,10 @@ pub type _Unwind_Trace_Fn =
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
pub const unwinder_private_data_size: usize = 5;
|
pub const unwinder_private_data_size: usize = 5;
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
|
#[cfg(all(target_arch = "x86_64", not(any(target_os = "windows", target_os = "cygwin"))))]
|
||||||
pub const unwinder_private_data_size: usize = 2;
|
pub const unwinder_private_data_size: usize = 2;
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
#[cfg(all(target_arch = "x86_64", any(target_os = "windows", target_os = "cygwin")))]
|
||||||
pub const unwinder_private_data_size: usize = 6;
|
pub const unwinder_private_data_size: usize = 6;
|
||||||
|
|
||||||
#[cfg(all(target_arch = "arm", not(target_vendor = "apple")))]
|
#[cfg(all(target_arch = "arm", not(target_vendor = "apple")))]
|
||||||
|
@ -289,7 +289,10 @@ if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch =
|
||||||
} // cfg_if!
|
} // cfg_if!
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
|
if #[cfg(any(
|
||||||
|
all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"),
|
||||||
|
target_os = "cygwin",
|
||||||
|
))] {
|
||||||
// We declare these as opaque types. This is fine since you just need to
|
// We declare these as opaque types. This is fine since you just need to
|
||||||
// pass them to _GCC_specific_handler and forget about them.
|
// pass them to _GCC_specific_handler and forget about them.
|
||||||
pub enum EXCEPTION_RECORD {}
|
pub enum EXCEPTION_RECORD {}
|
||||||
|
|
|
@ -655,7 +655,7 @@ mod dist {
|
||||||
let mut builder = Builder::new(&build);
|
let mut builder = Builder::new(&build);
|
||||||
builder.run_step_descriptions(
|
builder.run_step_descriptions(
|
||||||
&Builder::get_step_descriptions(Kind::Build),
|
&Builder::get_step_descriptions(Kind::Build),
|
||||||
&["compiler/rustc".into(), "library".into()],
|
&["compiler/rustc".into(), "std".into()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(builder.config.stage, 2);
|
assert_eq!(builder.config.stage, 2);
|
||||||
|
|
|
@ -62,6 +62,11 @@ pub fn build(build: &mut Build) {
|
||||||
let relative_path = krate.local_path(build);
|
let relative_path = krate.local_path(build);
|
||||||
build.crates.insert(name.clone(), krate);
|
build.crates.insert(name.clone(), krate);
|
||||||
let existing_path = build.crate_paths.insert(relative_path, name);
|
let existing_path = build.crate_paths.insert(relative_path, name);
|
||||||
|
// `literal-escaper` is both a dependency of `compiler/rustc_lexer` and of
|
||||||
|
// `library/proc-macro`, making it appear multiple times in the workspace.
|
||||||
|
if existing_path.as_deref() == Some("literal-escaper") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
assert!(
|
assert!(
|
||||||
existing_path.is_none(),
|
existing_path.is_none(),
|
||||||
"multiple crates with the same path: {}",
|
"multiple crates with the same path: {}",
|
||||||
|
|
|
@ -716,7 +716,7 @@ impl Build {
|
||||||
features.push("llvm");
|
features.push("llvm");
|
||||||
}
|
}
|
||||||
// keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
|
// keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
|
||||||
if self.config.rust_randomize_layout {
|
if self.config.rust_randomize_layout && check("rustc_randomized_layouts") {
|
||||||
features.push("rustc_randomized_layouts");
|
features.push("rustc_randomized_layouts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,6 +383,6 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
|
||||||
ChangeInfo {
|
ChangeInfo {
|
||||||
change_id: 137147,
|
change_id: 137147,
|
||||||
severity: ChangeSeverity::Info,
|
severity: ChangeSeverity::Info,
|
||||||
summary: "New option `build.exclude` that adds support for excluding test.",
|
summary: "Added new option `build.exclude` which works the same way as `--exclude` flag on `x`.",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -407,7 +407,7 @@ target | std | host | notes
|
||||||
[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI)
|
[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI)
|
||||||
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
|
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
|
||||||
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
|
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
|
||||||
[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin |
|
[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin |
|
||||||
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
|
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
|
||||||
[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
|
[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
|
||||||
[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS |
|
[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS |
|
||||||
|
|
55
src/doc/unstable-book/src/language-features/register-tool.md
Normal file
55
src/doc/unstable-book/src/language-features/register-tool.md
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# `register_tool`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#66079]
|
||||||
|
|
||||||
|
[#66079]: https://github.com/rust-lang/rust/issues/66079
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The `register_tool` language feature informs the compiler that attributes in your code are meant to be used with tools other than the compiler itself. This can be useful if your code has semantic meaning without the external tool, but enables additional features when the tool is present.
|
||||||
|
|
||||||
|
`register_tool` also allows configuring lint levels for external tools.
|
||||||
|
|
||||||
|
Tool attributes are only meant for ignorable attributes. If your code *changes* meaning when the attribute is present, it should not use a tool attribute (because it cannot be compiled with anything other than the external tool, and in a sense is a fork of the language).
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
`#![register_tool(tool)]` is an attribute, and is only valid at the crate root.
|
||||||
|
Attributes using the registered tool are checked for valid syntax, and lint attributes are checked to be in a valid format. However, the compiler cannot validate the semantics of the attribute, nor can it tell whether the configured lint is present in the external tool.
|
||||||
|
|
||||||
|
Semantically, `clippy::*`, `rustdoc::*`, and `rustfmt::*` lints and attributes all behave as if `#![register_tool(clippy, rustdoc, rustfmt)]` were injected into the crate root, except that the `rustdoc` namespace can only be used for lints, not for attributes.
|
||||||
|
When compiling with `-Z unstable-features`, `rustc::*` lints can also be used. Like `rustdoc`, the `rustc` namespace can only be used with lints, not attributes.
|
||||||
|
|
||||||
|
The compiler will emit an error if it encounters a lint/attribute whose namespace isn't a registered tool.
|
||||||
|
|
||||||
|
Tool namespaces cannot be nested; `register_tool(main_tool::subtool)` is an error.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Tool attributes:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#![feature(register_tool)]
|
||||||
|
#![register_tool(c2rust)]
|
||||||
|
|
||||||
|
// Mark which C header file this module was generated from.
|
||||||
|
#[c2rust::header_src = "operations.h"]
|
||||||
|
pub mod operations_h {
|
||||||
|
use std::ffi::c_int;
|
||||||
|
|
||||||
|
// Mark which source line this struct was generated from.
|
||||||
|
#[c2rust::src_loc = "11:0"]
|
||||||
|
pub struct Point {
|
||||||
|
pub x: c_int,
|
||||||
|
pub y: c_int,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tool lints:
|
||||||
|
|
||||||
|
```
|
||||||
|
#![feature(register_tool)]
|
||||||
|
#![register_tool(bevy)]
|
||||||
|
#![deny(bevy::duplicate_bevy_dependencies)]
|
||||||
|
```
|
|
@ -1,7 +1,5 @@
|
||||||
//@ignore-target: windows
|
//@ignore-target: windows
|
||||||
|
|
||||||
#![feature(anonymous_pipe)]
|
|
||||||
|
|
||||||
use std::io::{Read, Write, pipe};
|
use std::io::{Read, Write, pipe};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -318,6 +318,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
||||||
"libloading",
|
"libloading",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"litemap",
|
"litemap",
|
||||||
|
"literal-escaper",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"log",
|
"log",
|
||||||
"matchers",
|
"matchers",
|
||||||
|
@ -363,6 +364,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
||||||
"rustc-rayon",
|
"rustc-rayon",
|
||||||
"rustc-rayon-core",
|
"rustc-rayon-core",
|
||||||
"rustc-stable-hash",
|
"rustc-stable-hash",
|
||||||
|
"rustc-std-workspace-std",
|
||||||
"rustc_apfloat",
|
"rustc_apfloat",
|
||||||
"rustix",
|
"rustix",
|
||||||
"ruzstd", // via object in thorin-dwp
|
"ruzstd", // via object in thorin-dwp
|
||||||
|
|
46
tests/ui/async-await/async-closures/imm-deref-lending.rs
Normal file
46
tests/ui/async-await/async-closures/imm-deref-lending.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
struct FooS {
|
||||||
|
precise: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ref_inside_mut(f: &mut &FooS) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_inside_ref(f: &&mut FooS) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_ref_inside_mut(f: &mut &mut FooS) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ref_inside_box(f: Box<&FooS>) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_inside_ref(f: &Box<FooS>) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_inside_box(f: Box<Box<FooS>>) {
|
||||||
|
let x: impl AsyncFn() = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
49
tests/ui/async-await/async-closures/imm-deref-not-lending.rs
Normal file
49
tests/ui/async-await/async-closures/imm-deref-not-lending.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
#![feature(impl_trait_in_bindings)]
|
||||||
|
|
||||||
|
struct FooS {
|
||||||
|
precise: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ref_inside_mut(f: &mut &FooS) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_inside_ref(f: &&mut FooS) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected to fail, no immutable reference here.
|
||||||
|
fn mut_ref_inside_mut(f: &mut &mut FooS) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
//~^ ERROR async closure does not implement `Fn`
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ref_inside_box(f: Box<&FooS>) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_inside_ref(f: &Box<FooS>) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected to fail, no immutable reference here.
|
||||||
|
fn box_inside_box(f: Box<Box<FooS>>) {
|
||||||
|
let x: impl Fn() -> _ = async move || {
|
||||||
|
//~^ ERROR async closure does not implement `Fn`
|
||||||
|
let y = &f.precise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error: async closure does not implement `Fn` because it captures state from its environment
|
||||||
|
--> $DIR/imm-deref-not-lending.rs:23:29
|
||||||
|
|
|
||||||
|
LL | let x: impl Fn() -> _ = async move || {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: async closure does not implement `Fn` because it captures state from its environment
|
||||||
|
--> $DIR/imm-deref-not-lending.rs:43:29
|
||||||
|
|
|
||||||
|
LL | let x: impl Fn() -> _ = async move || {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
3
tests/ui/feature-gates/literal-escaper.rs
Normal file
3
tests/ui/feature-gates/literal-escaper.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
extern crate literal_escaper; //~ ERROR
|
13
tests/ui/feature-gates/literal-escaper.stderr
Normal file
13
tests/ui/feature-gates/literal-escaper.stderr
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
|
||||||
|
--> $DIR/literal-escaper.rs:3:1
|
||||||
|
|
|
||||||
|
LL | extern crate literal_escaper;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #27812 <https://github.com/rust-lang/rust/issues/27812> for more information
|
||||||
|
= help: add `#![feature(rustc_private)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
|
@ -1,10 +1,11 @@
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
use proc_macro::Literal;
|
use proc_macro::{ConversionErrorKind, Literal};
|
||||||
|
|
||||||
pub fn test() {
|
pub fn test() {
|
||||||
test_display_literal();
|
test_display_literal();
|
||||||
test_parse_literal();
|
test_parse_literal();
|
||||||
|
test_str_value_methods();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_display_literal() {
|
fn test_display_literal() {
|
||||||
|
@ -81,3 +82,53 @@ fn test_parse_literal() {
|
||||||
assert!("- 10".parse::<Literal>().is_err());
|
assert!("- 10".parse::<Literal>().is_err());
|
||||||
assert!("-'x'".parse::<Literal>().is_err());
|
assert!("-'x'".parse::<Literal>().is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_str_value_methods() {
|
||||||
|
// Testing `str_value`
|
||||||
|
let lit = "\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.str_value(), Ok("\n".to_string()));
|
||||||
|
|
||||||
|
let lit = "r#\"\n\"#".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.str_value(), Ok("\n".to_string()));
|
||||||
|
|
||||||
|
let lit = "1".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "b\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "c\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
// Testing `cstr_value`
|
||||||
|
let lit = "\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.cstr_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "r#\"\n\"#".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.cstr_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "1".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.cstr_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "b\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.cstr_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "c\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.cstr_value(), Ok(vec![b'\n', 0]));
|
||||||
|
|
||||||
|
// Testing `byte_str_value`
|
||||||
|
let lit = "\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.byte_str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "r#\"\n\"#".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.byte_str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "1".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.byte_str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
|
||||||
|
let lit = "b\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.byte_str_value(), Ok(vec![b'\n']));
|
||||||
|
|
||||||
|
let lit = "c\"\n\"".parse::<Literal>().unwrap();
|
||||||
|
assert_eq!(lit.byte_str_value(), Err(ConversionErrorKind::InvalidLiteralKind));
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//@ edition: 2021
|
//@ edition: 2021
|
||||||
|
|
||||||
#![feature(proc_macro_span)]
|
#![feature(proc_macro_span)]
|
||||||
|
#![feature(proc_macro_value)]
|
||||||
#![deny(dead_code)] // catch if a test function is never called
|
#![deny(dead_code)] // catch if a test function is never called
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
5
tests/ui/tool-attributes/crate-attr.rs
Normal file
5
tests/ui/tool-attributes/crate-attr.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
//@ check-pass
|
||||||
|
//@ compile-flags: -Z crate-attr=feature(register_tool) -Z crate-attr=register_tool(foo)
|
||||||
|
|
||||||
|
#[allow(foo::bar)]
|
||||||
|
fn main() {}
|
7
tests/ui/tool-attributes/multiple-registered.rs
Normal file
7
tests/ui/tool-attributes/multiple-registered.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(register_tool)]
|
||||||
|
#![register_tool(foo, bar, baz)]
|
||||||
|
|
||||||
|
#[allow(foo::a, bar::b, baz::c)]
|
||||||
|
fn main() {}
|
4
tests/ui/tool-attributes/nested-disallowed.rs
Normal file
4
tests/ui/tool-attributes/nested-disallowed.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#![feature(register_tool)]
|
||||||
|
#![register_tool(foo::bar)] //~ ERROR only accepts identifiers
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/tool-attributes/nested-disallowed.stderr
Normal file
8
tests/ui/tool-attributes/nested-disallowed.stderr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
error: `register_tool` only accepts identifiers
|
||||||
|
--> $DIR/nested-disallowed.rs:2:18
|
||||||
|
|
|
||||||
|
LL | #![register_tool(foo::bar)]
|
||||||
|
| ^^^^^^^^ not an identifier
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue