Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 15 pull requests #92785

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0660732
`std::path::absolute`
ChrisDenton Dec 8, 2021
60ec6a0
Tweak sentence in `transmute` docs
camelid Dec 27, 2021
7fd6ddf
Error when selected impl is not const in constck
fee1-dead Dec 30, 2021
2b70a3d
Display "private fields" instead of "fields omitted"
camelid Jan 9, 2022
8fd8db5
Extended the note on the use of `no_run` attribute
JohnScience Jan 10, 2022
680ebea
RELEASES.md: Add 1.58 release note for `File::options` stabilization
joshtriplett Jan 9, 2022
2ae616a
Fix doc formatting for time.rs
rosik Jan 10, 2022
55abf38
Add note about upstream commit musl-patch-configure.diff is derived from
wesleywiser Jan 10, 2022
881b427
Add missing suffix for sidebar-items script path
GuillaumeGomez Jan 10, 2022
5786bbd
Eliminate "boxed" wording in `std::error::Error` documentation
david-perez Jan 10, 2022
fc8af98
Document Box<T> FFI guarantee in 1.41.0 release notes
nico-abram Jan 3, 2022
c91ad5d
Improve documentation for File::options to give a more likely example
joshtriplett Jan 9, 2022
11bea26
Update AsmArgs field visibility for rustfmt
ytmimi Jan 11, 2022
22d4e97
:arrow_up: rust-analyzer
lnicola Jan 11, 2022
9234c0f
Fix style for rust logo
GuillaumeGomez Jan 11, 2022
24c6e96
Add GUI test for rust logo style in the sidebars
GuillaumeGomez Jan 11, 2022
bf5130b
Add test
fee1-dead Jan 11, 2022
7485a7f
Rollup merge of #91673 - ChrisDenton:path-absolute, r=Mark-Simulacrum
matthiaskrgr Jan 11, 2022
2ab347b
Rollup merge of #92328 - camelid:sentence, r=scottmcm
matthiaskrgr Jan 11, 2022
9a6dd30
Rollup merge of #92432 - fee1-dead:constck-impl-constness, r=oli-obk
matthiaskrgr Jan 11, 2022
df59daf
Rollup merge of #92506 - nico-abram:uwu, r=Mark-Simulacrum
matthiaskrgr Jan 11, 2022
2276f9f
Rollup merge of #92699 - camelid:private-fields, r=jsha
matthiaskrgr Jan 11, 2022
530dc4b
Rollup merge of #92703 - joshtriplett:relnotes-file-options, r=pietro…
matthiaskrgr Jan 11, 2022
1576188
Rollup merge of #92707 - JohnScience:patch-1, r=GuillaumeGomez
matthiaskrgr Jan 11, 2022
142f040
Rollup merge of #92709 - joshtriplett:file-options-docs, r=Mark-Simul…
matthiaskrgr Jan 11, 2022
2383d92
Rollup merge of #92720 - rosik:patch-1, r=m-ou-se
matthiaskrgr Jan 11, 2022
d362337
Rollup merge of #92732 - wesleywiser:note_musl_patch_info, r=Mark-Sim…
matthiaskrgr Jan 11, 2022
d0e0d65
Rollup merge of #92742 - GuillaumeGomez:missing-suffix-sidebar-items,…
matthiaskrgr Jan 11, 2022
9d53c86
Rollup merge of #92748 - david-perez:eliminate-boxed-wording-std-erro…
matthiaskrgr Jan 11, 2022
0b21a51
Rollup merge of #92754 - ytmimi:AsmArgs-field-visibility, r=calebcart…
matthiaskrgr Jan 11, 2022
098c3e2
Rollup merge of #92756 - lnicola:rust-analyzer-2022-01-11, r=lnicola
matthiaskrgr Jan 11, 2022
7306d8c
Rollup merge of #92764 - GuillaumeGomez:fix-rust-logo-style, r=jsha
matthiaskrgr Jan 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Stabilized APIs
- [`Result::unwrap_unchecked`]
- [`Result::unwrap_err_unchecked`]
- [`NonZero{unsigned}::is_power_of_two`]
- [`File::options`]

These APIs are now usable in const contexts:

