Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c43786c

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

File tree

29 files changed

+277
-201
lines changed

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

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /