Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4121,6 +4121,7 @@ version = "0.0.0"
dependencies = [
"cc",
"libc",
"shell-words",
]

[[package]]
Expand Down Expand Up @@ -5115,6 +5116,12 @@ dependencies = [
"lazy_static",
]

[[package]]
name = "shell-words"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"

[[package]]
name = "shlex"
version = "1.3.0"
Expand Down
24 changes: 16 additions & 8 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2416,11 +2416,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
) -> Const<'tcx> {
let tcx = self.tcx();

let ty::Array(elem_ty, _) = ty.kind() else {
let e = tcx
.dcx()
.span_err(array_expr.span, format!("expected `{}`, found const array", ty));
return Const::new_error(tcx, e);
let elem_ty = match ty.kind() {
ty::Array(elem_ty, _) => elem_ty,
ty::Error(e) => return Const::new_error(tcx, *e),
_ => {
let e = tcx
.dcx()
.span_err(array_expr.span, format!("expected `{}`, found const array", ty));
return Const::new_error(tcx, e);
}
};

let elems = array_expr
Expand Down Expand Up @@ -2539,9 +2543,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
) -> Const<'tcx> {
let tcx = self.tcx();

let ty::Tuple(tys) = ty.kind() else {
let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty));
return Const::new_error(tcx, e);
let tys = match ty.kind() {
ty::Tuple(tys) => tys,
ty::Error(e) => return Const::new_error(tcx, *e),
_ => {
let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty));
return Const::new_error(tcx, e);
}
};

let exprs = exprs
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ libc = "0.2.73"
# tidy-alphabetical-start
# `cc` updates often break things, so we pin it here.
cc = "=1.2.16"
shell-words = "1.1.1"
# tidy-alphabetical-end

[features]
Expand Down
90 changes: 76 additions & 14 deletions compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::borrow::Cow;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fmt::Display;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::process::{Command, Output, Stdio};
use std::str::SplitWhitespace;
use std::vec::IntoIter;

