Skip to content

Commit

Permalink
Auto merge of rust-lang#117644 - cuviper:beta-next, r=cuviper
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
bors committed Nov 7, 2023
2 parents 489647f + efb81ca commit efc300e
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 115 deletions.
3 changes: 3 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ pub mod assert_matches {
pub use crate::macros::{assert_matches, debug_assert_matches};
}

#[unstable(feature = "cfg_match", issue = "115585")]
pub use crate::macros::cfg_match;

#[macro_use]
mod internal_macros;

Expand Down
177 changes: 88 additions & 89 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,94 @@ pub macro assert_matches {
},
}

/// A macro for defining `#[cfg]` match-like statements.
///
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
/// `#[cfg]` cases, emitting the implementation which matches first.
///
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
/// without having to rewrite each clause multiple times.
///
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
/// all previous declarations do not evaluate to true.
///
/// # Example
///
/// ```
/// #![feature(cfg_match)]
///
/// cfg_match! {
/// cfg(unix) => {
/// fn foo() { /* unix specific functionality */ }
/// }
/// cfg(target_pointer_width = "32") => {
/// fn foo() { /* non-unix, 32-bit functionality */ }
/// }
/// _ => {
/// fn foo() { /* fallback implementation */ }
/// }
/// }
/// ```
#[unstable(feature = "cfg_match", issue = "115585")]
#[rustc_diagnostic_item = "cfg_match"]
pub macro cfg_match {
// with a final wildcard
(
$(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
_ => { $($extra_tokens:item)* }
) => {
cfg_match! {
@__items ();
$((($initial_meta) ($($initial_tokens)*)),)+
(() ($($extra_tokens)*)),
}
},

// without a final wildcard
(
$(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
) => {
cfg_match! {
@__items ();
$((($extra_meta) ($($extra_tokens)*)),)*
}
},

// Internal and recursive macro to emit all the items
//
// Collects all the previous cfgs in a list at the beginning, so they can be
// negated. After the semicolon is all the remaining items.
(@__items ($($_:meta,)*);) => {},
(
@__items ($($no:meta,)*);
(($($yes:meta)?) ($($tokens:item)*)),
$($rest:tt,)*
) => {
// Emit all items within one block, applying an appropriate #[cfg]. The
// #[cfg] will require all `$yes` matchers specified and must also negate
// all previous matchers.
#[cfg(all(
$($yes,)?
not(any($($no),*))
))]
cfg_match! { @__identity $($tokens)* }

// Recurse to emit all other items in `$rest`, and when we do so add all
// our `$yes` matchers to the list of `$no` matchers as future emissions
// will have to negate everything we just matched as well.
cfg_match! {
@__items ($($no,)* $($yes,)?);
$($rest,)*
}
},

// Internal macro to make __apply work out right for different match types,
// because of how macros match/expand stuff.
(@__identity $($tokens:item)*) => {
$($tokens)*
}
}

/// Asserts that a boolean expression is `true` at runtime.
///
/// This will invoke the [`panic!`] macro if the provided expression cannot be
Expand Down Expand Up @@ -321,95 +409,6 @@ pub macro debug_assert_matches($($arg:tt)*) {
}
}

/// A macro for defining `#[cfg]` match-like statements.
///
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
/// `#[cfg]` cases, emitting the implementation which matches first.
///
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
/// without having to rewrite each clause multiple times.
///
/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
/// all previous declarations do not evaluate to true.
///
/// # Example
///
/// ```
/// #![feature(cfg_match)]
///
/// cfg_match! {
/// cfg(unix) => {
/// fn foo() { /* unix specific functionality */ }
/// }
/// cfg(target_pointer_width = "32") => {
/// fn foo() { /* non-unix, 32-bit functionality */ }
/// }
/// _ => {
/// fn foo() { /* fallback implementation */ }
/// }
/// }
/// ```
#[macro_export]
#[unstable(feature = "cfg_match", issue = "115585")]
#[rustc_diagnostic_item = "cfg_match"]
macro_rules! cfg_match {
// with a final wildcard
(
$(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
_ => { $($extra_tokens:item)* }
) => {
cfg_match! {
@__items ();
$((($initial_meta) ($($initial_tokens)*)),)+
(() ($($extra_tokens)*)),
}
};

// without a final wildcard
(
$(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
) => {
cfg_match! {
@__items ();
$((($extra_meta) ($($extra_tokens)*)),)*
}
};

// Internal and recursive macro to emit all the items
//
// Collects all the previous cfgs in a list at the beginning, so they can be
// negated. After the semicolon is all the remaining items.
(@__items ($($_:meta,)*);) => {};
(
@__items ($($no:meta,)*);
(($($yes:meta)?) ($($tokens:item)*)),
$($rest:tt,)*
) => {
// Emit all items within one block, applying an appropriate #[cfg]. The
// #[cfg] will require all `$yes` matchers specified and must also negate
// all previous matchers.
#[cfg(all(
$($yes,)?
not(any($($no),*))
))]
cfg_match! { @__identity $($tokens)* }

// Recurse to emit all other items in `$rest`, and when we do so add all
// our `$yes` matchers to the list of `$no` matchers as future emissions
// will have to negate everything we just matched as well.
cfg_match! {
@__items ($($no,)* $($yes,)?);
$($rest,)*
}
};

