Skip to content

Commit c79bbfa

Browse files
committed
Auto merge of rust-lang#141066 - matthiaskrgr:rollup-e7tyrj5, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#140791 (std: explain prefer `TryInto` over `TryFrom` when specifying traits bounds on generic function) - rust-lang#140834 (move (or remove) some impl Trait tests) - rust-lang#140910 (Remove `stable` attribute from wasi fs (read_exact|write_all)_at) - rust-lang#140984 (fix doc for UnixStream) - rust-lang#140997 (Add negative test coverage for `-Clink-self-contained` and `-Zlinker-features`) - rust-lang#141003 (Improve ternary operator recovery) - rust-lang#141009 (Migrate to modern datetime API) - rust-lang#141013 (Implement methods to set STARTUPINFO flags for Command API on Windows) - rust-lang#141026 (rustc-dev-guide subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7e19eef + 5ce27f5 commit c79bbfa

File tree

110 files changed

+461
-259
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+461
-259
lines changed

compiler/rustc_parse/messages.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,6 @@ parse_switch_ref_box_order = switch the order of `ref` and `box`
815815
.suggestion = swap them
816816
817817
parse_ternary_operator = Rust has no ternary operator
818-
.help = use an `if-else` expression instead
819818
820819
parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
821820
.suggestion = use `!` to perform bitwise not
@@ -963,6 +962,8 @@ parse_use_empty_block_not_semi = expected { "`{}`" }, found `;`
963962
parse_use_eq_instead = unexpected `==`
964963
.suggestion = try using `=` instead
965964
965+
parse_use_if_else = use an `if-else` expression instead
966+
966967
parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
967968
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable
968969