Expand Down Expand Up @@ -141,6 +142,7 @@ and related tools.
[`Result::unwrap_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_unchecked
[`Result::unwrap_err_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_err_unchecked
[`NonZero{unsigned}::is_power_of_two`]: https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html#method.is_power_of_two
[`File::options`]: https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.options
[`unix::process::ExitStatusExt::core_dumped`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.core_dumped
[`unix::process::ExitStatusExt::stopped_signal`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.stopped_signal
[`unix::process::ExitStatusExt::continued`]: https://doc.rust-lang.org/stable/std/os/unix/process/trait.ExitStatusExt.html#tymethod.continued
Expand Down Expand Up @@ -2588,6 +2590,11 @@ Language
- [Visibility modifiers (e.g. `pub`) are now syntactically allowed on trait items and
enum variants.][66183] These are still rejected semantically, but
can be seen and parsed by procedural macros and conditional compilation.
- [You can now define a Rust `extern "C"` function with `Box<T>` and use `T*` as the corresponding
type on the C side.][62514] Please see [the documentation][box-memory-layout] for more information,
including the important caveat about preferring to avoid `Box<T>` in Rust signatures for functions defined in C.

[box-memory-layout]: https://doc.rust-lang.org/std/boxed/index.html#memory-layout

Compiler
--------
Expand Down Expand Up @@ -2662,6 +2669,7 @@ Compatibility Notes

[54733]: https://github.com/rust-lang/rust/pull/54733/
[61351]: https://github.com/rust-lang/rust/pull/61351/
[62514]: https://github.com/rust-lang/rust/pull/62514/
[67255]: https://github.com/rust-lang/rust/pull/67255/
[66661]: https://github.com/rust-lang/rust/pull/66661/
[66771]: https://github.com/rust-lang/rust/pull/66771/
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_builtin_macros/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ use rustc_target::asm::InlineAsmArch;
use smallvec::smallvec;

pub struct AsmArgs {
templates: Vec<P<ast::Expr>>,
operands: Vec<(ast::InlineAsmOperand, Span)>,
pub templates: Vec<P<ast::Expr>>,
pub operands: Vec<(ast::InlineAsmOperand, Span)>,
named_args: FxHashMap<Symbol, usize>,
reg_args: FxHashSet<usize>,
clobber_abis: Vec<(Symbol, Span)>,
pub clobber_abis: Vec<(Symbol, Span)>,
options: ast::InlineAsmOptions,
options_spans: Vec<Span>,
pub options_spans: Vec<Span>,
}

fn parse_args<'a>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
param_env,
Binder::dummy(TraitPredicate {
trait_ref,
constness: ty::BoundConstness::ConstIfConst,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
}),
);
Expand All @@ -829,6 +829,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
return;
}
Ok(Some(ImplSource::UserDefined(data))) => {
if let hir::Constness::NotConst = tcx.impl_constness(data.impl_def_id) {
self.check_op(ops::FnCallNonConst(None));
return;
}
let callee_name = tcx.item_name(callee);
if let Some(&did) = tcx
.associated_item_def_ids(data.impl_def_id)
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ extern "rust-intrinsic" {
/// Below are common applications of `transmute` which can be replaced with safer
/// constructs.
///
/// Turning raw bytes(`&[u8]`) to `u32`, `f64`, etc.:
/// Turning raw bytes (`&[u8]`) into `u32`, `f64`, etc.:
///
/// ```
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
Expand Down
12 changes: 6 additions & 6 deletions library/std/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,21 +606,21 @@ impl Error for time::FromSecsError {}

// Copied from `any.rs`.
impl dyn Error + 'static {
/// Returns `true` if the boxed type is the same as `T`
/// Returns `true` if the inner type is the same as `T`.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
// Get `TypeId` of the type this function is instantiated with.
let t = TypeId::of::<T>();

// Get `TypeId` of the type in the trait object.
let boxed = self.type_id(private::Internal);
// Get `TypeId` of the type in the trait object (`self`).
let concrete = self.type_id(private::Internal);

// Compare both `TypeId`s on equality.
t == boxed
t == concrete
}

/// Returns some reference to the boxed value if it is of type `T`, or
/// Returns some reference to the inner value if it is of type `T`, or
/// `None` if it isn't.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
Expand All @@ -632,7 +632,7 @@ impl dyn Error + 'static {
}
}