// Internal macro to make __apply work out right for different match types,
// because of how macros match/expand stuff.
(@__identity $($tokens:item)*) => {
$($tokens)*
};
}

/// Returns whether the given expression matches any of the given patterns.
///
/// Like in a `match` expression, the pattern can be optionally followed by `if`
Expand Down
58 changes: 33 additions & 25 deletions src/bootstrap/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ fn sanitize_sh(path: &Path) -> String {
}

fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
let tmp_file = dir.join(".tmp");
match fs::File::create(&tmp_file) {
let tmp = dir.join(".tmp");
match fs::create_dir_all(&tmp) {
Ok(_) => {
fs::remove_file(tmp_file).unwrap();
fs::remove_dir_all(tmp).unwrap();
true
}
Err(e) => {
Expand All @@ -73,16 +73,27 @@ fn install_sh(

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

// Sanity check for the user write access on prefix and sysconfdir
assert!(
is_dir_writable_for_user(&prefix),
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
);
assert!(
is_dir_writable_for_user(&sysconfdir),
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
);
// Sanity checks on the write access of user.
//
// When the `DESTDIR` environment variable is present, there is no point to
// check write access for `prefix` and `sysconfdir` individually, as they
// are combined with the path from the `DESTDIR` environment variable. In
// this case, we only need to check the `DESTDIR` path, disregarding the
// `prefix` and `sysconfdir` paths.
if let Some(destdir) = &destdir_env {
assert!(is_dir_writable_for_user(destdir), "User doesn't have write access on DESTDIR.");
} else {
assert!(
is_dir_writable_for_user(&prefix),
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
);
assert!(
is_dir_writable_for_user(&sysconfdir),
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
);
}

let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
Expand All @@ -96,13 +107,13 @@ fn install_sh(
let mut cmd = Command::new(SHELL);
cmd.current_dir(&empty_dir)
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
.arg(format!("--prefix={}", prepare_dir(prefix)))
.arg(format!("--sysconfdir={}", prepare_dir(sysconfdir)))
.arg(format!("--datadir={}", prepare_dir(datadir)))
.arg(format!("--docdir={}", prepare_dir(docdir)))
.arg(format!("--bindir={}", prepare_dir(bindir)))
.arg(format!("--libdir={}", prepare_dir(libdir)))
.arg(format!("--mandir={}", prepare_dir(mandir)))
.arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix)))
.arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir)))
.arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir)))
.arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir)))
.arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir)))
.arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir)))
.arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir)))
.arg("--disable-ldconfig");
builder.run(&mut cmd);
t!(fs::remove_dir_all(&empty_dir));
Expand All @@ -112,19 +123,16 @@ fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
}

