Skip to content

Commit efc300e

Browse files
committed
Auto merge of rust-lang#117644 - cuviper:beta-next, r=cuviper
[beta] backports - ensure the parent path's existence on `x install` rust-lang#116349 - Remove `cfg_match` from the prelude rust-lang#117162 - improve and fix `x install` rust-lang#117383 - Update to LLVM 17.0.4 rust-lang#117436 r? cuviper
2 parents 489647f + efb81ca commit efc300e

File tree

4 files changed

+125
-115
lines changed

4 files changed

+125
-115
lines changed

library/core/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ pub mod assert_matches {
290290
pub use crate::macros::{assert_matches, debug_assert_matches};
291291
}
292292

293+
#[unstable(feature = "cfg_match", issue = "115585")]
294+
pub use crate::macros::cfg_match;
295+
293296
#[macro_use]
294297
mod internal_macros;
295298

library/core/src/macros/mod.rs

+88-89
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,94 @@ pub macro assert_matches {
168168
},
169169
}
170170

171+
/// A macro for defining `#[cfg]` match-like statements.
172+
///
173+
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
174+
/// `#[cfg]` cases, emitting the implementation which matches first.
175+
///
176+
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
177+
/// without having to rewrite each clause multiple times.
178+
///
179+
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
180+
/// all previous declarations do not evaluate to true.
181+
///
182+
/// # Example
183+
///
184+
/// ```
185+
/// #![feature(cfg_match)]
186+
///
187+
/// cfg_match! {
188+
/// cfg(unix) => {
189+
/// fn foo() { /* unix specific functionality */ }
190+
/// }
191+
/// cfg(target_pointer_width = "32") => {
192+
/// fn foo() { /* non-unix, 32-bit functionality */ }
193+
/// }
194+
/// _ => {
195+
/// fn foo() { /* fallback implementation */ }
196+
/// }
197+
/// }
198+
/// ```
199+
#[unstable(feature = "cfg_match", issue = "115585")]
200+
#[rustc_diagnostic_item = "cfg_match"]
201+
pub macro cfg_match {
202+
// with a final wildcard
203+
(
204+
$(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
205+
_ => { $($extra_tokens:item)* }
206+
) => {
207+
cfg_match! {
208+
@__items ();
209+
$((($initial_meta) ($($initial_tokens)*)),)+
210+
(() ($($extra_tokens)*)),
211+
}
212+
},
213+
214+
// without a final wildcard
215+
(
216+
$(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
217+
) => {
218+
cfg_match! {
219+
@__items ();
220+
$((($extra_meta) ($($extra_tokens)*)),)*
221+
}
222+
},
223+
224+
// Internal and recursive macro to emit all the items
225+
//
226+
// Collects all the previous cfgs in a list at the beginning, so they can be
227+
// negated. After the semicolon is all the remaining items.
228+
(@__items ($($_:meta,)*);) => {},
229+
(
230+
@__items ($($no:meta,)*);
231+
(($($yes:meta)?) ($($tokens:item)*)),
232+
$($rest:tt,)*
233+
) => {
234+
// Emit all items within one block, applying an appropriate #[cfg]. The
235+
// #[cfg] will require all `$yes` matchers specified and must also negate
236+
// all previous matchers.
237+
#[cfg(all(
238+
$($yes,)?
239+
not(any($($no),*))
240+
))]
241+
cfg_match! { @__identity $($tokens)* }
242+
243+
// Recurse to emit all other items in `$rest`, and when we do so add all
244+
// our `$yes` matchers to the list of `$no` matchers as future emissions
245+
// will have to negate everything we just matched as well.
246+
cfg_match! {
247+
@__items ($($no,)* $($yes,)?);
248+
$($rest,)*
249+
}
250+
},
251+
252+
// Internal macro to make __apply work out right for different match types,
253+
// because of how macros match/expand stuff.
254+
(@__identity $($tokens:item)*) => {
255+
$($tokens)*
256+
}
257+
}
258+
171259
/// Asserts that a boolean expression is `true` at runtime.
172260
///
173261
/// This will invoke the [`panic!`] macro if the provided expression cannot be
@@ -321,95 +409,6 @@ pub macro debug_assert_matches($($arg:tt)*) {
321409
}
322410
}
323411