compiler/rustc_parse/src/errors.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,28 @@ pub(crate) enum IfExpressionMissingThenBlockSub {
436436

437437
#[derive(Diagnostic)]
438438
#[diag(parse_ternary_operator)]
439-
#[help]
440439
pub(crate) struct TernaryOperator {
441440
#[primary_span]
442441
pub span: Span,
442+
/// If we have a span for the condition expression, suggest the if/else
443+
#[subdiagnostic]
444+
pub sugg: Option<TernaryOperatorSuggestion>,
445+
/// Otherwise, just print the suggestion message
446+
#[help(parse_use_if_else)]
447+
pub no_sugg: bool,
448+
}
449+
450+
#[derive(Subdiagnostic, Copy, Clone)]
451+
#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")]
452+
pub(crate) struct TernaryOperatorSuggestion {
453+
#[suggestion_part(code = "if ")]
454+
pub before_cond: Span,
455+
#[suggestion_part(code = "{{")]
456+
pub question: Span,
457+
#[suggestion_part(code = "}} else {{")]
458+
pub colon: Span,
459+
#[suggestion_part(code = " }}")]
460+
pub end: Span,
443461
}
444462

445463
#[derive(Subdiagnostic)]

compiler/rustc_parse/src/parser/diagnostics.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ use crate::errors::{
4141
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody,
4242
QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
4343
StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
44-
TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
45-
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
44+
TernaryOperator, TernaryOperatorSuggestion, UnexpectedConstInGenericParam,
45+
UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
46+
UseEqInstead, WrapType,
4647
};
4748
use crate::parser::attr::InnerAttrPolicy;
4849
use crate::{exp, fluent_generated as fluent};
@@ -497,7 +498,7 @@ impl<'a> Parser<'a> {
497498
// If the user is trying to write a ternary expression, recover it and
498499
// return an Err to prevent a cascade of irrelevant diagnostics.
499500
if self.prev_token == token::Question
500-
&& let Err(e) = self.maybe_recover_from_ternary_operator()
501+
&& let Err(e) = self.maybe_recover_from_ternary_operator(None)
501502
{
502503
return Err(e);
503504
}
@@ -1602,12 +1603,18 @@ impl<'a> Parser<'a> {
16021603
/// Rust has no ternary operator (`cond ? then : else`). Parse it and try
16031604
/// to recover from it if `then` and `else` are valid expressions. Returns
16041605
/// an err if this appears to be a ternary expression.
1605-
pub(super) fn maybe_recover_from_ternary_operator(&mut self) -> PResult<'a, ()> {
1606+
/// If we have the span of the condition, we can provide a better error span
1607+
/// and code suggestion.
1608+
pub(super) fn maybe_recover_from_ternary_operator(
1609+
&mut self,
1610+
cond: Option<Span>,
1611+
) -> PResult<'a, ()> {
16061612
if self.prev_token != token::Question {
16071613
return PResult::Ok(());
16081614
}
16091615

1610-
let lo = self.prev_token.span.lo();
1616+
let question = self.prev_token.span;
1617+
let lo = cond.unwrap_or(question).lo();
16111618
let snapshot = self.create_snapshot_for_diagnostic();
16121619

16131620
if match self.parse_expr() {
@@ -1620,11 +1627,20 @@ impl<'a> Parser<'a> {
16201627
}
16211628
} {
16221629
if self.eat_noexpect(&token::Colon) {
1630+
let colon = self.prev_token.span;
16231631
match self.parse_expr() {
1624-
Ok(_) => {
1625-
return Err(self
1626-
.dcx()
1627-
.create_err(TernaryOperator { span: self.token.span.with_lo(lo) }));
1632+
Ok(expr) => {
1633+
let sugg = cond.map(|cond| TernaryOperatorSuggestion {
1634+
before_cond: cond.shrink_to_lo(),
1635+
question,
1636+
colon,
1637+
end: expr.span.shrink_to_hi(),
1638+
});
1639+
return Err(self.dcx().create_err(TernaryOperator {
1640+
span: self.prev_token.span.with_lo(lo),
1641+
sugg,
1642+
no_sugg: sugg.is_none(),
1643+
}));
16281644
}
16291645
Err(err) => {
16301646
err.cancel();

compiler/rustc_parse/src/parser/stmt.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,12 @@ impl<'a> Parser<'a> {
879879
{
880880
// Just check for errors and recover; do not eat semicolon yet.
881881

882-
let expect_result = self.expect_one_of(&[], &[exp!(Semi), exp!(CloseBrace)]);
882+
let expect_result =
883+
if let Err(e) = self.maybe_recover_from_ternary_operator(Some(expr.span)) {
884+
Err(e)
885+
} else {
886+
self.expect_one_of(&[], &[exp!(Semi), exp!(CloseBrace)])
887+
};
883888

884889
// Try to both emit a better diagnostic, and avoid further errors by replacing
885890
// the `expr` with `ExprKind::Err`.

library/core/src/convert/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ pub trait Into<T>: Sized {
464464
/// orphaning rules.
465465
/// See [`Into`] for more details.
466466
///
467-
/// Prefer using [`Into`] over using `From` when specifying trait bounds on a generic function.
468-
/// This way, types that directly implement [`Into`] can be used as arguments as well.
467+
/// Prefer using [`Into`] over [`From`] when specifying trait bounds on a generic function
468+
/// to ensure that types that only implement [`Into`] can be used as well.
469469
///
470470
/// The `From` trait is also very useful when performing error handling. When constructing a function
471471
/// that is capable of failing, the return type will generally be of the form `Result<T, E>`.
@@ -597,6 +597,9 @@ pub trait From<T>: Sized {
597597
/// standard library. For more information on this, see the
598598
/// documentation for [`Into`].
599599
///
600+
/// Prefer using [`TryInto`] over [`TryFrom`] when specifying trait bounds on a generic function
601+
/// to ensure that types that only implement [`TryInto`] can be used as well.
602+
///
600603
/// # Implementing `TryInto`
601604
///
602605
/// This suffers the same restrictions and reasoning as implementing
@@ -636,6 +639,9 @@ pub trait TryInto<T>: Sized {
636639
/// When the [`!`] type is stabilized [`Infallible`] and [`!`] will be
637640
/// equivalent.
638641
///
642+
/// Prefer using [`TryInto`] over [`TryFrom`] when specifying trait bounds on a generic function
643+
/// to ensure that types that only implement [`TryInto`] can be used as well.
644+
///
639645
/// `TryFrom<T>` can be implemented as follows:
640646
///
641647
/// ```

library/std/src/os/unix/net/stream.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,11 @@ impl UnixStream {
307307
///
308308
/// ```no_run
309309
/// use std::io;
310-
/// use std::net::UdpSocket;
310+
/// use std::os::unix::net::UnixStream;
311311
/// use std::time::Duration;
312312
///
313313
/// fn main() -> std::io::Result<()> {
314-
/// let socket = UdpSocket::bind("127.0.0.1:34254")?;
314+
/// let socket = UnixStream::connect("/tmp/sock")?;
315315
/// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
316316
/// let err = result.unwrap_err();
317317
/// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);

library/std/src/os/wasi/fs.rs

-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ pub trait FileExt {
7272
/// If this function returns an error, it is unspecified how many bytes it
7373
/// has read, but it will never read more than would be necessary to
7474
/// completely fill the buffer.
75-
#[stable(feature = "rw_exact_all_at", since = "1.33.0")]
7675
fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
7776
while !buf.is_empty() {
7877
match self.read_at(buf, offset) {
@@ -144,7 +143,6 @@ pub trait FileExt {
144143
/// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
145144
///
146145
/// [`write_at`]: FileExt::write_at
147-
#[stable(feature = "rw_exact_all_at", since = "1.33.0")]
148146
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
149147
while !buf.is_empty() {
150148
match self.write_at(buf, offset) {

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

+36
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,27 @@ pub trait CommandExt: Sealed {
344344
&mut self,
345345
attribute_list: &ProcThreadAttributeList<'_>,
346346
) -> io::Result<process::Child>;
347+
348+
/// When true, sets the `STARTF_RUNFULLSCREEN` flag on the [STARTUPINFO][1] struct before passing it to `CreateProcess`.
349+
///
350+
/// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa
351+
#[unstable(feature = "windows_process_extensions_startupinfo", issue = "141010")]
352+
fn startupinfo_fullscreen(&mut self, enabled: bool) -> &mut process::Command;
353+
354+
/// When true, sets the `STARTF_UNTRUSTEDSOURCE` flag on the [STARTUPINFO][1] struct before passing it to `CreateProcess`.
355+
///
356+
/// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa
357+
#[unstable(feature = "windows_process_extensions_startupinfo", issue = "141010")]
358+
fn startupinfo_untrusted_source(&mut self, enabled: bool) -> &mut process::Command;
359+
360+
/// When specified, sets the following flags on the [STARTUPINFO][1] struct before passing it to `CreateProcess`:
361+
/// - If `Some(true)`, sets `STARTF_FORCEONFEEDBACK`
362+
/// - If `Some(false)`, sets `STARTF_FORCEOFFFEEDBACK`
363+
/// - If `None`, does not set any flags
364+
///
365+
/// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa
366+
#[unstable(feature = "windows_process_extensions_startupinfo", issue = "141010")]
367+
fn startupinfo_force_feedback(&mut self, enabled: Option<bool>) -> &mut process::Command;
347368
}
348369

349370
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
@@ -385,6 +406,21 @@ impl CommandExt for process::Command {
385406
.spawn_with_attributes(sys::process::Stdio::Inherit, true, Some(attribute_list))
386407
.map(process::Child::from_inner)
387408
}
409+
410+
fn startupinfo_fullscreen(&mut self, enabled: bool) -> &mut process::Command {
411+
self.as_inner_mut().startupinfo_fullscreen(enabled);
412+
self
413+
}
414+
415+
fn startupinfo_untrusted_source(&mut self, enabled: bool) -> &mut process::Command {
416+
self.as_inner_mut().startupinfo_untrusted_source(enabled);
417+
self
418+
}
419+
420+
fn startupinfo_force_feedback(&mut self, enabled: Option<bool>) -> &mut process::Command {
421+
self.as_inner_mut().startupinfo_force_feedback(enabled);
422+
self
423+
}
388424
}
389425

390426
#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]

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

+36
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ pub struct Command {
155155
stdout: Option<Stdio>,
156156
stderr: Option<Stdio>,
157157
force_quotes_enabled: bool,
158+
startupinfo_fullscreen: bool,
159+
startupinfo_untrusted_source: bool,
160+
startupinfo_force_feedback: Option<bool>,
158161
}
159162

160163
pub enum Stdio {
@@ -186,6 +189,9 @@ impl Command {
186189
stdout: None,
187190
stderr: None,
188191
force_quotes_enabled: false,
192+
startupinfo_fullscreen: false,
193+
startupinfo_untrusted_source: false,
194+
startupinfo_force_feedback: None,
189195
}
190196
}
191197

@@ -222,6 +228,18 @@ impl Command {
222228
self.args.push(Arg::Raw(command_str_to_append.to_os_string()))
223229
}
224230

231+
pub fn startupinfo_fullscreen(&mut self, enabled: bool) {
232+
self.startupinfo_fullscreen = enabled;
233+
}
234+
235+
pub fn startupinfo_untrusted_source(&mut self, enabled: bool) {
236+
self.startupinfo_untrusted_source = enabled;
237+
}
238+
239+
pub fn startupinfo_force_feedback(&mut self, enabled: Option<bool>) {
240+
self.startupinfo_force_feedback = enabled;
241+
}
242+
225243
pub fn get_program(&self) -> &OsStr {
226244
&self.program
227245
}
@@ -343,6 +361,24 @@ impl Command {
343361
si.wShowWindow = cmd_show;
344362
}
345363

364+
if self.startupinfo_fullscreen {
365+
si.dwFlags |= c::STARTF_RUNFULLSCREEN;
366+
}
367+
368+
if self.startupinfo_untrusted_source {
369+
si.dwFlags |= c::STARTF_UNTRUSTEDSOURCE;
370+
}
371+
372+
match self.startupinfo_force_feedback {
373+
Some(true) => {
374+
si.dwFlags |= c::STARTF_FORCEONFEEDBACK;
375+
}
376+
Some(false) => {
377+
si.dwFlags |= c::STARTF_FORCEOFFFEEDBACK;
378+
}
379+
None => {}
380+
}
381+
346382
let si_ptr: *mut c::STARTUPINFOW;
347383

348384
let mut si_ex;

src/ci/cpu-usage-over-time.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def idle_since(self, prev):
170170
while True:
171171
time.sleep(1)
172172
next_state = State()
173-
now = datetime.datetime.utcnow().isoformat()
173+
now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None).isoformat()
174174
idle = next_state.idle_since(cur_state)
175175
print("%s,%s" % (now, idle))
176176
sys.stdout.flush()

src/doc/rustc-dev-guide/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im
9191
3) Push the branch to your fork and create a PR into `rustc-dev-guide`
9292
9393
### Push changes from this repository into `rust-lang/rust`
94+
95+
NOTE: If you use Git protocol to push to your fork of `rust-lang/rust`,
96+
ensure that you have this entry in your Git config,
97+
else the 2 steps that follow would prompt for a username and password:
98+
99+
```
100+
101+
insteadOf = "https://github.com/"
102+
```
103+
94104
1) Run the push command to create a branch named `<branch-name>` in a `rustc` fork under the `<gh-username>` account
95105
```
96106
cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username>

0 commit comments

Comments
 (0)