Skip to content

Commit 4e8fb74

Browse files
committed
Auto merge of #93621 - JohnTitor:rollup-1bcud0x, r=JohnTitor
Rollup of 7 pull requests Successful merges: - #92310 (rustdoc: Fix ICE report) - #92802 (Deduplicate lines in long const-eval stack trace) - #93515 (Factor convenience functions out of main printer implementation) - #93566 (Make rustc use `RUST_BACKTRACE=full` by default) - #93589 (Use Option::then in two places) - #93600 (fix: Remove extra newlines from junit output) - #93606 (Correct incorrect description of preorder traversals) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8b7853f + 38adea9 commit 4e8fb74

File tree

12 files changed

+215
-105
lines changed

12 files changed

+215
-105
lines changed

compiler/rustc_ast_pretty/src/pp.rs

+1-75
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
//! methods called `Printer::scan_*`, and the 'PRINT' process is the
133133
//! method called `Printer::print`.
134134
135+
mod convenience;
135136
mod ring;
136137

137138
use ring::RingBuffer;
@@ -186,12 +187,6 @@ pub enum Token {
186187
End,
187188
}
188189

189-
impl Token {
190-
pub fn is_hardbreak_tok(&self) -> bool {
191-
matches!(self, Token::Break(BreakToken { offset: 0, blank_space: SIZE_INFINITY }))
192-
}
193-
}
194-
195190
#[derive(Copy, Clone)]
196191
enum PrintFrame {
197192
Fits,
@@ -441,73 +436,4 @@ impl Printer {
441436
self.out.push_str(string);
442437
self.space -= string.len() as isize;
443438
}
444-
445-
// Convenience functions to talk to the printer.
446-
447-
/// "raw box"
448-
pub fn rbox(&mut self, indent: usize, breaks: Breaks) {
449-
self.scan_begin(BeginToken {
450-
indent: IndentStyle::Block { offset: indent as isize },
451-
breaks,
452-
})
453-
}
454-
455-
/// Inconsistent breaking box
456-
pub fn ibox(&mut self, indent: usize) {
457-
self.rbox(indent, Breaks::Inconsistent)
458-
}
459-
460-
/// Consistent breaking box
461-
pub fn cbox(&mut self, indent: usize) {
462-
self.rbox(indent, Breaks::Consistent)
463-
}
464-
465-
pub fn visual_align(&mut self) {
466-
self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent });
467-
}
468-
469-
pub fn break_offset(&mut self, n: usize, off: isize) {
470-
self.scan_break(BreakToken { offset: off, blank_space: n as isize })
471-
}
472-
473-
pub fn end(&mut self) {
474-
self.scan_end()
475-
}
476-
477-
pub fn eof(mut self) -> String {
478-
self.scan_eof();
479-
self.out
480-
}
481-
482-
pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) {
483-
let string = wrd.into();
484-
self.scan_string(string)
485-
}
486-
487-
fn spaces(&mut self, n: usize) {
488-
self.break_offset(n, 0)
489-
}
490-
491-
pub fn zerobreak(&mut self) {
492-
self.spaces(0)
493-
}
494-
495-
pub fn space(&mut self) {
496-
self.spaces(1)
497-
}
498-
499-
pub fn hardbreak(&mut self) {
500-
self.spaces(SIZE_INFINITY as usize)
501-
}
502-
503-
pub fn is_beginning_of_line(&self) -> bool {
504-
match self.last_token() {
505-
Some(last_token) => last_token.is_hardbreak_tok(),
506-
None => true,
507-
}
508-
}
509-
510-
pub fn hardbreak_tok_offset(off: isize) -> Token {
511-
Token::Break(BreakToken { offset: off, blank_space: SIZE_INFINITY })
512-
}
513439
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::pp::{BeginToken, BreakToken, Breaks, IndentStyle, Printer, Token, SIZE_INFINITY};
2+
use std::borrow::Cow;
3+
4+
impl Printer {
5+
/// "raw box"
6+
pub fn rbox(&mut self, indent: usize, breaks: Breaks) {
7+
self.scan_begin(BeginToken {
8+
indent: IndentStyle::Block { offset: indent as isize },
9+
breaks,
10+
})
11+
}
12+
13+
/// Inconsistent breaking box
14+
pub fn ibox(&mut self, indent: usize) {
15+
self.rbox(indent, Breaks::Inconsistent)
16+
}
17+
18+
/// Consistent breaking box
19+
pub fn cbox(&mut self, indent: usize) {
20+
self.rbox(indent, Breaks::Consistent)
21+
}
22+
23+
pub fn visual_align(&mut self) {
24+
self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent });
25+
}
26+
27+
pub fn break_offset(&mut self, n: usize, off: isize) {
28+
self.scan_break(BreakToken { offset: off, blank_space: n as isize })
29+
}
30+
31+
pub fn end(&mut self) {
32+
self.scan_end()
33+
}
34+
35+
pub fn eof(mut self) -> String {
36+
self.scan_eof();
37+
self.out
38+
}
39+
40+
pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) {
41+
let string = wrd.into();
42+
self.scan_string(string)
43+
}
44+
45+
fn spaces(&mut self, n: usize) {
46+
self.break_offset(n, 0)
47+
}
48+
49+
pub fn zerobreak(&mut self) {
50+
self.spaces(0)
51+
}
52+
53+
pub fn space(&mut self) {
54+
self.spaces(1)
55+
}
56+
57+
pub fn hardbreak(&mut self) {
58+
self.spaces(SIZE_INFINITY as usize)
59+
}
60+
61+
pub fn is_beginning_of_line(&self) -> bool {
62+
match self.last_token() {
63+
Some(last_token) => last_token.is_hardbreak_tok(),
64+
None => true,
65+
}
66+
}
67+
68+
pub fn hardbreak_tok_offset(off: isize) -> Token {
69+
Token::Break(BreakToken { offset: off, blank_space: SIZE_INFINITY })
70+
}
71+
}
72+
73+
impl Token {
74+
pub fn is_hardbreak_tok(&self) -> bool {
75+
matches!(self, Token::Break(BreakToken { offset: 0, blank_space: SIZE_INFINITY }))
76+
}
77+
}

