Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
err.multipart_suggestion(
"consider moving the expression out of the loop so it is only moved once",
vec![
(parent.span, "value".to_string()),
(span.shrink_to_lo(), format!("let mut value = {value};{indent}")),
(parent.span, "value".to_string()),
],
Applicability::MaybeIncorrect,
);
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_data_structures/src/steal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ impl<T> Steal<T> {
let value = value_ref.take();
value.expect("attempt to steal from stolen value")
}

/// Writers of rustc drivers often encounter stealing issues. This function makes it possible to
/// handle these errors gracefully.
///
/// This should not be used within rustc as it leaks information not tracked
/// by the query system, breaking incremental compilation.
pub fn is_stolen(&self) -> bool {
self.value.borrow().is_none()
}
}

impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,8 +920,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
applicability: Applicability,
style: SuggestionStyle,
) -> &mut Self {
suggestion.sort_unstable();
suggestion.dedup_by(|(s1, m1), (s2, m2)| s1.source_equal(*s2) && m1 == m2);
let mut seen = crate::FxHashSet::default();
suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));

let parts = suggestion
.into_iter()
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
use rustc_span::{sym, Span, DUMMY_SP};
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
Expand Down Expand Up @@ -1140,8 +1140,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.get(arg_idx + 1)
.map(|&(_, sp)| sp)
.unwrap_or_else(|| {
// Subtract one to move before `)`
call_expr.span.with_lo(call_expr.span.hi() - BytePos(1))
// Try to move before `)`. Note that `)` here is not necessarily
// the latin right paren, it could be a Unicode-confusable that
// looks like a `)`, so we must not use `- BytePos(1)`
// manipulations here.
self.tcx().sess.source_map().end_point(call_expr.span)
});

// Include next comma
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,14 @@ impl<'a> Parser<'a> {
fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
let eq_consumed = match self.token.kind {
token::BinOpEq(..) => {
// Recover `let x <op>= 1` as `let x = 1`
// Recover `let x <op>= 1` as `let x = 1` We must not use `+ BytePos(1)` here
// because `<op>` can be a multi-byte lookalike that was recovered, e.g. `➖=` (the
// `➖` is a U+2796 Heavy Minus Sign Unicode Character) that was recovered as a
// `-=`.
let extra_op_span = self.psess.source_map().start_point(self.token.span);
self.dcx().emit_err(errors::CompoundAssignmentExpressionInLet {
span: self.token.span,
suggestion: self.token.span.with_hi(self.token.span.lo() + BytePos(1)),
suggestion: extra_op_span,
});
self.bump();
true
Expand Down
13 changes: 13 additions & 0 deletions library/std/src/sys/pal/unix/process/process_unix/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ fn exitstatus_display_tests() {
// The purpose of this test is to test our string formatting, not our understanding of the wait
// status magic numbers. So restrict these to Linux.
if cfg!(target_os = "linux") {
#[cfg(any(target_arch = "mips", target_arch = "mips64"))]
t(0x0137f, "stopped (not terminated) by signal: 19 (SIGPWR)");

#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
t(0x0137f, "stopped (not terminated) by signal: 19 (SIGCONT)");

#[cfg(not(any(
target_arch = "mips",
target_arch = "mips64",
target_arch = "sparc",
target_arch = "sparc64"
)))]
t(0x0137f, "stopped (not terminated) by signal: 19 (SIGSTOP)");

t(0x0ffff, "continued (WIFCONTINUED)");
}

Expand Down
19 changes: 14 additions & 5 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,8 @@ impl Build {
}

/// Execute a command and return its output.
/// This method should be used for all command executions in bootstrap.
/// Note: Ideally, you should use one of the BootstrapCommand::run* functions to
/// execute commands. They internally call this method.
#[track_caller]
fn run(
&self,
Expand Down Expand Up @@ -1057,20 +1058,28 @@ Executed at: {executed_at}"#,
CommandOutput::did_not_start(stdout, stderr)
}
};

let fail = |message: &str| {
if self.is_verbose() {
println!("{message}");
} else {
println!("Command has failed. Rerun with -v to see more details.");
}
exit!(1);
};

