Auto merge of #97063 - Dylan-DPC:rollup-u5el7hb, r=Dylan-DPC

Rollup of 4 pull requests

Successful merges:

 - #96947 (Add rustc_nonnull_optimization_guaranteed to Owned/Borrowed Fd/Socket)
 - #97021 (Added note in documentation)
 - #97042 (Add new eslint rule about brace style)
 - #97060 (Fix use of SetHandleInformation on UWP)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-05-15 18:52:28 +00:00
commit 29e972dc60
14 changed files with 123 additions and 35 deletions

View File

@ -32,6 +32,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
// 32-bit c_int. Below is -2, in two's complement, but that only works out // 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits. // because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedFd<'fd> { pub struct BorrowedFd<'fd> {
fd: RawFd, fd: RawFd,
@ -52,6 +53,7 @@ pub struct BorrowedFd<'fd> {
// 32-bit c_int. Below is -2, in two's complement, but that only works out // 32-bit c_int. Below is -2, in two's complement, but that only works out
// because c_int is 32 bits. // because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] #[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedFd { pub struct OwnedFd {
fd: RawFd, fd: RawFd,

View File

@ -32,3 +32,22 @@ fn test_fd() {
assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_fd); assert_eq!(stdin_as_file.as_fd().as_raw_fd(), raw_fd);
assert_eq!(Into::<OwnedFd>::into(stdin_as_file).into_raw_fd(), raw_fd); assert_eq!(Into::<OwnedFd>::into(stdin_as_file).into_raw_fd(), raw_fd);
} }
#[cfg(any(unix, target_os = "wasi"))]
#[test]
fn test_niche_optimizations() {
use crate::mem::size_of;
#[cfg(unix)]
use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[cfg(target_os = "wasi")]
use crate::os::wasi::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
assert_eq!(size_of::<Option<OwnedFd>>(), size_of::<RawFd>());
assert_eq!(size_of::<Option<BorrowedFd<'static>>>(), size_of::<RawFd>());
unsafe {
assert_eq!(OwnedFd::from_raw_fd(RawFd::MIN).into_raw_fd(), RawFd::MIN);
assert_eq!(OwnedFd::from_raw_fd(RawFd::MAX).into_raw_fd(), RawFd::MAX);
assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MIN)).unwrap().into_raw_fd(), RawFd::MIN);
assert_eq!(Some(OwnedFd::from_raw_fd(RawFd::MAX)).unwrap().into_raw_fd(), RawFd::MAX);
}
}

View File

