From 0bb020ace98e58ac2147a3fc43f8d9a610c39c24 Mon Sep 17 00:00:00 2001 From: lapla Date: Sun, 22 Feb 2026 19:45:25 +0900 Subject: [PATCH 1/7] Make `const_lit_matches_ty` check literal suffixes for exact type match --- compiler/rustc_middle/src/ty/consts/lit.rs | 15 +++++++--- .../const-arg-mismatched-literal-suffix.rs | 10 +++++++ ...const-arg-mismatched-literal-suffix.stderr | 8 ++++++ .../type-dependent/type-mismatch.full.stderr | 14 +--------- .../type-dependent/type-mismatch.min.stderr | 14 +--------- .../type-dependent/type-mismatch.rs | 3 +- .../const-eval/array-len-mismatch-type.rs | 5 +--- .../const-eval/array-len-mismatch-type.stderr | 28 ++----------------- tests/ui/repeat-expr/repeat_count.rs | 5 +--- tests/ui/repeat-expr/repeat_count.stderr | 22 +++++---------- 10 files changed, 43 insertions(+), 81 deletions(-) create mode 100644 tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs create mode 100644 tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr diff --git a/compiler/rustc_middle/src/ty/consts/lit.rs b/compiler/rustc_middle/src/ty/consts/lit.rs index 3d41925131b40..be6dfb20e0433 100644 --- a/compiler/rustc_middle/src/ty/consts/lit.rs +++ b/compiler/rustc_middle/src/ty/consts/lit.rs @@ -1,4 +1,4 @@ -use rustc_ast::LitKind; +use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_hir; use rustc_macros::HashStable; @@ -44,10 +44,17 @@ pub fn const_lit_matches_ty<'tcx>( { true } - (LitKind::Int(..), ty::Uint(_)) if !neg => true, - (LitKind::Int(..), ty::Int(_)) => true, + (LitKind::Int(_, LitIntType::Unsigned(lit_ty)), ty::Uint(expect_ty)) if !neg => { + lit_ty == *expect_ty + } + (LitKind::Int(_, LitIntType::Signed(lit_ty)), ty::Int(expect_ty)) => lit_ty == *expect_ty, + (LitKind::Int(_, LitIntType::Unsuffixed), ty::Uint(_)) if !neg => true, + (LitKind::Int(_, LitIntType::Unsuffixed), ty::Int(_)) => true, (LitKind::Bool(..), ty::Bool) => true, - (LitKind::Float(..), ty::Float(_)) => true, + (LitKind::Float(_, LitFloatType::Suffixed(lit_ty)), ty::Float(expect_ty)) => { + lit_ty == *expect_ty + } + (LitKind::Float(_, LitFloatType::Unsuffixed), ty::Float(_)) => true, (LitKind::Char(..), ty::Char) => true, (LitKind::Err(..), _) => true, _ => false, diff --git a/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs new file mode 100644 index 0000000000000..0494871023e5c --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.rs @@ -0,0 +1,10 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +type const CONST: usize = 1_i32; +//~^ ERROR the constant `1` is not of type `usize` +//~| NOTE expected `usize`, found `i32` + +fn main() { + const { CONST }; +} diff --git a/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr new file mode 100644 index 0000000000000..bd5de375e8545 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-arg-mismatched-literal-suffix.stderr @@ -0,0 +1,8 @@ +error: the constant `1` is not of type `usize` + --> $DIR/const-arg-mismatched-literal-suffix.rs:4:1 + | +LL | type const CONST: usize = 1_i32; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr index 9de140dab9eb6..95d20de1b432e 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -1,15 +1,3 @@ -error: the constant `1` is not of type `u8` - --> $DIR/type-mismatch.rs:8:27 - | -LL | assert_eq!(R.method::<1u16>(), 1); - | ^^^^ expected `u8`, found `u16` - | -note: required by a const generic parameter in `R::method` - --> $DIR/type-mismatch.rs:5:15 - | -LL | fn method(&self) -> u8 { N } - | ^^^^^^^^^^^ required by this const generic parameter in `R::method` - error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -22,6 +10,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr index 9de140dab9eb6..95d20de1b432e 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -1,15 +1,3 @@ -error: the constant `1` is not of type `u8` - --> $DIR/type-mismatch.rs:8:27 - | -LL | assert_eq!(R.method::<1u16>(), 1); - | ^^^^ expected `u8`, found `u16` - | -note: required by a const generic parameter in `R::method` - --> $DIR/type-mismatch.rs:5:15 - | -LL | fn method(&self) -> u8 { N } - | ^^^^^^^^^^^ required by this const generic parameter in `R::method` - error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -22,6 +10,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.rs b/tests/ui/const-generics/type-dependent/type-mismatch.rs index fc7ae994184be..6ed5fdca30ae3 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.rs +++ b/tests/ui/const-generics/type-dependent/type-mismatch.rs @@ -6,6 +6,5 @@ impl R { } fn main() { assert_eq!(R.method::<1u16>(), 1); - //~^ ERROR the constant `1` is not of type `u8` - //~| ERROR mismatched types + //~^ ERROR mismatched types } diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.rs b/tests/ui/consts/const-eval/array-len-mismatch-type.rs index 463572c13e104..6e08a05b1062a 100644 --- a/tests/ui/consts/const-eval/array-len-mismatch-type.rs +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.rs @@ -1,8 +1,5 @@ //! Regression test for pub struct Data([[&'static str]; 5_i32]); -//~^ ERROR the constant `5` is not of type `usize` -//~| ERROR the size for values of type `[&'static str]` cannot be known at compilation time -//~| ERROR mismatched types +//~^ ERROR mismatched types const _: &'static Data = unsafe { &*(&[] as *const Data) }; -//~^ ERROR the type `[[&str]; 5]` has an unknown layout fn main() {} diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr index 0f03006f00326..ce641f4a74b9c 100644 --- a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr @@ -1,26 +1,3 @@ -error: the constant `5` is not of type `usize` - --> $DIR/array-len-mismatch-type.rs:2:17 - | -LL | pub struct Data([[&'static str]; 5_i32]); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` - | - = note: the length of array `[[&'static str]; 5]` must be type `usize` - -error[E0277]: the size for values of type `[&'static str]` cannot be known at compilation time - --> $DIR/array-len-mismatch-type.rs:2:17 - | -LL | pub struct Data([[&'static str]; 5_i32]); - | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[&'static str]` - = note: slice and array elements must have `Sized` type - -error[E0080]: the type `[[&str]; 5]` has an unknown layout - --> $DIR/array-len-mismatch-type.rs:6:39 - | -LL | const _: &'static Data = unsafe { &*(&[] as *const Data) }; - | ^^ evaluation of `_` failed here - error[E0308]: mismatched types --> $DIR/array-len-mismatch-type.rs:2:34 | @@ -33,7 +10,6 @@ LL - pub struct Data([[&'static str]; 5_i32]); LL + pub struct Data([[&'static str]; 5_usize]); | -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0080, E0277, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/repeat-expr/repeat_count.rs b/tests/ui/repeat-expr/repeat_count.rs index b1e3a9d8cb3b6..f4d07cc2de03d 100644 --- a/tests/ui/repeat-expr/repeat_count.rs +++ b/tests/ui/repeat-expr/repeat_count.rs @@ -27,10 +27,7 @@ fn main() { //~| NOTE expected `usize`, found `isize` //~| NOTE `-1_isize` cannot fit into type `usize` let h = [0; 4u8]; - //~^ ERROR the constant `4` is not of type `usize` - //~| NOTE expected `usize`, found `u8` - //~| NOTE the length of array `[{integer}; 4]` must be type `usize` - //~| ERROR mismatched types + //~^ ERROR mismatched types //~| NOTE expected `usize`, found `u8` struct I { i: (), diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index 5da9dbe032098..eb9581b8f7ae4 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -50,20 +50,6 @@ LL | let g = [0_usize; -1_isize]; | = note: `-1_isize` cannot fit into type `usize` -error: the constant `4` is not of type `usize` - --> $DIR/repeat_count.rs:29:13 - | -LL | let h = [0; 4u8]; - | ^^^^^^^^ expected `usize`, found `u8` - | - = note: the length of array `[{integer}; 4]` must be type `usize` - -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:38:17 - | -LL | let i = [0; I { i: () }]; - | ^^^^^^^^^^^ expected `usize`, found `I` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:29:17 | @@ -76,7 +62,13 @@ LL - let h = [0; 4u8]; LL + let h = [0; 4usize]; | -error: aborting due to 10 previous errors +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:35:17 + | +LL | let i = [0; I { i: () }]; + | ^^^^^^^^^^^ expected `usize`, found `I` + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0435. For more information about an error, try `rustc --explain E0308`. From 7b4474a26502a0158d5b15029eddd3f8462ba029 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Mar 2026 16:52:31 +1100 Subject: [PATCH 2/7] Remove `TaskDeps::phantom_data`. It has no effect. Presumably at some point in the past there were generics involved here? --- compiler/rustc_middle/src/dep_graph/graph.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index a71373c62f38e..b0c1d188b9040 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -1,6 +1,5 @@ use std::fmt::Debug; use std::hash::Hash; -use std::marker::PhantomData; use std::sync::Arc; use std::sync::atomic::{AtomicU32, Ordering}; @@ -1353,8 +1352,6 @@ pub struct TaskDeps { /// scan. If the number is higher, a hashset has better perf. This field is that hashset. It's /// only used if the number of elements in `reads` exceeds `LINEAR_SCAN_MAX`. read_set: FxHashSet, - - phantom_data: PhantomData, } impl TaskDeps { @@ -1368,7 +1365,6 @@ impl TaskDeps { node, reads: EdgesVec::new(), read_set: FxHashSet::with_capacity_and_hasher(read_set_capacity, Default::default()), - phantom_data: PhantomData, } } } From 69042d166756d62a27e00c7e35af7414a2bad322 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Mar 2026 17:17:24 +1100 Subject: [PATCH 3/7] Remove unused `Lift` impl. --- compiler/rustc_middle/src/ty/structural_impls.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 8707b03e4b8f2..9a2f1e8a13a1a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -4,7 +4,6 @@ //! to help with the tedium. use std::fmt::{self, Debug}; -use std::marker::PhantomData; use rustc_abi::TyAndLayout; use rustc_hir::def::Namespace; @@ -270,13 +269,6 @@ TrivialTypeTraversalAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations -impl<'tcx> Lift> for PhantomData<&()> { - type Lifted = PhantomData<&'tcx ()>; - fn lift_to_interner(self, _: TyCtxt<'tcx>) -> Option { - Some(PhantomData) - } -} - impl<'tcx, T: Lift>> Lift> for Option { type Lifted = Option; fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option { From b3fddcbf28c9f45155b199ec989f7089285252b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Mar 2026 09:10:58 +1100 Subject: [PATCH 4/7] Add a comment explaining the 'tcx lifetime. --- compiler/rustc_interface/src/passes.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5d4db9aef003c..cdfe80e1fe963 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -964,6 +964,17 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( let incremental = dep_graph.is_fully_enabled(); + // Note: this function body is the origin point of the widely-used 'tcx lifetime. + // + // `gcx_cell` is defined here and `&gcx_cell` is passed to `create_global_ctxt`, which then + // actually creates the `GlobalCtxt` with a `gcx_cell.get_or_init(...)` call. This is done so + // that the resulting reference has the type `&'tcx GlobalCtxt<'tcx>`, which is what `TyCtxt` + // needs. If we defined and created the `GlobalCtxt` within `create_global_ctxt` then its type + // would be `&'a GlobalCtxt<'tcx>`, with two lifetimes. + // + // Similarly, by creating `arena` here and passing in `&arena`, that reference has the type + // `&'tcx WorkerLocal>`, also with one lifetime. And likewise for `hir_arena`. + let gcx_cell = OnceLock::new(); let arena = WorkerLocal::new(|_| Arena::default()); let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); From e26974ca33aa322bbc60db5d1010899e40f6d624 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 9 Jan 2026 08:35:43 +1000 Subject: [PATCH 5/7] bootstrap: minimal fix for ./x install src with build.docs = false When running the `install src` command I'm seeing failures as the `builder.doc_out(host)` directory does not exist. This is because `match_paths_to_steps_and_run()` doesn't actually build any documentation as the `paths.is_empty()` causes an early return. This results in install failures as the `*/doc` src directory doesn't exist. This patch ensures that the builder.doc_out(host) directory exists. This fixes installing the Rust source when `build.docs = false`. This fixes installing the Rust source code in OpenEmbedded. Signed-off-by: Alistair Francis Signed-off-by: Jieyou Xu --- src/bootstrap/src/core/build_steps/dist.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 2e291f7c2c320..28a7afd6c61a6 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -87,6 +87,12 @@ impl Step for Docs { // from a shared directory. builder.run_default_doc_steps(); + // In case no default doc steps are run for host, it is possible that `/doc` directory + // is never created. + if !builder.config.dry_run() { + t!(fs::create_dir_all(builder.doc_out(host))); + } + let dest = "share/doc/rust/html"; let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); From 169dd72d476b415a974f8c37416af1bb80f29de3 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Thu, 5 Mar 2026 10:38:56 +0300 Subject: [PATCH 6/7] Fix obtaining def_id from unresolved segment --- compiler/rustc_hir_analysis/src/delegation.rs | 10 ++++------ .../generics/unresolved-segment-ice-153389.rs | 13 +++++++++++++ .../generics/unresolved-segment-ice-153389.stderr | 9 +++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 tests/ui/delegation/generics/unresolved-segment-ice-153389.rs create mode 100644 tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index b1c03b824866e..3392a72daec14 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -572,17 +572,15 @@ fn get_delegation_user_specified_args<'tcx>( .opt_delegation_generics() .expect("Lowering delegation"); - let get_segment = |hir_id: HirId| -> (&'tcx PathSegment<'tcx>, DefId) { + let get_segment = |hir_id: HirId| -> Option<(&'tcx PathSegment<'tcx>, DefId)> { let segment = tcx.hir_node(hir_id).expect_path_segment(); - let def_id = segment.res.def_id(); - - (segment, def_id) + segment.res.opt_def_id().map(|def_id| (segment, def_id)) }; let ctx = ItemCtxt::new(tcx, delegation_id); let lowerer = ctx.lowerer(); - let parent_args = info.parent_args_segment_id.map(get_segment).map(|(segment, def_id)| { + let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { let self_ty = get_delegation_self_ty(tcx, delegation_id); lowerer @@ -598,7 +596,7 @@ fn get_delegation_user_specified_args<'tcx>( .as_slice() }); - let child_args = info.child_args_segment_id.map(get_segment).map(|(segment, def_id)| { + let child_args = info.child_args_segment_id.and_then(get_segment).map(|(segment, def_id)| { let parent_args = if let Some(parent_args) = parent_args { parent_args } else { diff --git a/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs b/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs new file mode 100644 index 0000000000000..431184923887d --- /dev/null +++ b/tests/ui/delegation/generics/unresolved-segment-ice-153389.rs @@ -0,0 +1,13 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait{ + fn bar(); +} + +impl Trait for () { + reuse missing::<> as bar; + //~^ ERROR: cannot find function `missing` in this scope +} + +fn main() {} diff --git a/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr b/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr new file mode 100644 index 0000000000000..b69917117fce9 --- /dev/null +++ b/tests/ui/delegation/generics/unresolved-segment-ice-153389.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find function `missing` in this scope + --> $DIR/unresolved-segment-ice-153389.rs:9:11 + | +LL | reuse missing::<> as bar; + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From f352e743b14cfd74fe46fc0d5f6dd193b56d427c Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Thu, 5 Mar 2026 10:59:18 +0000 Subject: [PATCH 7/7] Use shlex instead of shell-words --- Cargo.lock | 8 +------- compiler/rustc_llvm/Cargo.toml | 2 +- compiler/rustc_llvm/build.rs | 32 +++++++++++++++++++++----------- src/tools/tidy/src/deps.rs | 1 - 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45020437fd903..d9fd6e5d8be9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4121,7 +4121,7 @@ version = "0.0.0" dependencies = [ "cc", "libc", - "shell-words", + "shlex", ] [[package]] @@ -5116,12 +5116,6 @@ 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" diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index b618bc199d885..c9f8cd9495834 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -12,7 +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" +shlex = "1.3.0" # tidy-alphabetical-end [features] diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 45d5bbd020f43..38c16fb1cd6d5 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -5,7 +5,8 @@ use std::fmt::Display; use std::path::{Path, PathBuf}; use std::process::{Command, Output, Stdio}; use std::str::SplitWhitespace; -use std::vec::IntoIter; + +use shlex::Shlex; const OPTIONAL_COMPONENTS: &[&str] = &[ "x86", @@ -121,9 +122,8 @@ enum LlvmConfigOutput { UnquotedPaths(String), } -#[derive(Clone)] enum SplitLlvmConfigOutput<'a> { - QuotedPaths(IntoIter), + QuotedPaths(Shlex<'a>), UnquotedPaths(SplitWhitespace<'a>), } @@ -137,14 +137,22 @@ impl<'a> Iterator for SplitLlvmConfigOutput<'a> { } } +impl Drop for SplitLlvmConfigOutput<'_> { + fn drop(&mut self) { + if let Self::QuotedPaths(shlex) = self { + assert!(!shlex.had_error, "error parsing llvm-config output"); + } + } +} + 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::QuotedPaths(output) => { + SplitLlvmConfigOutput::QuotedPaths(Shlex::new(output)) + } LlvmConfigOutput::UnquotedPaths(output) => { SplitLlvmConfigOutput::UnquotedPaths(output.split_whitespace()) } @@ -229,7 +237,6 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); let cxxflags = quoted_split(cmd); - let mut cxxflags_iter = cxxflags.into_iter(); let mut cfg = cc::Build::new(); cfg.warnings(false); @@ -242,7 +249,7 @@ fn main() { if std::env::var_os("CI").is_some() && !target.contains("msvc") { cfg.warnings_into_errors(true); } - for flag in cxxflags_iter.clone() { + for flag in &cxxflags { // Ignore flags like `-m64` when we're doing a cross build if is_crossed && flag.starts_with("-m") { continue; @@ -435,13 +442,16 @@ fn main() { // dependencies. let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS"); if let Some(s) = llvm_linker_flags { - for lib in shell_words::split(&s.into_string().unwrap()).expect("matched quotes") { + let linker_flags = s.into_string().unwrap(); + let mut shlex = Shlex::new(&linker_flags); + for lib in shlex.by_ref() { if let Some(stripped) = lib.strip_prefix("-l") { println!("cargo:rustc-link-lib={stripped}"); } else if let Some(stripped) = lib.strip_prefix("-L") { println!("cargo:rustc-link-search=native={stripped}"); } } + assert!(!shlex.had_error, "error parsing LLVM_LINKER_FLAGS"); } let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP"); @@ -476,7 +486,7 @@ fn main() { // C++ runtime library if !target.contains("msvc") { if let Some(s) = llvm_static_stdcpp { - assert!(cxxflags_iter.all(|flag| flag != "-stdlib=libc++")); + assert!(cxxflags.into_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") { @@ -484,7 +494,7 @@ fn main() { } else { println!("cargo:rustc-link-lib=static={stdcppname}"); } - } else if cxxflags_iter.any(|flag| flag == "-stdlib=libc++") { + } else if cxxflags.into_iter().any(|flag| flag == "-stdlib=libc++") { println!("cargo:rustc-link-lib=c++"); } else { println!("cargo:rustc-link-lib={stdcppname}"); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 220eadfdb9edd..9e9d463acdb3b 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -425,7 +425,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "sha1", "sha2", "sharded-slab", - "shell-words", "shlex", "simd-adler32", "smallvec",