/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// Returns some mutable reference to the inner value if it is of type `T`, or
/// `None` if it isn't.
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
Expand Down
9 changes: 5 additions & 4 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,10 @@ impl File {
/// open or create a file with specific options if `open()` or `create()`
/// are not appropriate.
///
/// It is equivalent to `OpenOptions::new()` but allows you to write more
/// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")`
/// you can write `File::options().read(true).open("foo.txt")`. This
/// It is equivalent to `OpenOptions::new()`, but allows you to write more
/// readable code. Instead of
/// `OpenOptions::new().append(true).open("example.log")`,
/// you can write `File::options().append(true).open("example.log")`. This
/// also avoids the need to import `OpenOptions`.
///
/// See the [`OpenOptions::new`] function for more details.
Expand All @@ -369,7 +370,7 @@ impl File {
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let mut f = File::options().read(true).open("foo.txt")?;
/// let mut f = File::options().append(true).open("example.log")?;
/// Ok(())
/// }
/// ```
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
// std is implemented with unstable features, many of which are internal
// compiler details that will never be stable
// NB: the following list is sorted to minimize merge conflicts.
#![feature(absolute_path)]
#![feature(alloc_error_handler)]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
Expand Down
80 changes: 79 additions & 1 deletion library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ use crate::str::FromStr;
use crate::sync::Arc;

use crate::ffi::{OsStr, OsString};

use crate::sys;
use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3141,3 +3141,81 @@ impl Error for StripPrefixError {
"prefix not found"
}
}

/// Makes the path absolute without accessing the filesystem.
///
/// If the path is relative, the current directory is used as the base directory.
/// All intermediate components will be resolved according to platforms-specific
/// rules but unlike [`canonicalize`][crate::fs::canonicalize] this does not
/// resolve symlinks and may succeed even if the path does not exist.
///
/// If the `path` is empty or getting the
/// [current directory][crate::env::current_dir] fails then an error will be
/// returned.
///
/// # Examples
///
/// ## Posix paths
///
/// ```
/// #![feature(absolute_path)]
/// # #[cfg(unix)]
/// fn main() -> std::io::Result<()> {
/// use std::path::{self, Path};
///
/// // Relative to absolute
/// let absolute = path::absolute("foo/./bar")?;
/// assert!(absolute.ends_with("foo/bar"));
///
/// // Absolute to absolute
/// let absolute = path::absolute("/foo//test/.././bar.rs")?;
/// assert_eq!(absolute, Path::new("/foo/test/../bar.rs"));
/// Ok(())
/// }
/// # #[cfg(not(unix))]
/// # fn main() {}
/// ```
///
/// The paths is resolved using [POSIX semantics][posix-semantics] except that
/// it stops short of resolving symlinks. This means it will keep `..`
/// components and trailing slashes.
///
/// ## Windows paths
///
/// ```
/// #![feature(absolute_path)]
/// # #[cfg(windows)]
/// fn main() -> std::io::Result<()> {
/// use std::path::{self, Path};
///
/// // Relative to absolute
/// let absolute = path::absolute("foo/./bar")?;
/// assert!(absolute.ends_with(r"foo\bar"));
///
/// // Absolute to absolute
/// let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;
///
/// assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
/// Ok(())
/// }
/// # #[cfg(not(windows))]
/// # fn main() {}
/// ```
///
/// For verbatim paths this will simply return the path as given. For other
/// paths this is currently equivalent to calling [`GetFullPathNameW`][windows-path]
/// This may change in the future.
///
/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
#[unstable(feature = "absolute_path", issue = "none")]
pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
let path = path.as_ref();
if path.as_os_str().is_empty() {
return Err(io::Error::new_const(
io::ErrorKind::InvalidInput,
&"cannot make an empty path absolute",
));
}
sys::path::absolute(path)
}
58 changes: 58 additions & 0 deletions library/std/src/path/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,64 @@ fn test_ord() {
ord!(Equal, "foo/bar", "foo/bar//");
}

#[test]
#[cfg(unix)]
fn test_unix_absolute() {
use crate::path::absolute;

assert!(absolute("").is_err());

let relative = "a/b";
let mut expected = crate::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap(), expected);