if !output.is_success() {
match command.failure_behavior {
BehaviorOnFailure::DelayFail => {
if self.fail_fast {
println!("{message}");
exit!(1);
fail(&message);
}

let mut failures = self.delayed_failures.borrow_mut();
failures.push(message);
}
BehaviorOnFailure::Exit => {
println!("{message}");
exit!(1);
fail(&message);
}
BehaviorOnFailure::Ignore => {
// If failures are allowed, either the error has been printed already
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/parser/suggest-remove-compount-assign-let-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Previously we would try to issue a suggestion for `let x <op>= 1`, i.e. a compound assignment
//! within a `let` binding, to remove the `<op>`. The suggestion code unfortunately incorrectly
//! assumed that the `<op>` is an exactly-1-byte ASCII character, but this assumption is incorrect
//! because we also recover Unicode-confusables like `➖=` as `-=`. In this example, the suggestion
//! code used a `+ BytePos(1)` to calculate the span of the `<op>` codepoint that looks like `-` but
//! the mult-byte Unicode look-alike would cause the suggested removal span to be inside a
//! multi-byte codepoint boundary, triggering a codepoint boundary assertion.
//!
//! issue: rust-lang/rust#128845

fn main() {
// Adapted from #128845 but with irrelevant components removed and simplified.
let x ➖= 1;
//~^ ERROR unknown start of token: \u{2796}
//~| ERROR: can't reassign to an uninitialized variable
}
26 changes: 26 additions & 0 deletions tests/ui/parser/suggest-remove-compount-assign-let-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: unknown start of token: \u{2796}
--> $DIR/suggest-remove-compount-assign-let-ice.rs:13:11
|
LL | let x ➖= 1;
| ^^
|
help: Unicode character '➖' (Heavy Minus Sign) looks like '-' (Minus/Hyphen), but it is not
|
LL | let x -= 1;
| ~

error: can't reassign to an uninitialized variable
--> $DIR/suggest-remove-compount-assign-let-ice.rs:13:11
|
LL | let x ➖= 1;
| ^^^
|
= help: if you meant to overwrite, remove the `let` binding
help: initialize the variable
|
LL - let x ➖= 1;
LL + let x = 1;
|

error: aborting due to 2 previous errors

19 changes: 19 additions & 0 deletions tests/ui/typeck/suggest-arg-comma-delete-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//! Previously, we tried to remove extra arg commas when providing extra arg removal suggestions.
//! One of the edge cases is having to account for an arg that has a closing delimiter `)`
//! following it. However, the previous suggestion code assumed that the delimiter is in fact
//! exactly the 1-byte `)` character. This assumption was proven incorrect, because we recover
//! from Unicode-confusable delimiters in the parser, which means that the ending delimiter could be
//! a multi-byte codepoint that looks *like* a `)`. Subtracing 1 byte could land us in the middle of
//! a codepoint, triggering a codepoint boundary assertion.
//!
//! issue: rust-lang/rust#128717

fn main() {
// The following example has been modified from #128717 to remove irrelevant Unicode as they do
// not otherwise partake in the right delimiter calculation causing the codepoint boundary
// assertion.
main(rahh);
//~^ ERROR unknown start of token
//~| ERROR this function takes 0 arguments but 1 argument was supplied
//~| ERROR cannot find value `rahh` in this scope
}
38 changes: 38 additions & 0 deletions tests/ui/typeck/suggest-arg-comma-delete-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error: unknown start of token: \u{ff09}
--> $DIR/suggest-arg-comma-delete-ice.rs:15:14
|
LL | main(rahh);
| ^^
|
help: Unicode character ')' (Fullwidth Right Parenthesis) looks like ')' (Right Parenthesis), but it is not
|
LL | main(rahh);
| ~

error[E0425]: cannot find value `rahh` in this scope
--> $DIR/suggest-arg-comma-delete-ice.rs:15:10
|
LL | main(rahh);
| ^^^^ not found in this scope

error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/suggest-arg-comma-delete-ice.rs:15:5
|
LL | main(rahh);
| ^^^^ ---- unexpected argument
|
note: function defined here
--> $DIR/suggest-arg-comma-delete-ice.rs:11:4
|
LL | fn main() {
| ^^^^
help: remove the extra argument
|
LL - main(rahh);
LL + main();
|

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0061, E0425.
For more information about an error, try `rustc --explain E0061`.
Loading