Skip to content

Commit c43786c

Browse files
committed
Auto merge of rust-lang#141331 - matthiaskrgr:rollup-k0loxj6, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#137759 (Add `std::os::unix::process::CommandExt::chroot` to safely chroot a child process) - rust-lang#140994 (replace `cc_detect::cc2ar` with `cc::try_get_archiver`) - rust-lang#141213 (Suggest use "{}", self.x instead of {self.x} when resolve x as field of `self`) - rust-lang#141283 (Allow `x perf` to find rustc.exe on Windows) - rust-lang#141284 (Allow trailing comma after argument in query definition) - rust-lang#141317 (typeck: catch `continue`s pointing to blocks) - rust-lang#141318 (Avoid creating an empty identifer in `Symbol::to_ident_string`.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents bbd3a5a + 5b150e3 commit c43786c

29 files changed

+277
-201
lines changed

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,14 +532,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
532532
ExprKind::Break(destination, ref expr_opt) => {
533533
self.check_expr_break(destination, expr_opt.as_deref(), expr)
534534
}
535-
ExprKind::Continue(destination) => {
536-
if destination.target_id.is_ok() {
537-
tcx.types.never
538-
} else {
539-
// There was an error; make type-check fail.
540-
Ty::new_misc_error(tcx)
541-
}
542-
}
535+
ExprKind::Continue(destination) => self.check_expr_continue(destination, expr),
543536
ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
544537
ExprKind::Become(call) => self.check_expr_become(call, expr),
545538
ExprKind::Let(let_expr) => self.check_expr_let(let_expr, expr.hir_id),
@@ -989,6 +982,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
989982
}
990983
}
991984

985+
fn check_expr_continue(
986+
&self,
987+
destination: hir::Destination,
988+
expr: &'tcx hir::Expr<'tcx>,
989+
) -> Ty<'tcx> {
990+
if let Ok(target_id) = destination.target_id {
991+
if let hir::Node::Expr(hir::Expr { kind: ExprKind::Loop(..), .. }) =
992+
self.tcx.hir_node(target_id)
993+
{
994+
self.tcx.types.never
995+
} else {
996+
// Liveness linting assumes `continue`s all point to loops. We'll report an error
997+
// in `check_mod_loops`, but make sure we don't run liveness (#113379, #121623).
998+
let guar = self.dcx().span_delayed_bug(
999+
expr.span,
1000+
"found `continue` not pointing to loop, but no error reported",
1001+
);
1002+
Ty::new_error(self.tcx, guar)
1003+
}
1004+
} else {
1005+
// There was an error; make type-check fail.
1006+
Ty::new_misc_error(self.tcx)
1007+
}
1008+
}
1009+
9921010
fn check_expr_return(
9931011
&self,
9941012
expr_opt: Option<&'tcx hir::Expr<'tcx>>,

compiler/rustc_macros/src/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl Parse for Query {
5151
let key = Pat::parse_single(&arg_content)?;
5252
arg_content.parse::<Token![:]>()?;
5353
let arg = arg_content.parse()?;
54+
let _ = arg_content.parse::<Option<Token![,]>>()?;
5455
let result = input.parse()?;
5556

5657
// Parse the query modifiers

compiler/rustc_mir_build/src/builder/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
6666
}
6767
};
6868

69-
// this must run before MIR dump, because
70-
// "not all control paths return a value" is reported here.
69+
// Checking liveness after building the THIR ensures there were no typeck errors.
7170
//
7271
// maybe move the check to a MIR pass?
7372
tcx.ensure_ok().check_liveness(def);