compiler/rustc_const_eval/src/const_eval/error.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,37 @@ impl<'tcx> ConstEvalErr<'tcx> {
156156
}
157157
// Add spans for the stacktrace. Don't print a single-line backtrace though.
158158
if self.stacktrace.len() > 1 {
159+
// Helper closure to print duplicated lines.
160+
let mut flush_last_line = |last_frame, times| {
161+
if let Some((line, span)) = last_frame {
162+
err.span_label(span, &line);
163+
// Don't print [... additional calls ...] if the number of lines is small
164+
if times < 3 {
165+
for _ in 0..times {
166+
err.span_label(span, &line);
167+
}
168+
} else {
169+
err.span_label(
170+
span,
171+
format!("[... {} additional calls {} ...]", times, &line),
172+
);
173+
}
174+
}
175+
};
176+
177+
let mut last_frame = None;
178+
let mut times = 0;
159179
for frame_info in &self.stacktrace {
160-
err.span_label(frame_info.span, frame_info.to_string());
180+
let frame = (frame_info.to_string(), frame_info.span);
181+
if last_frame.as_ref() == Some(&frame) {
182+
times += 1;
183+
} else {
184+
flush_last_line(last_frame, times);
185+
last_frame = Some(frame);
186+
times = 0;
187+
}
161188
}
189+
flush_last_line(last_frame, times);
162190
}
163191
// Let the caller finish the job.
164192
emit(err)

compiler/rustc_driver/src/lib.rs

+30-21
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub const EXIT_FAILURE: i32 = 1;
6666
const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/issues/new\
6767
?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md";
6868

69-
const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["Z", "C", "crate-type"];
69+
const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
7070

7171
const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
7272

@@ -1100,31 +1100,31 @@ fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<as
11001100
/// debugging, since some ICEs only happens with non-default compiler flags
11011101
/// (and the users don't always report them).
11021102
fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
1103-
let args = env::args_os().map(|arg| arg.to_string_lossy().to_string()).collect::<Vec<_>>();
1103+
let mut args = env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable();
11041104

1105-
// Avoid printing help because of empty args. This can suggest the compiler
1106-
// itself is not the program root (consider RLS).
1107-
if args.len() < 2 {
1108-
return None;
1109-
}
1110-
1111-
let matches = handle_options(&args)?;
11121105
let mut result = Vec::new();
11131106
let mut excluded_cargo_defaults = false;
1114-
for flag in ICE_REPORT_COMPILER_FLAGS {
1115-
let prefix = if flag.len() == 1 { "-" } else { "--" };
1116-
1117-
for content in &matches.opt_strs(flag) {
1118-
// Split always returns the first element
1119-
let name = if let Some(first) = content.split('=').next() { first } else { &content };
1120-
1121-
let content =
1122-
if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { name } else { content };
1123-
1124-
if !ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&name) {
1125-
result.push(format!("{}{} {}", prefix, flag, content));
1107+
while let Some(arg) = args.next() {
1108+
if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
1109+
let content = if arg.len() == a.len() {
1110+
match args.next() {
1111+
Some(arg) => arg.to_string(),
1112+
None => continue,
1113+
}
1114+
} else if arg.get(a.len()..a.len() + 1) == Some("=") {
1115+
arg[a.len() + 1..].to_string()
11261116
} else {
1117+
arg[a.len()..].to_string()
1118+
};
1119+
if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| content.starts_with(exc)) {
11271120
excluded_cargo_defaults = true;
1121+
} else {
1122+
result.push(a.to_string());
1123+
match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| content.starts_with(*s))
1124+
{
1125+
Some(s) => result.push(s.to_string()),
1126+
None => result.push(content),
1127+
}
11281128
}
11291129
}
11301130
}
@@ -1240,6 +1240,15 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
12401240
///
12411241
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
12421242
pub fn install_ice_hook() {
1243+
// If the user has not explicitly overriden "RUST_BACKTRACE", then produce
1244+
// full backtraces. When a compiler ICE happens, we want to gather
1245+
// as much information as possible to present in the issue opened
1246+
// by the user. Compiler developers and other rustc users can
1247+
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
1248+
// (e.g. `RUST_BACKTRACE=1`)
1249+
if std::env::var("RUST_BACKTRACE").is_err() {
1250+
std::env::set_var("RUST_BACKTRACE", "full");
1251+
}
12431252
SyncLazy::force(&DEFAULT_HOOK);
12441253
}
12451254

