Skip to content

Commit 098b1b9

Browse files
committed
make path separators available in const context
* consolidate various representations of separators in std::sys::path into a single macro_rules invocation per platform to save transcription errors * make `std::path::is_separator()` const * new constants `std::path::{SEPARATORS, SEPARATORS_STR}`
1 parent 72de815 commit 098b1b9

8 files changed

Lines changed: 58 additions & 58 deletions

File tree

library/std/src/path.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -266,22 +266,33 @@ impl<'a> Prefix<'a> {
266266
/// ```
267267
#[must_use]
268268
#[stable(feature = "rust1", since = "1.0.0")]
269-
pub fn is_separator(c: char) -> bool {
269+
#[rustc_const_unstable(feature = "const_path_separators", issue = "153106")]
270+
pub const fn is_separator(c: char) -> bool {
270271
c.is_ascii() && is_sep_byte(c as u8)
271272
}
272273

273-
/// The primary separator of path components for the current platform.
274-
///
275-
/// For example, `/` on Unix and `\` on Windows.
274+
/// All path separators recognized on the current platform, represented as [`char`]s; for example,
275+
/// this is `&['/'][..]` on Unix and `&['\\', '/'][..]` on Windows. The [primary
276+
/// separator](MAIN_SEPARATOR) is always element 0 of the slice.
277+
#[unstable(feature = "const_path_separators", issue = "153106")]
278+
pub const SEPARATORS: &[char] = crate::sys::path::SEPARATORS;
279+
280+
/// All path separators recognized on the current platform, represented as [`&str`]s; for example,
281+
/// this is `&["/"][..]` on Unix and `&["\\", "/"][..]` on Windows. The [primary
282+
/// separator](MAIN_SEPARATOR_STR) is always element 0 of the slice.
283+
#[unstable(feature = "const_path_separators", issue = "153106")]
284+
pub const SEPARATORS_STR: &[&str] = crate::sys::path::SEPARATORS_STR;
285+
286+
/// The primary separator of path components for the current platform, represented as a [`char`];
287+
/// for example, this is `'/'` on Unix and `'\\'` on Windows.
276288
#[stable(feature = "rust1", since = "1.0.0")]
277289
#[cfg_attr(not(test), rustc_diagnostic_item = "path_main_separator")]
278-
pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
290+
pub const MAIN_SEPARATOR: char = SEPARATORS[0];
279291

280-
/// The primary separator of path components for the current platform.
281-
///
282-
/// For example, `/` on Unix and `\` on Windows.
292+
/// The primary separator of path components for the current platform, represented as a [`&str`];
293+
/// for example, this is `"/"` on Unix and `"\\"` on Windows.
283294
#[stable(feature = "main_separator_str", since = "1.68.0")]
284-
pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR;
295+
pub const MAIN_SEPARATOR_STR: &str = SEPARATORS_STR[0];
285296

286297
////////////////////////////////////////////////////////////////////////////////
287298
// Misc helpers

library/std/src/sys/path/cygwin.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,20 @@ use crate::sys::cvt;
55
use crate::sys::helpers::run_path_with_cstr;
66
use crate::{io, ptr};
77

8-
#[inline]
9-
pub fn is_sep_byte(b: u8) -> bool {
10-
b == b'/' || b == b'\\'
11-
}
8+
path_separator_bytes!(b'/', b'\\');
129

1310
/// Cygwin always prefers `/` over `\`, and it always converts all `/` to `\`
1411
/// internally when calling Win32 APIs. Therefore, the server component of path
1512
/// `\\?\UNC\localhost/share` is `localhost/share` on Win32, but `localhost`
1613
/// on Cygwin.
1714
#[inline]
18-
pub fn is_verbatim_sep(b: u8) -> bool {
19-
b == b'/' || b == b'\\'
15+
pub const fn is_verbatim_sep(b: u8) -> bool {
16+
is_sep_byte(b)
2017
}
2118

2219
pub use super::windows_prefix::parse_prefix;
2320

2421
pub const HAS_PREFIXES: bool = true;
25-
pub const MAIN_SEP_STR: &str = "/";
26-
pub const MAIN_SEP: char = '/';
2722

2823
unsafe extern "C" {
2924
// Doc: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html

library/std/src/sys/path/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
// There's a lot of necessary redundancy in separator definition. Consolidated into a macro to
2+
// prevent transcription errors.
3+
macro_rules! path_separator_bytes {
4+
($($sep:literal),+) => (
5+
pub const SEPARATORS: &[char] = &[$($sep as char,)+];
6+
pub const SEPARATORS_STR: &[&str] = &[$(
7+
match str::from_utf8(&[$sep]) {
8+
Ok(s) => s,
9+
Err(_) => panic!("path_separator_bytes must be ASCII bytes"),
10+
}
11+
),+];
12+
13+
#[inline]
14+
pub const fn is_sep_byte(b: u8) -> bool {
15+
$(b == $sep) ||+
16+
}
17+
)
18+
}
19+
120
cfg_select! {
221
target_os = "windows" => {
322
mod windows;

library/std/src/sys/path/sgx.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,18 @@ use crate::io;
33
use crate::path::{Path, PathBuf, Prefix};
44
use crate::sys::unsupported;
55

6-
#[inline]
7-
pub fn is_sep_byte(b: u8) -> bool {
8-
b == b'/'
9-
}
6+
path_separator_bytes!(b'/');
107

118
#[inline]
12-
pub fn is_verbatim_sep(b: u8) -> bool {
13-
b == b'/'
9+
pub const fn is_verbatim_sep(b: u8) -> bool {
10+
is_sep_byte(b)
1411
}
1512

1613
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
1714
None
1815
}
1916

2017
pub const HAS_PREFIXES: bool = false;
21-
pub const MAIN_SEP_STR: &str = "/";
22-
pub const MAIN_SEP: char = '/';
2318

2419
pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
2520
unsupported()

library/std/src/sys/path/uefi.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,21 @@ use crate::path::{Path, PathBuf, Prefix};
55
use crate::sys::pal::helpers;
66
use crate::sys::unsupported_err;
77

8+
path_separator_bytes!(b'\\');
9+
810
const FORWARD_SLASH: u8 = b'/';
911
const COLON: u8 = b':';
1012

1113
#[inline]
12-
pub fn is_sep_byte(b: u8) -> bool {
13-
b == b'\\'
14-
}
15-
16-
#[inline]
17-
pub fn is_verbatim_sep(b: u8) -> bool {
18-
b == b'\\'
14+
pub const fn is_verbatim_sep(b: u8) -> bool {
15+
is_sep_byte(b)
1916
}
2017

2118
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
2219
None
2320
}
2421

2522
pub const HAS_PREFIXES: bool = true;
26-
pub const MAIN_SEP_STR: &str = "\\";
27-
pub const MAIN_SEP: char = '\\';
2823

2924
/// UEFI paths can be of 4 types:
3025
///

library/std/src/sys/path/unix.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@ use crate::ffi::OsStr;
22
use crate::path::{Path, PathBuf, Prefix};
33
use crate::{env, io};
44

5-
#[inline]
6-
pub fn is_sep_byte(b: u8) -> bool {
7-
b == b'/'
8-
}
5+
path_separator_bytes!(b'/');
96

107
#[inline]
11-
pub fn is_verbatim_sep(b: u8) -> bool {
12-
b == b'/'
8+
pub const fn is_verbatim_sep(b: u8) -> bool {
9+
is_sep_byte(b)
1310
}
1411

1512
#[inline]
@@ -18,8 +15,6 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
1815
}
1916

2017
pub const HAS_PREFIXES: bool = false;
21-
pub const MAIN_SEP_STR: &str = "/";
22-
pub const MAIN_SEP: char = '/';
2318

2419
/// Make a POSIX path absolute without changing its semantics.
2520
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {

library/std/src/sys/path/unsupported_backslash.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@ use crate::io;
44
use crate::path::{Path, PathBuf, Prefix};
55
use crate::sys::unsupported;
66

7-
#[inline]
8-
pub fn is_sep_byte(b: u8) -> bool {
9-
b == b'\\'
10-
}
7+
path_separator_bytes!(b'\\');
118

129
#[inline]
13-
pub fn is_verbatim_sep(b: u8) -> bool {
14-
b == b'\\'
10+
pub const fn is_verbatim_sep(b: u8) -> bool {
11+
is_sep_byte(b)
1512
}
1613

1714
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
1815
None
1916
}
2017

2118
pub const HAS_PREFIXES: bool = true;
22-
pub const MAIN_SEP_STR: &str = "\\";
23-
pub const MAIN_SEP: char = '\\';
2419

2520
pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
2621
unsupported()

library/std/src/sys/path/windows.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ mod tests;
99

1010
pub use super::windows_prefix::parse_prefix;
1111

12+
path_separator_bytes!(b'\\', b'/');
13+
1214
pub const HAS_PREFIXES: bool = true;
13-
pub const MAIN_SEP_STR: &str = "\\";
14-
pub const MAIN_SEP: char = '\\';
1515

1616
/// A null terminated wide string.
1717
#[repr(transparent)]
@@ -48,12 +48,7 @@ pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&WCStr) -> io::Result<T>) ->
4848
}
4949

5050
#[inline]
51-
pub fn is_sep_byte(b: u8) -> bool {
52-
b == b'/' || b == b'\\'
53-
}
54-
55-
#[inline]
56-
pub fn is_verbatim_sep(b: u8) -> bool {
51+
pub const fn is_verbatim_sep(b: u8) -> bool {
5752
b == b'\\'
5853
}
5954

0 commit comments

Comments
 (0)