Skip to content

Rollup of 7 pull requests #141331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e0421f8
replace `cc_detect::cc2ar` with `cc::try_get_archiver`
onur-ozkan May 14, 2025
5027ee2
bump bootstrap cc-rs to `1.2.23`
onur-ozkan May 16, 2025
fe0663c
Add test sugg-field-in-format-string-issue-141136
xizheyin May 18, 2025
9de7fff
Suggest use `"{}", self.x` instead of `{self.x}` when resolve `x` as …
xizheyin May 18, 2025
4ec9919
Add println! test for sugg-field-in-format-string-issue-141136
xizheyin May 20, 2025
37260e1
Allow trailing comma after argument in query definition
compiler-errors May 20, 2025
a3cf6f6
Add `std::os::unix::process::CommandExt::chroot` to safely chroot a c…
joshtriplett Feb 27, 2025
c3b750c
`CommandExt::chroot`: Document difference to underlying `chroot`
joshtriplett May 20, 2025
17fdf19
`CommandExt::chroot`: Add tracking issue
joshtriplett May 20, 2025
ed01a20
typeck: catch `continue`s pointing to blocks
dianne May 21, 2025
5c4eb87
add missing PATH
onur-ozkan May 19, 2025
348c1b0
Apply suggestions from code review
joshtriplett May 20, 2025
6ac8e51
Allow x perf to find rustc.exe on Windows
Sol-Ell May 21, 2025
84f67a5
Downgrade the confident of suggestion `available field in format stri…
xizheyin May 21, 2025
1cc0e38
Avoid creating an empty identifer in `Symbol::to_ident_string`.
nnethercote May 21, 2025
7b4f7a3
Rollup merge of #137759 - joshtriplett:command-chroot, r=Amanieu
matthiaskrgr May 21, 2025
64a5a66
Rollup merge of #140994 - onur-ozkan:cc2ar-removal, r=albertlarsan68
matthiaskrgr May 21, 2025
d30f047
Rollup merge of #141213 - xizheyin:issue-141136, r=nnethercote
matthiaskrgr May 21, 2025
04a7c2c
Rollup merge of #141283 - Sol-Ell:fix-benchmarking-on-windows, r=Kobzol
matthiaskrgr May 21, 2025
e4836fb
Rollup merge of #141284 - compiler-errors:query-nit, r=oli-obk
matthiaskrgr May 21, 2025
aaa684f
Rollup merge of #141317 - dianne:continue-liveness-ice-fix, r=compile…
matthiaskrgr May 21, 2025
5b150e3
Rollup merge of #141318 - nnethercote:fix-140884, r=compiler-errors
matthiaskrgr May 21, 2025
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
34 changes: 26 additions & 8 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,14 +532,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::Break(destination, ref expr_opt) => {
self.check_expr_break(destination, expr_opt.as_deref(), expr)
}
ExprKind::Continue(destination) => {
if destination.target_id.is_ok() {
tcx.types.never
} else {
// There was an error; make type-check fail.
Ty::new_misc_error(tcx)
}
}
ExprKind::Continue(destination) => self.check_expr_continue(destination, expr),
ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
ExprKind::Become(call) => self.check_expr_become(call, expr),
ExprKind::Let(let_expr) => self.check_expr_let(let_expr, expr.hir_id),
Expand Down Expand Up @@ -989,6 +982,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

fn check_expr_continue(
&self,
destination: hir::Destination,
expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> {
if let Ok(target_id) = destination.target_id {
if let hir::Node::Expr(hir::Expr { kind: ExprKind::Loop(..), .. }) =
self.tcx.hir_node(target_id)
{
self.tcx.types.never
} else {
// Liveness linting assumes `continue`s all point to loops. We'll report an error
// in `check_mod_loops`, but make sure we don't run liveness (#113379, #121623).
let guar = self.dcx().span_delayed_bug(
expr.span,
"found `continue` not pointing to loop, but no error reported",
);
Ty::new_error(self.tcx, guar)
}
} else {
// There was an error; make type-check fail.
Ty::new_misc_error(self.tcx)
}
}

fn check_expr_return(
&self,
expr_opt: Option<&'tcx hir::Expr<'tcx>>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl Parse for Query {
let key = Pat::parse_single(&arg_content)?;
arg_content.parse::<Token![:]>()?;
let arg = arg_content.parse()?;
let _ = arg_content.parse::<Option<Token![,]>>()?;
let result = input.parse()?;

// Parse the query modifiers
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_build/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
}
};

// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
// Checking liveness after building the THIR ensures there were no typeck errors.
//
// maybe move the check to a MIR pass?
tcx.ensure_ok().check_liveness(def);
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ enum LiveNodeKind {
VarDefNode(Span, HirId),
ClosureNode,
ExitNode,
ErrNode,
}

fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
Expand All @@ -133,7 +132,6 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
VarDefNode(s, _) => format!("Var def node [{}]", sm.span_to_diagnostic_string(s)),
ClosureNode => "Closure node".to_owned(),
ExitNode => "Exit node".to_owned(),
ErrNode => "Error node".to_owned(),
}
}

Expand Down Expand Up @@ -492,6 +490,9 @@ struct Liveness<'a, 'tcx> {
impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn new(ir: &'a mut IrMaps<'tcx>, body_owner: LocalDefId) -> Liveness<'a, 'tcx> {
let typeck_results = ir.tcx.typeck(body_owner);
// Liveness linting runs after building the THIR. We make several assumptions based on
// typeck succeeding, e.g. that breaks and continues are well-formed.
assert!(typeck_results.tainted_by_errors.is_none());
// FIXME(#132279): we're in a body here.
let typing_env = ty::TypingEnv::non_body_analysis(ir.tcx, body_owner);
let closure_min_captures = typeck_results.closure_min_captures.get(&body_owner);
Expand Down Expand Up @@ -976,8 +977,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// Now that we know the label we're going to,
// look it up in the continue loop nodes table
self.cont_ln.get(&sc).cloned().unwrap_or_else(|| {
self.ir.tcx.dcx().span_delayed_bug(expr.span, "continue to unknown label");
self.ir.add_live_node(ErrNode)
// Liveness linting happens after building the THIR. Bad labels should already
// have been caught.
span_bug!(expr.span, "continue to unknown label");
})
}

Expand Down
24 changes: 18 additions & 6 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,12 +765,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
match candidate {
AssocSuggestion::Field(field_span) => {
if self_is_available {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"you might have meant to use the available field",
format!("{pre}self."),
Applicability::MachineApplicable,
);
let source_map = self.r.tcx.sess.source_map();
// check if the field is used in a format string, such as `"{x}"`
let field_is_format_named_arg = source_map
.span_to_source(span, |s, start, _| {
Ok(s.get(start - 1..start) == Some("{"))
});
if let Ok(true) = field_is_format_named_arg {
err.help(
format!("you might have meant to use the available field in a format string: `\"{{}}\", self.{}`", segment.ident.name),
);
} else {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"you might have meant to use the available field",
format!("{pre}self."),
Applicability::MaybeIncorrect,
);
}
} else {
err.span_label(field_span, "a field by that name exists in `Self`");
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2592,7 +2592,8 @@ impl Symbol {
/// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
/// or edition, so we have to guess the rawness using the global edition.
pub fn to_ident_string(self) -> String {
Ident::with_dummy_span(self).to_string()
// Avoid creating an empty identifier, because that asserts in debug builds.
if self == kw::Empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
}
}

Expand Down
18 changes: 18 additions & 0 deletions library/std/src/os/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use cfg_if::cfg_if;

use crate::ffi::OsStr;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::path::Path;
use crate::sealed::Sealed;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
use crate::{io, process, sys};
Expand Down Expand Up @@ -197,6 +198,18 @@ pub trait CommandExt: Sealed {
/// ```
#[stable(feature = "process_set_process_group", since = "1.64.0")]
fn process_group(&mut self, pgroup: i32) -> &mut process::Command;

/// Set the root of the child process. This calls `chroot` in the child process before executing
/// the command.
///
/// This happens before changing to the directory specified with
/// [`process::Command::current_dir`], and that directory will be relative to the new root.
///
/// If no directory has been specified with [`process::Command::current_dir`], this will set the
/// directory to `/`, to avoid leaving the current directory outside the chroot. (This is an
/// intentional difference from the underlying `chroot` system call.)
#[unstable(feature = "process_chroot", issue = "141298")]
fn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut process::Command;
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -242,6 +255,11 @@ impl CommandExt for process::Command {
self.as_inner_mut().pgroup(pgroup);
self
}

fn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut process::Command {
self.as_inner_mut().chroot(dir.as_ref());
self
}
}

/// Unix-specific extensions to [`process::ExitStatus`] and
Expand Down
13 changes: 13 additions & 0 deletions library/std/src/sys/process/unix/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct Command {

program_kind: ProgramKind,
cwd: Option<CString>,
chroot: Option<CString>,
uid: Option<uid_t>,
gid: Option<gid_t>,
saw_nul: bool,
Expand Down Expand Up @@ -182,6 +183,7 @@ impl Command {
program_kind,
env: Default::default(),
cwd: None,
chroot: None,
uid: None,
gid: None,
saw_nul,
Expand All @@ -206,6 +208,7 @@ impl Command {
program_kind,
env: Default::default(),
cwd: None,
chroot: None,
uid: None,
gid: None,
saw_nul,
Expand Down Expand Up @@ -254,6 +257,12 @@ impl Command {
pub fn pgroup(&mut self, pgroup: pid_t) {
self.pgroup = Some(pgroup);
}
pub fn chroot(&mut self, dir: &Path) {
self.chroot = Some(os2c(dir.as_os_str(), &mut self.saw_nul));
if self.cwd.is_none() {
self.cwd(&OsStr::new("/"));
}
}

#[cfg(target_os = "linux")]
pub fn create_pidfd(&mut self, val: bool) {
Expand Down Expand Up @@ -326,6 +335,10 @@ impl Command {
pub fn get_pgroup(&self) -> Option<pid_t> {
self.pgroup
}
#[allow(dead_code)]
pub fn get_chroot(&self) -> Option<&CStr> {
self.chroot.as_deref()
}

pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
&mut self.closures
Expand Down
10 changes: 10 additions & 0 deletions library/std/src/sys/process/unix/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,15 @@ impl Command {
cvt(libc::setuid(u as uid_t))?;
}
}
if let Some(chroot) = self.get_chroot() {
#[cfg(not(target_os = "fuchsia"))]
cvt(libc::chroot(chroot.as_ptr()))?;
#[cfg(target_os = "fuchsia")]
return Err(io::const_error!(
io::ErrorKind::Unsupported,
"chroot not supported by fuchsia"
));
}
if let Some(cwd) = self.get_cwd() {
cvt(libc::chdir(cwd.as_ptr()))?;
}
Expand Down Expand Up @@ -447,6 +456,7 @@ impl Command {
|| (self.env_saw_path() && !self.program_is_path())
|| !self.get_closures().is_empty()
|| self.get_groups().is_some()
|| self.get_chroot().is_some()
{
return Ok(None);
}
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/sys/process/unix/vxworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ impl Command {
"nul byte found in provided data",
));
}
if self.get_chroot().is_some() {
return Err(io::const_error!(
ErrorKind::Unsupported,
"chroot not supported by vxworks",
));
}
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
let mut p = Process { pid: 0, status: None };

Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ dependencies = [

[[package]]
name = "cc"
version = "1.2.17"
version = "1.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766"
dependencies = [
"shlex",
]
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ test = false
# Most of the time updating these dependencies requires modifications to the
# bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
# otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
cc = "=1.2.17"
cc = "=1.2.23"
cmake = "=0.1.54"

build_helper = { path = "../build_helper" }
Expand Down
6 changes: 5 additions & 1 deletion src/bootstrap/src/core/build_steps/perf.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::env::consts::EXE_EXTENSION;
use std::fmt::{Display, Formatter};

use crate::core::build_steps::compile::{Std, Sysroot};
Expand Down Expand Up @@ -160,7 +161,10 @@ Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#);
}

let sysroot = builder.ensure(Sysroot::new(compiler));
let rustc = sysroot.join("bin/rustc");
let mut rustc = sysroot.clone();
rustc.push("bin");
rustc.push("rustc");
rustc.set_extension(EXE_EXTENSION);

let rustc_perf_dir = builder.build.tempdir().join("rustc-perf");
let results_dir = rustc_perf_dir.join("results");
Expand Down
34 changes: 2 additions & 32 deletions src/bootstrap/src/utils/cc_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,13 @@
//! everything.

use std::collections::HashSet;
use std::iter;
use std::path::{Path, PathBuf};
use std::{env, iter};

use crate::core::config::TargetSelection;
use crate::utils::exec::{BootstrapCommand, command};
use crate::{Build, CLang, GitRepo};

/// Finds archiver tool for the given target if possible.
/// FIXME(onur-ozkan): This logic should be replaced by calling into the `cc` crate.
fn cc2ar(cc: &Path, target: TargetSelection, default_ar: PathBuf) -> Option<PathBuf> {
if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace('-', "_"))) {
Some(PathBuf::from(ar))
} else if let Some(ar) = env::var_os("AR") {
Some(PathBuf::from(ar))
} else if target.is_msvc() {
None
} else if target.contains("musl") || target.contains("openbsd") {
Some(PathBuf::from("ar"))
} else if target.contains("vxworks") {
Some(PathBuf::from("wr-ar"))
} else if target.contains("-nto-") {
if target.starts_with("i586") {
Some(PathBuf::from("ntox86-ar"))
} else if target.starts_with("aarch64") {
Some(PathBuf::from("ntoaarch64-ar"))
} else if target.starts_with("x86_64") {
Some(PathBuf::from("ntox86_64-ar"))
} else {
panic!("Unknown architecture, cannot determine archiver for Neutrino QNX");
}
} else if target.contains("android") || target.contains("-wasi") {
Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
} else {
Some(default_ar)
}
}

/// Creates and configures a new [`cc::Build`] instance for the given target.
fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
let mut cfg = cc::Build::new();
Expand Down Expand Up @@ -140,7 +110,7 @@ pub fn find_target(build: &Build, target: TargetSelection) {
let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) {
ar
} else {
cc2ar(compiler.path(), target, PathBuf::from(cfg.get_archiver().get_program()))
cfg.try_get_archiver().map(|c| PathBuf::from(c.get_program())).ok()
};

build.cc.borrow_mut().insert(target, compiler.clone());
Expand Down
Loading