@ -206,6 +206,7 @@ impl OwnedHandle {
} }
/// Allow child processes to inherit the handle. /// Allow child processes to inherit the handle.
#[cfg(not(target_vendor = "uwp"))]
pub(crate) fn set_inheritable(&self) -> io::Result<()> { pub(crate) fn set_inheritable(&self) -> io::Result<()> {
cvt(unsafe { cvt(unsafe {
c::SetHandleInformation( c::SetHandleInformation(

View File

@ -54,3 +54,6 @@ pub use handle::*;
pub use raw::*; pub use raw::*;
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub use socket::*; pub use socket::*;
#[cfg(test)]
mod tests;

View File

@ -10,6 +10,7 @@ use crate::mem;
use crate::mem::forget; use crate::mem::forget;
use crate::sys; use crate::sys;
use crate::sys::c; use crate::sys::c;
#[cfg(not(target_vendor = "uwp"))]
use crate::sys::cvt; use crate::sys::cvt;
/// A borrowed socket. /// A borrowed socket.
@ -34,6 +35,7 @@ use crate::sys::cvt;
target_pointer_width = "64", target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)] )]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct BorrowedSocket<'socket> { pub struct BorrowedSocket<'socket> {
socket: RawSocket, socket: RawSocket,
@ -56,6 +58,7 @@ pub struct BorrowedSocket<'socket> {
target_pointer_width = "64", target_pointer_width = "64",
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE) rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)] )]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")] #[unstable(feature = "io_safety", issue = "87074")]
pub struct OwnedSocket { pub struct OwnedSocket {
socket: RawSocket, socket: RawSocket,

View File

@ -0,0 +1,21 @@
#[test]
fn test_niche_optimizations_socket() {
use crate::mem::size_of;
use crate::os::windows::io::{
BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
assert_eq!(size_of::<Option<OwnedSocket>>(), size_of::<RawSocket>());
assert_eq!(size_of::<Option<BorrowedSocket<'static>>>(), size_of::<RawSocket>(),);
unsafe {
#[cfg(target_pointer_width = "32")]
let (min, max) = (i32::MIN as u32, i32::MAX as u32);
#[cfg(target_pointer_width = "64")]
let (min, max) = (i64::MIN as u64, i64::MAX as u64);
assert_eq!(OwnedSocket::from_raw_socket(min).into_raw_socket(), min);
assert_eq!(OwnedSocket::from_raw_socket(max).into_raw_socket(), max);
assert_eq!(Some(OwnedSocket::from_raw_socket(min)).unwrap().into_raw_socket(), min);
assert_eq!(Some(OwnedSocket::from_raw_socket(max)).unwrap().into_raw_socket(), max);
}
}

View File

@ -221,6 +221,7 @@ impl Handle {
Ok(Self(self.0.duplicate(access, inherit, options)?)) Ok(Self(self.0.duplicate(access, inherit, options)?))
} }
#[cfg(not(target_vendor = "uwp"))]
pub(crate) fn set_inheritable(&self) -> io::Result<()> { pub(crate) fn set_inheritable(&self) -> io::Result<()> {
self.0.set_inheritable() self.0.set_inheritable()
} }

View File

@ -57,10 +57,21 @@ impl Pipes {
} else { } else {
let (ours, theirs) = if ours_readable { (read, write) } else { (write, read) }; let (ours, theirs) = if ours_readable { (read, write) } else { (write, read) };
let ours = Handle::from_raw_handle(ours); let ours = Handle::from_raw_handle(ours);
#[cfg(not(target_vendor = "uwp"))]
let theirs = Handle::from_raw_handle(theirs); let theirs = Handle::from_raw_handle(theirs);
#[cfg(target_vendor = "uwp")]
let mut theirs = Handle::from_raw_handle(theirs);
if their_handle_inheritable { if their_handle_inheritable {
theirs.set_inheritable()?; #[cfg(not(target_vendor = "uwp"))]
{
theirs.set_inheritable()?;
}
#[cfg(target_vendor = "uwp")]
{
theirs = theirs.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?;
}
} }
Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) }) Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) })

View File

@ -22,7 +22,10 @@ This feature allows for use of one of following sanitizers:
To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`, To enable a sanitizer compile with `-Zsanitizer=address`,`-Zsanitizer=cfi`,
`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`, `-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`,
`-Zsanitizer=memtag`, or `-Zsanitizer=thread`. `-Zsanitizer=memtag`, or `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags. Example:
```shell
$ RUSTFLAGS=-Zsanitizer=address cargo build -Zbuild-std --target x86_64-unknown-linux-gnu
```
# AddressSanitizer # AddressSanitizer

View File

@ -29,5 +29,10 @@ module.exports = {
"no-var": ["error"], "no-var": ["error"],
"prefer-const": ["error"], "prefer-const": ["error"],
"prefer-arrow-callback": ["error"], "prefer-arrow-callback": ["error"],
"brace-style": [
"error",
"1tbs",
{ "allowSingleLine": false }
],
} }
}; };

View File

@ -709,8 +709,8 @@ function loadCss(cssFileName) {
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
if (e.parentNode.id !== "implementations-list" || if (e.parentNode.id !== "implementations-list" ||
(!hasClass(e, "implementors-toggle") && (!hasClass(e, "implementors-toggle") &&
!hasClass(e, "type-contents-toggle"))) !hasClass(e, "type-contents-toggle"))
{ ) {
e.open = false; e.open = false;
} }
}); });

View File