const OPTIONAL_COMPONENTS: &[&str] = &[
"x86",
Expand Down Expand Up @@ -86,8 +89,8 @@ fn rerun_if_changed_anything_in_dir(dir: &Path) {
}

#[track_caller]
fn output(cmd: &mut Command) -> String {
let output = match cmd.stderr(Stdio::inherit()).output() {
fn execute(cmd: &mut Command) -> Output {
let output = match cmd.output() {
Ok(status) => status,
Err(e) => {
println!("\n\nfailed to execute command: {cmd:?}\nerror: {e}\n\n");
Expand All @@ -101,7 +104,52 @@ fn output(cmd: &mut Command) -> String {
cmd, output.status
);
}
String::from_utf8(output.stdout).unwrap()
output
}

#[track_caller]
fn output(cmd: &mut Command) -> String {
String::from_utf8(execute(cmd.stderr(Stdio::inherit())).stdout).unwrap()
}
#[track_caller]
fn stderr(cmd: &mut Command) -> String {
String::from_utf8(execute(cmd).stderr).unwrap()
}

enum LlvmConfigOutput {
QuotedPaths(String),
UnquotedPaths(String),
}

#[derive(Clone)]
enum SplitLlvmConfigOutput<'a> {
QuotedPaths(IntoIter<String>),
UnquotedPaths(SplitWhitespace<'a>),
}

impl<'a> Iterator for SplitLlvmConfigOutput<'a> {
type Item = Cow<'a, str>;
fn next(&mut self) -> Option<Cow<'a, str>> {
match self {
Self::QuotedPaths(iter) => iter.next().map(Cow::Owned),
Self::UnquotedPaths(iter) => iter.next().map(Cow::Borrowed),
}
}
}

impl<'a> IntoIterator for &'a LlvmConfigOutput {
type Item = Cow<'a, str>;
type IntoIter = SplitLlvmConfigOutput<'a>;
fn into_iter(self) -> Self::IntoIter {
match self {
LlvmConfigOutput::QuotedPaths(output) => SplitLlvmConfigOutput::QuotedPaths(
shell_words::split(&output).expect("matched quotes").into_iter(),
),
LlvmConfigOutput::UnquotedPaths(output) => {
SplitLlvmConfigOutput::UnquotedPaths(output.split_whitespace())
}
}
}
}

fn main() {
Expand All @@ -125,6 +173,19 @@ fn main() {

println!("cargo:rerun-if-changed={}", llvm_config.display());

// FIXME: `--quote-paths` was added to llvm-config in LLVM 22, so this test (and all its ensuing
// fallback paths) can be removed once we bump the minimum llvm_version >= (22, 0, 0).
let llvm_config_supports_quote_paths =
stderr(Command::new(&llvm_config).arg("--help")).contains("quote-paths");

let quoted_split = |mut cmd: Command| {
if llvm_config_supports_quote_paths {
LlvmConfigOutput::QuotedPaths(output(cmd.arg("--quote-paths")))
} else {
LlvmConfigOutput::UnquotedPaths(output(&mut cmd))
}
};

// Test whether we're cross-compiling LLVM. This is a pretty rare case
// currently where we're producing an LLVM for a different platform than
// what this build script is currently running on.
Expand Down Expand Up @@ -167,7 +228,8 @@ fn main() {
// Link in our own LLVM shims, compiled with the same flags as LLVM
let mut cmd = Command::new(&llvm_config);
cmd.arg("--cxxflags");
let cxxflags = output(&mut cmd);
let cxxflags = quoted_split(cmd);
let mut cxxflags_iter = cxxflags.into_iter();
let mut cfg = cc::Build::new();
cfg.warnings(false);

Expand All @@ -180,7 +242,7 @@ fn main() {
if std::env::var_os("CI").is_some() && !target.contains("msvc") {
cfg.warnings_into_errors(true);
}
for flag in cxxflags.split_whitespace() {
for flag in cxxflags_iter.clone() {
// Ignore flags like `-m64` when we're doing a cross build
if is_crossed && flag.starts_with("-m") {
continue;
Expand All @@ -201,7 +263,7 @@ fn main() {
continue;
}

cfg.flag(flag);
cfg.flag(&*flag);
}

for component in &components {
Expand Down Expand Up @@ -289,13 +351,13 @@ fn main() {
}
cmd.args(&components);

for lib in output(&mut cmd).split_whitespace() {
for lib in &quoted_split(cmd) {
let mut is_static = false;
let name = if let Some(stripped) = lib.strip_prefix("-l") {
stripped
} else if let Some(stripped) = lib.strip_prefix('-') {
stripped
} else if Path::new(lib).exists() {
} else if Path::new(&*lib).exists() {
// On MSVC llvm-config will print the full name to libraries, but
// we're only interested in the name part
// On Unix when we get a static library llvm-config will print the
Expand All @@ -306,7 +368,7 @@ fn main() {
// and we transform the zstd part into
// cargo:rustc-link-search-native=/usr/local/lib
// cargo:rustc-link-lib=static=zstd
let path = Path::new(lib);
let path = Path::new(&*lib);
if lib.ends_with(".a") {
is_static = true;
println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display());
Expand Down Expand Up @@ -351,7 +413,7 @@ fn main() {
// that those -L directories are the same!
let mut cmd = Command::new(&llvm_config);
cmd.arg(llvm_link_arg).arg("--ldflags");
for lib in output(&mut cmd).split_whitespace() {
for lib in &quoted_split(cmd) {
if is_crossed {
if let Some(stripped) = lib.strip_prefix("-LIBPATH:") {
println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target));
Expand All @@ -373,7 +435,7 @@ fn main() {
// dependencies.
let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS");
if let Some(s) = llvm_linker_flags {
for lib in s.into_string().unwrap().split_whitespace() {
for lib in shell_words::split(&s.into_string().unwrap()).expect("matched quotes") {
if let Some(stripped) = lib.strip_prefix("-l") {
println!("cargo:rustc-link-lib={stripped}");
} else if let Some(stripped) = lib.strip_prefix("-L") {
Expand Down Expand Up @@ -414,15 +476,15 @@ fn main() {
// C++ runtime library
if !target.contains("msvc") {
if let Some(s) = llvm_static_stdcpp {
assert!(!cxxflags.contains("stdlib=libc++"));
assert!(cxxflags_iter.all(|flag| flag != "stdlib=libc++"));
let path = PathBuf::from(s);
println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display());
if target.contains("windows") {
println!("cargo:rustc-link-lib=static:-bundle={stdcppname}");
} else {
println!("cargo:rustc-link-lib=static={stdcppname}");
}
} else if cxxflags.contains("stdlib=libc++") {
} else if cxxflags_iter.any(|flag| flag == "stdlib=libc++") {
println!("cargo:rustc-link-lib=c++");
} else {
println!("cargo:rustc-link-lib={stdcppname}");
Expand Down
14 changes: 6 additions & 8 deletions library/core/src/ops/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ impl<B, C> ControlFlow<B, C> {
/// # Examples
///
/// ```
/// #![feature(control_flow_ok)]
///
/// use std::ops::ControlFlow;
///
/// struct TreeNode<T> {
Expand Down Expand Up @@ -263,8 +261,9 @@ impl<B, C> ControlFlow<B, C> {
/// assert_eq!(res, Ok(&5));
/// ```
#[inline]
#[unstable(feature = "control_flow_ok", issue = "140266")]
#[rustc_const_unstable(feature = "control_flow_ok", issue = "140266")]
#[stable(feature = "control_flow_ok", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "control_flow_ok", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
pub const fn break_ok(self) -> Result<B, C> {
match self {
ControlFlow::Continue(c) => Err(c),
Expand Down Expand Up @@ -317,8 +316,6 @@ impl<B, C> ControlFlow<B, C> {
/// # Examples
///
/// ```
/// #![feature(control_flow_ok)]
///
/// use std::ops::ControlFlow;
///
/// struct TreeNode<T> {
Expand Down Expand Up @@ -376,8 +373,9 @@ impl<B, C> ControlFlow<B, C> {
/// assert_eq!(res, Err("too big value detected"));
/// ```
#[inline]
#[unstable(feature = "control_flow_ok", issue = "140266")]
#[rustc_const_unstable(feature = "control_flow_ok", issue = "140266")]
#[stable(feature = "control_flow_ok", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "control_flow_ok", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
pub const fn continue_ok(self) -> Result<C, B> {
match self {
ControlFlow::Continue(c) => Ok(c),
Expand Down
1 change: 0 additions & 1 deletion library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#![feature(const_select_unpredictable)]
#![feature(const_trait_impl)]
#![feature(const_unsigned_bigint_helpers)]
#![feature(control_flow_ok)]
#![feature(core_intrinsics)]
#![feature(core_intrinsics_fallbacks)]
#![feature(core_io_borrowed_buf)]
Expand Down
11 changes: 5 additions & 6 deletions src/ci/docker/host-aarch64/aarch64-gnu-llvm-20/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,19 @@ RUN sh /scripts/sccache.sh

# We are disabling CI LLVM since this builder is intentionally using a host
# LLVM, rather than the typical src/llvm-project LLVM.
ENV NO_DOWNLOAD_CI_LLVM 1
ENV EXTERNAL_LLVM 1
ENV NO_DOWNLOAD_CI_LLVM="1"
ENV EXTERNAL_LLVM="1"

# Using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
--build=aarch64-unknown-linux-gnu \
ENV RUST_CONFIGURE_ARGS="--build=aarch64-unknown-linux-gnu \
--llvm-root=/usr/lib/llvm-20 \
--enable-llvm-link-shared \
--set rust.randomize-layout=true \
--set rust.thin-lto-import-instr-limit=10
--set rust.thin-lto-import-instr-limit=10"

COPY scripts/shared.sh /scripts/

COPY scripts/stage_2_test_set1.sh /scripts/
COPY scripts/stage_2_test_set2.sh /scripts/

ENV SCRIPT "Must specify DOCKER_SCRIPT for this image"
ENV SCRIPT="Must specify DOCKER_SCRIPT for this image"
9 changes: 4 additions & 5 deletions src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

ENV RUST_CONFIGURE_ARGS \
--build=aarch64-unknown-linux-gnu \
ENV RUST_CONFIGURE_ARGS="--build=aarch64-unknown-linux-gnu \
--enable-sanitizers \
--enable-profiler \
--enable-compiler-docs
ENV SCRIPT python3 ../x.py --stage 2 test && \
python3 ../x.py --stage 2 test src/tools/cargo
--enable-compiler-docs"
ENV SCRIPT="python3 ../x.py --stage 2 test && \
python3 ../x.py --stage 2 test src/tools/cargo"
13 changes: 6 additions & 7 deletions src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ ENV HOSTS=aarch64-unknown-linux-gnu

ENV CPATH=/usr/include/aarch64-linux-gnu/:$CPATH

ENV RUST_CONFIGURE_ARGS \
--build=aarch64-unknown-linux-gnu \
ENV RUST_CONFIGURE_ARGS="--build=aarch64-unknown-linux-gnu \
--enable-full-tools \
--enable-profiler \
--enable-sanitizers \
Expand All @@ -93,12 +92,12 @@ ENV RUST_CONFIGURE_ARGS \
--set rust.jemalloc \
--set rust.bootstrap-override-lld=true \
--set rust.lto=thin \
--set rust.codegen-units=1
--set rust.codegen-units=1"

ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
ENV SCRIPT="python3 ../x.py build --set rust.debug=true opt-dist && \
./build/$HOSTS/stage1-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
--host $HOSTS --target $HOSTS --include-default-paths build-manifest bootstrap enzyme
--host $HOSTS --target $HOSTS --include-default-paths build-manifest bootstrap enzyme"

ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=clang
ENV LIBCURL_NO_PKG_CONFIG 1
ENV DIST_REQUIRE_ALL_TOOLS 1
ENV LIBCURL_NO_PKG_CONFIG="1"
ENV DIST_REQUIRE_ALL_TOOLS="1"
1 change: 1 addition & 0 deletions src/tools/tidy/src/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"sha1",
"sha2",
"sharded-slab",
"shell-words",
"shlex",
"simd-adler32",
"smallvec",
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/const-generics/mgca/syntactic-type-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This test ensures proper diagnostics emission during HIR ty lowering
// See https://github.com/rust-lang/rust/issues/153254

#![feature(min_generic_const_args)]
#![expect(incomplete_features)]

type const T0: _ = ();
//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for constants [E0121]

type const T1 = [0];
//~^ ERROR: missing type for `const` item

fn main() {}
Loading
Loading