Skip to content

Commit 3f41b03

Browse files
committed
Auto merge of #68496 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports This backports: * Do not ICE on malformed suggestion spans #68256 * Distinguish between private items and hidden items in rustdoc #67875 * Revert parts of #66405. #67471 It also includes a few formatting commits to permit the backports to proceed cleanly (those are scoped to the relevant files, but still generate noise, of course). This was deemed easier than attempting to manually deal with the formatting. r? @ghost
2 parents fb30562 + b0a99fd commit 3f41b03

24 files changed

+1537
-1423
lines changed

src/librustc_data_structures/obligation_forest/mod.rs

+122-170
Large diffs are not rendered by default.

src/librustc_errors/emitter.rs

+324-295
Large diffs are not rendered by default.

src/librustc_errors/lib.rs

+119-113
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,41 @@
33
//! This module contains the code for creating and emitting diagnostics.
44
55
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
6-
76
#![feature(crate_visibility_modifier)]
87
#![cfg_attr(unix, feature(libc))]
98
#![feature(nll)]
109
#![feature(optin_builtin_traits)]
1110

1211
pub use emitter::ColorConfig;
1312

13+
use log::debug;
1414
use Level::*;
1515

16-
use emitter::{Emitter, EmitterWriter, is_case_difference};
16+
use emitter::{is_case_difference, Emitter, EmitterWriter};
1717
use registry::Registry;
18-
use rustc_data_structures::sync::{self, Lrc, Lock};
1918
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
2019
use rustc_data_structures::stable_hasher::StableHasher;
20+
use rustc_data_structures::sync::{self, Lock, Lrc};
2121
use syntax_pos::source_map::SourceMap;
22-
use syntax_pos::{Loc, Span, MultiSpan};
22+
use syntax_pos::{Loc, MultiSpan, Span};
2323

2424
use std::borrow::Cow;
2525
use std::cell::Cell;
26-
use std::{error, fmt};
2726
use std::panic;
2827
use std::path::Path;
28+
use std::{error, fmt};
2929

30-
use termcolor::{ColorSpec, Color};
30+
use termcolor::{Color, ColorSpec};
3131

32+
pub mod annotate_snippet_emitter_writer;
3233
mod diagnostic;
3334
mod diagnostic_builder;
3435
pub mod emitter;
35-
pub mod annotate_snippet_emitter_writer;
36-
mod snippet;
36+
pub mod json;
37+
mod lock;
3738
pub mod registry;
39+
mod snippet;
3840
mod styled_buffer;
39-
mod lock;
40-
pub mod json;
4141
pub use snippet::Style;
4242