compiler/rustc_middle/src/mir/traversal.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use super::*;
44

55
/// Preorder traversal of a graph.
66
///
7-
/// Preorder traversal is when each node is visited before any of its
8-
/// successors
7+
/// Preorder traversal is when each node is visited after at least one of its predecessors. If you
8+
/// are familar with some basic graph theory, then this performs a depth first search and returns
9+
/// nodes in order of discovery time.
910
///
1011
/// ```text
1112
///
@@ -82,8 +83,9 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
8283

8384
/// Postorder traversal of a graph.
8485
///
85-
/// Postorder traversal is when each node is visited after all of its
86-
/// successors, except when the successor is only reachable by a back-edge
86+
/// Postorder traversal is when each node is visited after all of its successors, except when the
87+
/// successor is only reachable by a back-edge. If you are familiar with some basic graph theory,
88+
/// then this performs a depth first search and returns nodes in order of completion time.
8789
///
8890
///
8991
/// ```text

compiler/rustc_mir_build/src/build/matches/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
264264
// The set of places that we are creating fake borrows of. If there are
265265
// no match guards then we don't need any fake borrows, so don't track
266266
// them.
267-
let mut fake_borrows = if match_has_guard { Some(FxHashSet::default()) } else { None };
267+
let mut fake_borrows = match_has_guard.then(FxHashSet::default);
268268

269269
let mut otherwise = None;
270270

compiler/rustc_query_system/src/dep_graph/serialized.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<K: DepKind> EncoderState<K> {
182182
total_edge_count: 0,
183183
total_node_count: 0,
184184
result: Ok(()),
185-
stats: if record_stats { Some(FxHashMap::default()) } else { None },
185+
stats: record_stats.then(FxHashMap::default),
186186
}
187187
}
188188

library/test/src/formatters/junit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
3333
_shuffle_seed: Option<u64>,
3434
) -> io::Result<()> {
3535
// We write xml header on run start
36-
self.out.write_all(b"\n")?;
3736
self.write_message("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
3837
}
3938

@@ -138,7 +137,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
138137
self.write_message("</testsuite>")?;
139138
self.write_message("</testsuites>")?;
140139

141-
self.out.write_all(b"\n\n")?;
140+
self.out.write_all(b"\n")?;
142141

143142
Ok(state.failed == 0)
144143
}

src/test/ui/consts/recursive.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(unused)]
2+
3+
const fn f<T>(x: T) { //~ WARN function cannot return without recursing
4+
f(x);
5+
//~^ ERROR any use of this value will cause an error
6+
//~| WARN this was previously accepted by the compiler
7+
}
8+
9+
const X: () = f(1);
10+
11+
fn main() {}

src/test/ui/consts/recursive.stderr

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: function cannot return without recursing
2+
--> $DIR/recursive.rs:3:1
3+
|
4+
LL | const fn f<T>(x: T) {
5+
| ^^^^^^^^^^^^^^^^^^^ cannot return without recursing
6+
LL | f(x);
7+
| ---- recursive call site
8+
|
9+
= note: `#[warn(unconditional_recursion)]` on by default
10+
= help: a `loop` may express intention better if this is on purpose
11+
12+
error: any use of this value will cause an error
13+
--> $DIR/recursive.rs:4:5
14+
|
15+
LL | f(x);
16+
| ^^^^
17+
| |
18+
| reached the configured maximum number of stack frames
19+
| inside `f::<i32>` at $DIR/recursive.rs:4:5
20+
| [... 126 additional calls inside `f::<i32>` at $DIR/recursive.rs:4:5 ...]
21+
| inside `X` at $DIR/recursive.rs:9:15
22+
...
23+
LL | const X: () = f(1);
24+
| -------------------
25+
|
26+
= note: `#[deny(const_err)]` on by default
27+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
28+
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
29+
30+
error: aborting due to previous error; 1 warning emitted
31+

0 commit comments

Comments
 (0)