@ -98,7 +98,9 @@
// visible. This is necessary since updateScrapedExample calls scrollToLoc which // visible. This is necessary since updateScrapedExample calls scrollToLoc which
// depends on offsetHeight, a property that requires an element to be visible to // depends on offsetHeight, a property that requires an element to be visible to
// compute correctly. // compute correctly.
setTimeout(() => { onEachLazy(moreExamples, updateScrapedExample); }); setTimeout(() => {
onEachLazy(moreExamples, updateScrapedExample);
});
}, {once: true}); }, {once: true});
}); });
})(); })();

View File

@ -320,8 +320,8 @@ window.initSearch = rawSearchIndex => {
if (foundExclamation) { if (foundExclamation) {
throw new Error("Cannot have more than one `!` in an ident"); throw new Error("Cannot have more than one `!` in an ident");
} else if (parserState.pos + 1 < parserState.length && } else if (parserState.pos + 1 < parserState.length &&
isIdentCharacter(parserState.userQuery[parserState.pos + 1])) isIdentCharacter(parserState.userQuery[parserState.pos + 1])
{ ) {
throw new Error("`!` can only be at the end of an ident"); throw new Error("`!` can only be at the end of an ident");
} }
foundExclamation = true; foundExclamation = true;
@ -330,12 +330,10 @@ window.initSearch = rawSearchIndex => {
} else if ( } else if (
isStopCharacter(c) || isStopCharacter(c) ||
isSpecialStartCharacter(c) || isSpecialStartCharacter(c) ||
isSeparatorCharacter(c)) isSeparatorCharacter(c)
{ ) {
break; break;
} } else if (c === ":") { // If we allow paths ("str::string" for example).
// If we allow paths ("str::string" for example).
else if (c === ":") {
if (!isPathStart(parserState)) { if (!isPathStart(parserState)) {
break; break;
} }
@ -372,8 +370,8 @@ window.initSearch = rawSearchIndex => {
end = getIdentEndPosition(parserState); end = getIdentEndPosition(parserState);
} }
if (parserState.pos < parserState.length && if (parserState.pos < parserState.length &&
parserState.userQuery[parserState.pos] === "<") parserState.userQuery[parserState.pos] === "<"
{ ) {
if (isInGenerics) { if (isInGenerics) {
throw new Error("Unexpected `<` after `<`"); throw new Error("Unexpected `<` after `<`");
} else if (start >= end) { } else if (start >= end) {
@ -592,8 +590,8 @@ window.initSearch = rawSearchIndex => {
if (elem && if (elem &&
elem.value !== "All crates" && elem.value !== "All crates" &&
hasOwnPropertyRustdoc(rawSearchIndex, elem.value)) hasOwnPropertyRustdoc(rawSearchIndex, elem.value)
{ ) {
return elem.value; return elem.value;
} }
return null; return null;
@ -786,37 +784,51 @@ window.initSearch = rawSearchIndex => {
// sort by exact match with regard to the last word (mismatch goes later) // sort by exact match with regard to the last word (mismatch goes later)
a = (aaa.word !== userQuery); a = (aaa.word !== userQuery);
b = (bbb.word !== userQuery); b = (bbb.word !== userQuery);
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// Sort by non levenshtein results and then levenshtein results by the distance // Sort by non levenshtein results and then levenshtein results by the distance
// (less changes required to match means higher rankings) // (less changes required to match means higher rankings)
a = (aaa.lev); a = (aaa.lev);
b = (bbb.lev); b = (bbb.lev);
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// sort by crate (non-current crate goes later) // sort by crate (non-current crate goes later)
a = (aaa.item.crate !== window.currentCrate); a = (aaa.item.crate !== window.currentCrate);
b = (bbb.item.crate !== window.currentCrate); b = (bbb.item.crate !== window.currentCrate);
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// sort by item name length (longer goes later) // sort by item name length (longer goes later)
a = aaa.word.length; a = aaa.word.length;
b = bbb.word.length; b = bbb.word.length;
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// sort by item name (lexicographically larger goes later) // sort by item name (lexicographically larger goes later)
a = aaa.word; a = aaa.word;
b = bbb.word; b = bbb.word;
if (a !== b) { return (a > b ? +1 : -1); } if (a !== b) {
return (a > b ? +1 : -1);
}
// sort by index of keyword in item name (no literal occurrence goes later) // sort by index of keyword in item name (no literal occurrence goes later)
a = (aaa.index < 0); a = (aaa.index < 0);
b = (bbb.index < 0); b = (bbb.index < 0);
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// (later literal occurrence, if any, goes later) // (later literal occurrence, if any, goes later)
a = aaa.index; a = aaa.index;
b = bbb.index; b = bbb.index;
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// special precedence for primitive and keyword pages // special precedence for primitive and keyword pages
if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) || if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) ||
@ -831,17 +843,23 @@ window.initSearch = rawSearchIndex => {
// sort by description (no description goes later) // sort by description (no description goes later)
a = (aaa.item.desc === ""); a = (aaa.item.desc === "");
b = (bbb.item.desc === ""); b = (bbb.item.desc === "");
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// sort by type (later occurrence in `itemTypes` goes later) // sort by type (later occurrence in `itemTypes` goes later)
a = aaa.item.ty; a = aaa.item.ty;
b = bbb.item.ty; b = bbb.item.ty;
if (a !== b) { return a - b; } if (a !== b) {
return a - b;
}
// sort by path (lexicographically larger goes later) // sort by path (lexicographically larger goes later)
a = aaa.item.path; a = aaa.item.path;
b = bbb.item.path; b = bbb.item.path;
if (a !== b) { return (a > b ? +1 : -1); } if (a !== b) {
return (a > b ? +1 : -1);
}
// que sera, sera // que sera, sera
return 0; return 0;
@ -1315,16 +1333,15 @@ window.initSearch = rawSearchIndex => {
} }
if (searchWord.indexOf(elem.pathLast) > -1 || if (searchWord.indexOf(elem.pathLast) > -1 ||
row.normalizedName.indexOf(elem.pathLast) > -1) row.normalizedName.indexOf(elem.pathLast) > -1
{ ) {
// filter type: ... queries // filter type: ... queries
if (!results_others[fullId] !== undefined) { if (!results_others[fullId] !== undefined) {
index = row.normalizedName.indexOf(elem.pathLast); index = row.normalizedName.indexOf(elem.pathLast);
} }
} }
lev = levenshtein(searchWord, elem.pathLast); lev = levenshtein(searchWord, elem.pathLast);
if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) {
{
if (elem.pathLast.length < 6) { if (elem.pathLast.length < 6) {
lev = 1; lev = 1;
} else { } else {
@ -1670,8 +1687,8 @@ window.initSearch = rawSearchIndex => {
// By default, the search DOM element is "empty" (meaning it has no children not // By default, the search DOM element is "empty" (meaning it has no children not
// text content). Once a search has been run, it won't be empty, even if you press // text content). Once a search has been run, it won't be empty, even if you press
// ESC or empty the search input (which also "cancels" the search). // ESC or empty the search input (which also "cancels" the search).
&& (!search.firstChild || search.firstChild.innerText !== searchState.loadingText))) && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText))
{ ) {
const elem = document.createElement("a"); const elem = document.createElement("a");
elem.href = results.others[0].href; elem.href = results.others[0].href;
removeClass(elem, "active"); removeClass(elem, "active");
@ -1766,7 +1783,7 @@ window.initSearch = rawSearchIndex => {
let i = 0; let i = 0;
for (const elem of elems) { for (const elem of elems) {
const j = i; const j = i;
elem.onclick = () => { printTab(j); }; elem.onclick = () => printTab(j);
searchState.focusedByTab.push(null); searchState.focusedByTab.push(null);
i += 1; i += 1;
} }

View File

@ -254,8 +254,8 @@
function blurHandler(event) { function blurHandler(event) {
const settingsButton = getSettingsButton(); const settingsButton = getSettingsButton();
if (!elemIsInParent(document.activeElement, settingsButton) && if (!elemIsInParent(document.activeElement, settingsButton) &&
!elemIsInParent(event.relatedTarget, settingsButton)) !elemIsInParent(event.relatedTarget, settingsButton)
{ ) {
window.hideSettings(); window.hideSettings();
} }
} }