4343
pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
@@ -146,16 +146,15 @@ pub struct SubstitutionPart {
146146
impl CodeSuggestion {
147147
/// Returns the assembled code suggestions, whether they should be shown with an underline
148148
/// and whether the substitution only differs in capitalization.
149-
pub fn splice_lines(
150-
&self,
151-
cm: &SourceMap,
152-
) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
149+
pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
153150
use syntax_pos::{CharPos, Pos};
154151

155-
fn push_trailing(buf: &mut String,
156-
line_opt: Option<&Cow<'_, str>>,
157-
lo: &Loc,
158-
hi_opt: Option<&Loc>) {
152+
fn push_trailing(
153+
buf: &mut String,
154+
line_opt: Option<&Cow<'_, str>>,
155+
lo: &Loc,
156+
hi_opt: Option<&Loc>,
157+
) {
159158
let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi| hi.col.to_usize()));
160159
if let Some(line) = line_opt {
161160
if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) {
@@ -174,67 +173,80 @@ impl CodeSuggestion {
174173

175174
assert!(!self.substitutions.is_empty());
176175

177-
self.substitutions.iter().cloned().map(|mut substitution| {
178-
// Assumption: all spans are in the same file, and all spans
179-
// are disjoint. Sort in ascending order.
180-
substitution.parts.sort_by_key(|part| part.span.lo());
181-
182-
// Find the bounding span.
183-
let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
184-
let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap();
185-
let bounding_span = Span::with_root_ctxt(lo, hi);
186-
let lines = cm.span_to_lines(bounding_span).unwrap();
187-
assert!(!lines.lines.is_empty());
188-
189-
// To build up the result, we do this for each span:
190-
// - push the line segment trailing the previous span
191-
// (at the beginning a "phantom" span pointing at the start of the line)
192-
// - push lines between the previous and current span (if any)
193-
// - if the previous and current span are not on the same line
194-
// push the line segment leading up to the current span
195-
// - splice in the span substitution
196-
//
197-
// Finally push the trailing line segment of the last span
198-
let fm = &lines.file;
199-
let mut prev_hi = cm.lookup_char_pos(bounding_span.lo());
200-
prev_hi.col = CharPos::from_usize(0);
201-
202-
let mut prev_line = fm.get_line(lines.lines[0].line_index);
203-
let mut buf = String::new();
204-
205-
for part in &substitution.parts {
206-
let cur_lo = cm.lookup_char_pos(part.span.lo());
207-
if prev_hi.line == cur_lo.line {
208-
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
209-
} else {
210-
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
211-
// push lines between the previous and current span (if any)
212-
for idx in prev_hi.line..(cur_lo.line - 1) {
213-
if let Some(line) = fm.get_line(idx) {
214-
buf.push_str(line.as_ref());
215-
buf.push('\n');
176+
self.substitutions
177+
.iter()
178+
.filter(|subst| {
179+
// Suggestions coming from macros can have malformed spans. This is a heavy
180+
// handed approach to avoid ICEs by ignoring the suggestion outright.
181+
let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err());
182+
if invalid {
183+
debug!("splice_lines: suggestion contains an invalid span: {:?}", subst);
184+
}
185+
!invalid
186+
})
187+
.cloned()
188+
.map(|mut substitution| {
189+
// Assumption: all spans are in the same file, and all spans
190+
// are disjoint. Sort in ascending order.
191+
substitution.parts.sort_by_key(|part| part.span.lo());
192+
193+
// Find the bounding span.
194+
let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
195+
let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap();
196+
let bounding_span = Span::with_root_ctxt(lo, hi);
197+
let lines = cm.span_to_lines(bounding_span).unwrap();
198+
assert!(!lines.lines.is_empty());
199+
200+
// To build up the result, we do this for each span:
201+
// - push the line segment trailing the previous span
202+
// (at the beginning a "phantom" span pointing at the start of the line)
203+
// - push lines between the previous and current span (if any)
204+
// - if the previous and current span are not on the same line
205+
// push the line segment leading up to the current span
206+
// - splice in the span substitution
207+
//
208+
// Finally push the trailing line segment of the last span
209+
let fm = &lines.file;
210+
let mut prev_hi = cm.lookup_char_pos(bounding_span.lo());
211+
prev_hi.col = CharPos::from_usize(0);
212+
213+
let mut prev_line = fm.get_line(lines.lines[0].line_index);
214+
let mut buf = String::new();
215+
216+
for part in &substitution.parts {
217+
let cur_lo = cm.lookup_char_pos(part.span.lo());
218+
if prev_hi.line == cur_lo.line {
219+
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
220+
} else {
221+
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
222+
// push lines between the previous and current span (if any)
223+
for idx in prev_hi.line..(cur_lo.line - 1) {
224+
if let Some(line) = fm.get_line(idx) {
225+
buf.push_str(line.as_ref());
226+
buf.push('\n');
227+
}
228+
}
229+
if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
230+
let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize());
231+
buf.push_str(&cur_line[..end]);
216232
}
217233
}
218-
if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
219-
let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize());
220-
buf.push_str(&cur_line[..end]);
221-
}
234+
buf.push_str(&part.snippet);
235+
prev_hi = cm.lookup_char_pos(part.span.hi());
236+
prev_line = fm.get_line(prev_hi.line - 1);
222237
}
223-
buf.push_str(&part.snippet);
224-
prev_hi = cm.lookup_char_pos(part.span.hi());
225-
prev_line = fm.get_line(prev_hi.line - 1);
226-
}
227-
let only_capitalization = is_case_difference(cm, &buf, bounding_span);
228-
// if the replacement already ends with a newline, don't print the next line
229-
if !buf.ends_with('\n') {
230-
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
231-
}
232-
// remove trailing newlines
233-
while buf.ends_with('\n') {
234-
buf.pop();
235-
}
236-
(buf, substitution.parts, only_capitalization)
237-
}).collect()
238+
let only_capitalization = is_case_difference(cm, &buf, bounding_span);
239+
// if the replacement already ends with a newline, don't print the next line
240+
if !buf.ends_with('\n') {
241+
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
242+
}
243+
// remove trailing newlines
244+
while buf.ends_with('\n') {
245+
buf.pop();
246+
}
247+
(buf, substitution.parts, only_capitalization)
248+
})
249+
.collect()
238250
}
239251
}
240252

@@ -257,7 +269,7 @@ impl error::Error for ExplicitBug {
257269
}
258270
}
259271

260-
pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString, DiagnosticId};
272+
pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic};
261273
pub use diagnostic_builder::DiagnosticBuilder;
262274