fn prepare_dir(mut path: PathBuf) -> String {
fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
// The DESTDIR environment variable is a standard way to install software in a subdirectory
// while keeping the original directory structure, even if the prefix or other directories
// contain absolute paths.
//
// More information on the environment variable is available here:
// https://www.gnu.org/prep/standards/html_node/DESTDIR.html
if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
// Sanity check for the user write access on DESTDIR
assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR.");

if let Some(destdir) = destdir_env {
let without_destdir = path.clone();
path = destdir;
path = destdir.clone();
// Custom .join() which ignores disk roots.
for part in without_destdir.components() {
if let Component::Normal(s) = part {
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-project
Submodule llvm-project updated 67 files
+4 −2 .github/workflows/release-tasks.yml
+1 −1 clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
+3 −0 clang-tools-extra/clangd/TidyProvider.cpp
+18 −0 clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-cxx20.cpp
+8 −1 clang/docs/ReleaseNotes.rst
+1 −1 clang/include/clang/Basic/DiagnosticASTKinds.td
+9 −4 clang/lib/AST/ExprConstant.cpp
+2 −1 clang/lib/AST/Interp/Interp.cpp
+1 −1 clang/lib/Format/WhitespaceManager.cpp
+9 −2 clang/lib/Parse/ParseDecl.cpp
+27 −0 clang/test/CodeGen/thread_local.c
+19 −0 clang/test/Sema/thread_local.c
+6 −0 clang/test/SemaCXX/constant-expression-cxx2a.cpp
+7 −0 clang/test/SemaCXX/eval-crashes.cpp
+0 −10 clang/unittests/Format/FormatTest.cpp
+9 −0 flang/lib/Optimizer/CodeGen/CodeGen.cpp
+41 −0 flang/test/Fir/comdat.fir
+7 −1 flang/test/Intrinsics/math-codegen.fir
+44 −16 libcxx/include/__config
+46 −0 libcxx/test/libcxx/odr_signature.exceptions.sh.cpp
+72 −0 libcxx/test/libcxx/odr_signature.hardening.sh.cpp
+1 −0 libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/gcount.pass.cpp
+8 −0 libcxx/utils/libcxx/test/params.py
+1 −1 llvm/CMakeLists.txt
+1 −1 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+24 −0 llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+3 −0 llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
+5 −2 llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+2 −0 llvm/lib/Target/LoongArch/LoongArch.h
+121 −0 llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+17 −0 llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
+12 −0 llvm/lib/Target/LoongArch/LoongArchFloatInstrFormats.td
+6 −0 llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+0 −7 llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp
+1 −0 llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+14 −5 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+13 −3 llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+29 −39 llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+8 −3 llvm/lib/Transforms/Scalar/GVN.cpp
+1 −0 llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+29 −0 llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll
+190 −0 llvm/test/CodeGen/AArch64/arg_promotion.ll
+22 −0 llvm/test/CodeGen/AArch64/framelayout-sve.mir
+1 −0 llvm/test/CodeGen/LoongArch/O0-pipeline.ll
+34 −0 llvm/test/CodeGen/LoongArch/cfr-copy.mir
+26 −0 llvm/test/CodeGen/LoongArch/cfr-pseudo-copy.mir
+6 −7 llvm/test/CodeGen/LoongArch/inline-asm-clobbers-fcc.mir
+1 −0 llvm/test/CodeGen/LoongArch/opt-pipeline.ll
+6 −0 llvm/test/CodeGen/RISCV/double-maximum-minimum.ll
+14 −0 llvm/test/CodeGen/RISCV/double-select-fcmp.ll
+15 −1 llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
+1 −1 llvm/test/Transforms/ConstraintElimination/shl.ll
+131 −2 llvm/test/Transforms/CorrelatedValuePropagation/abs.ll
+57 −0 llvm/test/Transforms/GVN/pr69301.ll
+14 −0 llvm/test/Transforms/MemCpyOpt/memcpy.ll
+1 −1 llvm/utils/gn/secondary/llvm/version.gni
+1 −1 llvm/utils/lit/lit/__init__.py
+26 −0 mlir/include/mlir/Dialect/LLVMIR/Transforms/AddComdats.h
+1 −0 mlir/include/mlir/Dialect/LLVMIR/Transforms/Passes.h
+13 −0 mlir/include/mlir/Dialect/LLVMIR/Transforms/Passes.td
+64 −0 mlir/lib/Dialect/LLVMIR/Transforms/AddComdats.cpp
+1 −0 mlir/lib/Dialect/LLVMIR/Transforms/CMakeLists.txt
+2 −1 mlir/lib/ExecutionEngine/CRunnerUtils.cpp
+17 −0 mlir/test/Dialect/LLVMIR/add-linkonce-comdat.mlir
+1 −2 openmp/libomptarget/tools/kernelreplay/llvm-omp-kernel-replay.cpp
+2 −1 openmp/runtime/src/kmp_runtime.cpp
+1 −1 openmp/runtime/src/kmp_wrapper_getpid.h

0 comments on commit efc300e

Please sign in to comment.