324-
/// A macro for defining `#[cfg]` match-like statements.
325-
///
326-
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
327-
/// `#[cfg]` cases, emitting the implementation which matches first.
328-
///
329-
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
330-
/// without having to rewrite each clause multiple times.
331-
///
332-
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
333-
/// all previous declarations do not evaluate to true.
334-
///
335-
/// # Example
336-
///
337-
/// ```
338-
/// #![feature(cfg_match)]
339-
///
340-
/// cfg_match! {
341-
/// cfg(unix) => {
342-
/// fn foo() { /* unix specific functionality */ }
343-
/// }
344-
/// cfg(target_pointer_width = "32") => {
345-
/// fn foo() { /* non-unix, 32-bit functionality */ }
346-
/// }
347-
/// _ => {
348-
/// fn foo() { /* fallback implementation */ }
349-
/// }
350-
/// }
351-
/// ```
352-
#[macro_export]
353-
#[unstable(feature = "cfg_match", issue = "115585")]
354-
#[rustc_diagnostic_item = "cfg_match"]
355-
macro_rules! cfg_match {
356-
// with a final wildcard
357-
(
358-
$(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
359-
_ => { $($extra_tokens:item)* }
360-
) => {
361-
cfg_match! {
362-
@__items ();
363-
$((($initial_meta) ($($initial_tokens)*)),)+
364-
(() ($($extra_tokens)*)),
365-
}
366-
};
367-
368-
// without a final wildcard
369-
(
370-
$(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
371-
) => {
372-
cfg_match! {
373-
@__items ();
374-
$((($extra_meta) ($($extra_tokens)*)),)*
375-
}
376-
};
377-
378-
// Internal and recursive macro to emit all the items
379-
//
380-
// Collects all the previous cfgs in a list at the beginning, so they can be
381-
// negated. After the semicolon is all the remaining items.
382-
(@__items ($($_:meta,)*);) => {};
383-
(
384-
@__items ($($no:meta,)*);
385-
(($($yes:meta)?) ($($tokens:item)*)),
386-
$($rest:tt,)*
387-
) => {
388-
// Emit all items within one block, applying an appropriate #[cfg]. The
389-
// #[cfg] will require all `$yes` matchers specified and must also negate
390-
// all previous matchers.
391-
#[cfg(all(
392-
$($yes,)?
393-
not(any($($no),*))
394-
))]
395-
cfg_match! { @__identity $($tokens)* }
396-
397-
// Recurse to emit all other items in `$rest`, and when we do so add all
398-
// our `$yes` matchers to the list of `$no` matchers as future emissions
399-
// will have to negate everything we just matched as well.
400-
cfg_match! {
401-
@__items ($($no,)* $($yes,)?);
402-
$($rest,)*
403-
}
404-
};
405-
406-
// Internal macro to make __apply work out right for different match types,
407-
// because of how macros match/expand stuff.
408-
(@__identity $($tokens:item)*) => {
409-
$($tokens)*
410-
};
411-
}
412-
413412
/// Returns whether the given expression matches any of the given patterns.
414413
///
415414
/// Like in a `match` expression, the pattern can be optionally followed by `if`

src/bootstrap/install.rs

+33-25
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ fn sanitize_sh(path: &Path) -> String {
4646
}
4747

4848
fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
49-
let tmp_file = dir.join(".tmp");
50-
match fs::File::create(&tmp_file) {
49+
let tmp = dir.join(".tmp");
50+
match fs::create_dir_all(&tmp) {
5151
Ok(_) => {
52-
fs::remove_file(tmp_file).unwrap();
52+
fs::remove_dir_all(tmp).unwrap();
5353
true
5454
}
5555
Err(e) => {
@@ -73,16 +73,27 @@ fn install_sh(
7373

7474
let prefix = default_path(&builder.config.prefix, "/usr/local");
7575
let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
76+
let destdir_env = env::var_os("DESTDIR").map(PathBuf::from);
7677

77-
// Sanity check for the user write access on prefix and sysconfdir
78-
assert!(
79-
is_dir_writable_for_user(&prefix),
80-
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
81-
);
82-
assert!(
83-
is_dir_writable_for_user(&sysconfdir),
84-
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
85-
);
78+
// Sanity checks on the write access of user.
79+
//
80+
// When the `DESTDIR` environment variable is present, there is no point to
81+
// check write access for `prefix` and `sysconfdir` individually, as they
82+
// are combined with the path from the `DESTDIR` environment variable. In
83+
// this case, we only need to check the `DESTDIR` path, disregarding the
84+
// `prefix` and `sysconfdir` paths.
85+
if let Some(destdir) = &destdir_env {
86+
assert!(is_dir_writable_for_user(destdir), "User doesn't have write access on DESTDIR.");
87+
} else {
88+
assert!(
89+
is_dir_writable_for_user(&prefix),
90+
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
91+
);
92+
assert!(
93+
is_dir_writable_for_user(&sysconfdir),
94+
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
95+
);
96+
}
8697

8798
let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
8899
let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
@@ -96,13 +107,13 @@ fn install_sh(
96107
let mut cmd = Command::new(SHELL);
97108
cmd.current_dir(&empty_dir)
98109
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
99-
.arg(format!("--prefix={}", prepare_dir(prefix)))
100-
.arg(format!("--sysconfdir={}", prepare_dir(sysconfdir)))
101-
.arg(format!("--datadir={}", prepare_dir(datadir)))
102-
.arg(format!("--docdir={}", prepare_dir(docdir)))
103-
.arg(format!("--bindir={}", prepare_dir(bindir)))
104-
.arg(format!("--libdir={}", prepare_dir(libdir)))
105-
.arg(format!("--mandir={}", prepare_dir(mandir)))
110+
.arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix)))
111+
.arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir)))
112+
.arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir)))
113+
.arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir)))
114+
.arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir)))
115+
.arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir)))
116+
.arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir)))
106117
.arg("--disable-ldconfig");
107118
builder.run(&mut cmd);
108119
t!(fs::remove_dir_all(&empty_dir));
@@ -112,19 +123,16 @@ fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
112123
config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
113124
}
114125

115-
fn prepare_dir(mut path: PathBuf) -> String {
126+
fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
116127
// The DESTDIR environment variable is a standard way to install software in a subdirectory
117128
// while keeping the original directory structure, even if the prefix or other directories
118129
// contain absolute paths.
119130
//
120131
// More information on the environment variable is available here:
121132
// https://www.gnu.org/prep/standards/html_node/DESTDIR.html
122-
if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
123-
// Sanity check for the user write access on DESTDIR
124-
assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR.");
125-
133+
if let Some(destdir) = destdir_env {
126134
let without_destdir = path.clone();
127-
path = destdir;
135+
path = destdir.clone();
128136
// Custom .join() which ignores disk roots.
129137
for part in without_destdir.components() {
130138
if let Component::Normal(s) = part {

src/llvm-project

Submodule llvm-project updated 67 files

0 commit comments

Comments
 (0)