// Test how components are collected.
assert_eq!(absolute("/a/b/c").unwrap(), Path::new("/a/b/c"));
assert_eq!(absolute("/a//b/c").unwrap(), Path::new("/a/b/c"));
assert_eq!(absolute("//a/b/c").unwrap(), Path::new("//a/b/c"));
assert_eq!(absolute("///a/b/c").unwrap(), Path::new("/a/b/c"));
assert_eq!(absolute("/a/b/c/").unwrap(), Path::new("/a/b/c/"));
assert_eq!(absolute("/a/./b/../c/.././..").unwrap(), Path::new("/a/b/../c/../.."));
}

#[test]
#[cfg(windows)]
fn test_windows_absolute() {
use crate::path::absolute;
// An empty path is an error.
assert!(absolute("").is_err());

let relative = r"a\b";
let mut expected = crate::env::current_dir().unwrap();
expected.push(relative);
assert_eq!(absolute(relative).unwrap(), expected);

macro_rules! unchanged(
($path:expr) => {
assert_eq!(absolute($path).unwrap(), Path::new($path));
}
);

unchanged!(r"C:\path\to\file");
unchanged!(r"C:\path\to\file\");
unchanged!(r"\\server\share\to\file");
unchanged!(r"\\server.\share.\to\file");
unchanged!(r"\\.\PIPE\name");
unchanged!(r"\\.\C:\path\to\COM1");
unchanged!(r"\\?\C:\path\to\file");
unchanged!(r"\\?\UNC\server\share\to\file");
unchanged!(r"\\?\PIPE\name");
// Verbatim paths are always unchanged, no matter what.
unchanged!(r"\\?\path.\to/file..");

assert_eq!(absolute(r"C:\path..\to.\file.").unwrap(), Path::new(r"C:\path..\to\file"));
assert_eq!(absolute(r"C:\path\to\COM1").unwrap(), Path::new(r"\\.\COM1"));
assert_eq!(absolute(r"C:\path\to\COM1.txt").unwrap(), Path::new(r"\\.\COM1"));
assert_eq!(absolute(r"C:\path\to\COM1 .txt").unwrap(), Path::new(r"\\.\COM1"));
assert_eq!(absolute(r"C:\path\to\cOnOuT$").unwrap(), Path::new(r"\\.\cOnOuT$"));
}

#[bench]
fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
let prefix = "my/home";
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/sgx/path.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::ffi::OsStr;
use crate::path::Prefix;
use crate::path::{Path, PathBuf, Prefix};
use crate::sys::unsupported;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
Expand All @@ -17,3 +18,7 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {

pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';

pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
unsupported()
}
7 changes: 6 additions & 1 deletion library/std/src/sys/solid/path.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::ffi::OsStr;
use crate::path::Prefix;
use crate::path::{Path, PathBuf, Prefix};
use crate::sys::unsupported;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
Expand All @@ -17,3 +18,7 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {

pub const MAIN_SEP_STR: &str = "\\";
pub const MAIN_SEP: char = '\\';

pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
unsupported()
}
45 changes: 44 additions & 1 deletion library/std/src/sys/unix/path.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::env;
use crate::ffi::OsStr;
use crate::path::Prefix;
use crate::io;
use crate::os::unix::ffi::OsStrExt;
use crate::path::{Path, PathBuf, Prefix};

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
Expand All @@ -18,3 +21,43 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {

pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';

/// Make a POSIX path absolute without changing its semantics.
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
// This is mostly a wrapper around collecting `Path::components`, with
// exceptions made where this conflicts with the POSIX specification.
// See 4.13 Pathname Resolution, IEEE Std 1003.1-2017
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13

let mut components = path.components();
let path_os = path.as_os_str().as_bytes();

let mut normalized = if path.is_absolute() {
// "If a pathname begins with two successive <slash> characters, the
// first component following the leading <slash> characters may be
// interpreted in an implementation-defined manner, although more than
// two leading <slash> characters shall be treated as a single <slash>
// character."
if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
components.next();
PathBuf::from("//")
} else {
PathBuf::new()
}
} else {
env::current_dir()?
};
normalized.extend(components);

// "Interfaces using pathname resolution may specify additional constraints
// when a pathname that does not name an existing directory contains at
// least one non- <slash> character and contains one or more trailing
// <slash> characters".
// A trailing <slash> is also meaningful if "a symbolic link is
// encountered during pathname resolution".
if path_os.ends_with(b"/") {
normalized.push("");
}

Ok(normalized)
}
Loading