compiler/rustc_passes/src/liveness.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ enum LiveNodeKind {
122122
VarDefNode(Span, HirId),
123123
ClosureNode,
124124
ExitNode,
125-
ErrNode,
126125
}
127126

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

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

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,12 +765,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
765765
match candidate {
766766
AssocSuggestion::Field(field_span) => {
767767
if self_is_available {
768-
err.span_suggestion_verbose(
769-
span.shrink_to_lo(),
770-
"you might have meant to use the available field",
771-
format!("{pre}self."),
772-
Applicability::MachineApplicable,
773-
);
768+
let source_map = self.r.tcx.sess.source_map();
769+
// check if the field is used in a format string, such as `"{x}"`
770+
let field_is_format_named_arg = source_map
771+
.span_to_source(span, |s, start, _| {
772+
Ok(s.get(start - 1..start) == Some("{"))
773+
});
774+
if let Ok(true) = field_is_format_named_arg {
775+
err.help(
776+
format!("you might have meant to use the available field in a format string: `\"{{}}\", self.{}`", segment.ident.name),
777+
);
778+
} else {
779+
err.span_suggestion_verbose(
780+
span.shrink_to_lo(),
781+
"you might have meant to use the available field",
782+
format!("{pre}self."),
783+
Applicability::MaybeIncorrect,
784+
);
785+
}
774786
} else {
775787
err.span_label(field_span, "a field by that name exists in `Self`");
776788
}

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2592,7 +2592,8 @@ impl Symbol {
25922592
/// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
25932593
/// or edition, so we have to guess the rawness using the global edition.
25942594
pub fn to_ident_string(self) -> String {
2595-
Ident::with_dummy_span(self).to_string()
2595+
// Avoid creating an empty identifier, because that asserts in debug builds.
2596+
if self == kw::Empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
25962597
}
25972598
}
25982599

library/std/src/os/unix/process.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use cfg_if::cfg_if;
88

99
use crate::ffi::OsStr;
1010
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
11+
use crate::path::Path;
1112
use crate::sealed::Sealed;
1213
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
1314
use crate::{io, process, sys};
@@ -197,6 +198,18 @@ pub trait CommandExt: Sealed {
197198
/// ```
198199
#[stable(feature = "process_set_process_group", since = "1.64.0")]
199200
fn process_group(&mut self, pgroup: i32) -> &mut process::Command;
201+
202+
/// Set the root of the child process. This calls `chroot` in the child process before executing
203+
/// the command.
204+
///
205+
/// This happens before changing to the directory specified with
206+
/// [`process::Command::current_dir`], and that directory will be relative to the new root.
207+
///
208+
/// If no directory has been specified with [`process::Command::current_dir`], this will set the
209+
/// directory to `/`, to avoid leaving the current directory outside the chroot. (This is an
210+
/// intentional difference from the underlying `chroot` system call.)
211+
#[unstable(feature = "process_chroot", issue = "141298")]
212+
fn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut process::Command;
200213
}
201214

202215
#[stable(feature = "rust1", since = "1.0.0")]
@@ -242,6 +255,11 @@ impl CommandExt for process::Command {
242255
self.as_inner_mut().pgroup(pgroup);
243256
self
244257
}
258+
259+
fn chroot<P: AsRef<Path>>(&mut self, dir: P) -> &mut process::Command {
260+
self.as_inner_mut().chroot(dir.as_ref());
261+
self
262+
}
245263
}
246264

247265
/// Unix-specific extensions to [`process::ExitStatus`] and

library/std/src/sys/process/unix/common.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub struct Command {
8888

8989
program_kind: ProgramKind,
9090
cwd: Option<CString>,
91+
chroot: Option<CString>,
9192
uid: Option<uid_t>,
9293
gid: Option<gid_t>,
9394
saw_nul: bool,
@@ -182,6 +183,7 @@ impl Command {
182183
program_kind,
183184
env: Default::default(),
184185
cwd: None,
186+
chroot: None,
185187
uid: None,
186188
gid: None,
187189
saw_nul,
@@ -206,6 +208,7 @@ impl Command {
206208
program_kind,
207209
env: Default::default(),
208210
cwd: None,
211+
chroot: None,
209212
uid: None,
210213
gid: None,
211214
saw_nul,
@@ -254,6 +257,12 @@ impl Command {
254257
pub fn pgroup(&mut self, pgroup: pid_t) {
255258
self.pgroup = Some(pgroup);
256259
}
260+
pub fn chroot(&mut self, dir: &Path) {
261+
self.chroot = Some(os2c(dir.as_os_str(), &mut self.saw_nul));
262+
if self.cwd.is_none() {
263+
self.cwd(&OsStr::new("/"));
264+
}
265+
}
257266

258267
#[cfg(target_os = "linux")]
259268
pub fn create_pidfd(&mut self, val: bool) {
@@ -326,6 +335,10 @@ impl Command {
326335
pub fn get_pgroup(&self) -> Option<pid_t> {
327336
self.pgroup
328337
}
338+
#[allow(dead_code)]
339+
pub fn get_chroot(&self) -> Option<&CStr> {
340+
self.chroot.as_deref()
341+
}
329342

330343
pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
331344
&mut self.closures

library/std/src/sys/process/unix/unix.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,15 @@ impl Command {
323323
cvt(libc::setuid(u as uid_t))?;
324324
}
325325
}
326+
if let Some(chroot) = self.get_chroot() {
327+
#[cfg(not(target_os = "fuchsia"))]
328+
cvt(libc::chroot(chroot.as_ptr()))?;
329+
#[cfg(target_os = "fuchsia")]
330+
return Err(io::const_error!(
331+
io::ErrorKind::Unsupported,
332+
"chroot not supported by fuchsia"
333+
));
334+
}
326335
if let Some(cwd) = self.get_cwd() {
327336
cvt(libc::chdir(cwd.as_ptr()))?;
328337
}
@@ -447,6 +456,7 @@ impl Command {
447456
|| (self.env_saw_path() && !self.program_is_path())
448457
|| !self.get_closures().is_empty()
449458
|| self.get_groups().is_some()
459+
|| self.get_chroot().is_some()
450460
{
451461
return Ok(None);
452462
}

library/std/src/sys/process/unix/vxworks.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ impl Command {
2727
"nul byte found in provided data",
2828
));
2929
}
30+
if self.get_chroot().is_some() {
31+
return Err(io::const_error!(
32+
ErrorKind::Unsupported,
33+
"chroot not supported by vxworks",
34+
));
35+
}
3036
let (ours, theirs) = self.setup_io(default, needs_stdin)?;
3137
let mut p = Process { pid: 0, status: None };
3238

src/bootstrap/Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ dependencies = [
8989

9090
[[package]]
9191
name = "cc"
92-
version = "1.2.17"
92+
version = "1.2.23"
9393
source = "registry+https://github.com/rust-lang/crates.io-index"
94-
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
94+
checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766"
9595
dependencies = [
9696
"shlex",
9797
]

src/bootstrap/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ test = false
3232
# Most of the time updating these dependencies requires modifications to the
3333
# bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
3434
# otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
35-
cc = "=1.2.17"
35+
cc = "=1.2.23"
3636
cmake = "=0.1.54"
3737

3838
build_helper = { path = "../build_helper" }

src/bootstrap/src/core/build_steps/perf.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::env::consts::EXE_EXTENSION;
12
use std::fmt::{Display, Formatter};
23

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

162163
let sysroot = builder.ensure(Sysroot::new(compiler));
163-
let rustc = sysroot.join("bin/rustc");
164+
let mut rustc = sysroot.clone();
165+
rustc.push("bin");
166+
rustc.push("rustc");
167+
rustc.set_extension(EXE_EXTENSION);
164168

165169
let rustc_perf_dir = builder.build.tempdir().join("rustc-perf");
166170
let results_dir = rustc_perf_dir.join("results");

src/bootstrap/src/utils/cc_detect.rs

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,13 @@
2222
//! everything.
2323
2424
use std::collections::HashSet;
25+
use std::iter;
2526
use std::path::{Path, PathBuf};
26-
use std::{env, iter};
2727

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

32-
/// Finds archiver tool for the given target if possible.
33-
/// FIXME(onur-ozkan): This logic should be replaced by calling into the `cc` crate.
34-
fn cc2ar(cc: &Path, target: TargetSelection, default_ar: PathBuf) -> Option<PathBuf> {
35-
if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace('-', "_"))) {
36-
Some(PathBuf::from(ar))
37-
} else if let Some(ar) = env::var_os("AR") {
38-
Some(PathBuf::from(ar))
39-
} else if target.is_msvc() {
40-
None
41-
} else if target.contains("musl") || target.contains("openbsd") {
42-
Some(PathBuf::from("ar"))
43-
} else if target.contains("vxworks") {
44-
Some(PathBuf::from("wr-ar"))
45-
} else if target.contains("-nto-") {
46-
if target.starts_with("i586") {
47-
Some(PathBuf::from("ntox86-ar"))
48-
} else if target.starts_with("aarch64") {
49-
Some(PathBuf::from("ntoaarch64-ar"))
50-
} else if target.starts_with("x86_64") {
51-
Some(PathBuf::from("ntox86_64-ar"))
52-
} else {
53-
panic!("Unknown architecture, cannot determine archiver for Neutrino QNX");
54-
}
55-
} else if target.contains("android") || target.contains("-wasi") {
56-
Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
57-
} else {
58-
Some(default_ar)
59-
}
60-
}
61-
6232
/// Creates and configures a new [`cc::Build`] instance for the given target.
6333
fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
6434
let mut cfg = cc::Build::new();
@@ -140,7 +110,7 @@ pub fn find_target(build: &Build, target: TargetSelection) {
140110
let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) {
141111
ar
142112
} else {
143-
cc2ar(compiler.path(), target, PathBuf::from(cfg.get_archiver().get_program()))
113+
cfg.try_get_archiver().map(|c| PathBuf::from(c.get_program())).ok()
144114
};
145115

146116
build.cc.borrow_mut().insert(target, compiler.clone());

0 commit comments

Comments
 (0)