263275
/// A handler deals with errors and other compiler output.
@@ -360,11 +372,7 @@ impl Handler {
360372
Self::with_tty_emitter_and_flags(
361373
color_config,
362374
cm,
363-
HandlerFlags {
364-
can_emit_warnings,
365-
treat_err_as_bug,
366-
.. Default::default()
367-
},
375+
HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() },
368376
)
369377
}
370378

@@ -391,17 +399,13 @@ impl Handler {
391399
) -> Self {
392400
Handler::with_emitter_and_flags(
393401
emitter,
394-
HandlerFlags {
395-
can_emit_warnings,
396-
treat_err_as_bug,
397-
.. Default::default()
398-
},
402+
HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() },
399403
)
400404
}
401405

402406
pub fn with_emitter_and_flags(
403407
emitter: Box<dyn Emitter + sync::Send>,
404-
flags: HandlerFlags
408+
flags: HandlerFlags,
405409
) -> Self {
406410
Self {
407411
flags,
@@ -457,7 +461,10 @@ impl Handler {
457461
old_diag.level = Bug;
458462
old_diag.note(&format!(
459463
"{}:{}: already existing stashed diagnostic with (span = {:?}, key = {:?})",
460-
file!(), line!(), span, key
464+
file!(),
465+
line!(),
466+
span,
467+
key
461468
));
462469
inner.emit_diag_at_span(old_diag, span);
463470
panic!(ExplicitBug);
@@ -779,7 +786,7 @@ impl HandlerInner {
779786
let s = match self.deduplicated_err_count {
780787
0 => return,
781788
1 => "aborting due to previous error".to_string(),
782-
count => format!("aborting due to {} previous errors", count)
789+
count => format!("aborting due to {} previous errors", count),
783790
};
784791
if self.treat_err_as_bug() {
785792
return;
@@ -804,16 +811,22 @@ impl HandlerInner {
804811
error_codes.sort();
805812
if error_codes.len() > 1 {
806813
let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() };
807-
self.failure(&format!("Some errors have detailed explanations: {}{}",
808-
error_codes[..limit].join(", "),
809-
if error_codes.len() > 9 { "..." } else { "." }));
810-
self.failure(&format!("For more information about an error, try \
814+
self.failure(&format!(
815+
"Some errors have detailed explanations: {}{}",
816+
error_codes[..limit].join(", "),
817+
if error_codes.len() > 9 { "..." } else { "." }
818+
));
819+
self.failure(&format!(
820+
"For more information about an error, try \
811821
`rustc --explain {}`.",
812-
&error_codes[0]));
822+
&error_codes[0]
823+
));
813824
} else {
814-
self.failure(&format!("For more information about this error, try \
825+
self.failure(&format!(
826+
"For more information about this error, try \
815827
`rustc --explain {}`.",
816-
&error_codes[0]));
828+
&error_codes[0]
829+
));
817830
}
818831
}
819832
}
@@ -880,7 +893,7 @@ impl HandlerInner {
880893
}
881894

882895
/// Emit an error; level should be `Error` or `Fatal`.
883-
fn emit_error(&mut self, level: Level, msg: &str,) {
896+
fn emit_error(&mut self, level: Level, msg: &str) {
884897
if self.treat_err_as_bug() {
885898
self.bug(msg);
886899
}
@@ -910,13 +923,10 @@ impl HandlerInner {
910923
(0, _) => return,
911924
(1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(),
912925
(1, _) => return,
913-
(count, as_bug) => {
914-
format!(
915-
"aborting after {} errors due to `-Z treat-err-as-bug={}`",
916-
count,
917-
as_bug,
918-
)
919-
}
926+
(count, as_bug) => format!(
927+
"aborting after {} errors due to `-Z treat-err-as-bug={}`",
928+
count, as_bug,
929+
),
920930
};
921931
panic!(s);
922932
}
@@ -946,20 +956,16 @@ impl Level {
946956
let mut spec = ColorSpec::new();
947957
match self {
948958
Bug | Fatal | Error => {
949-
spec.set_fg(Some(Color::Red))
950-
.set_intense(true);
959+
spec.set_fg(Some(Color::Red)).set_intense(true);
951960
}
952961
Warning => {
953-
spec.set_fg(Some(Color::Yellow))
954-
.set_intense(cfg!(windows));
962+
spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows));
955963
}
956964
Note => {
957-
spec.set_fg(Some(Color::Green))
958-
.set_intense(true);
965+
spec.set_fg(Some(Color::Green)).set_intense(true);
959966
}
960967
Help => {
961-
spec.set_fg(Some(Color::Cyan))
962-
.set_intense(true);
968+
spec.set_fg(Some(Color::Cyan)).set_intense(true);
963969
}
964970
FailureNote => {}
965971
Cancelled => unreachable!(),

0 commit comments

Comments
 (0)