Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 65 additions & 0 deletions compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub struct AnnotateSnippetEmitter {
track_diagnostics: bool,
terminal_url: TerminalUrl,
theme: OutputTheme,
show_suggestions_with_unavailable_source: bool,
}

impl Debug for AnnotateSnippetEmitter {
Expand All @@ -60,6 +61,7 @@ impl Debug for AnnotateSnippetEmitter {
track_diagnostics,
terminal_url,
theme,
show_suggestions_with_unavailable_source,
} = self;

f.debug_struct("AnnotateSnippetEmitter")
Expand All @@ -73,6 +75,10 @@ impl Debug for AnnotateSnippetEmitter {
.field("track_diagnostics", track_diagnostics)
.field("terminal_url", terminal_url)
.field("theme", theme)
.field(
"show_suggestions_with_unavailable_source",
show_suggestions_with_unavailable_source,
)
.finish()
}
}
Expand Down Expand Up @@ -153,6 +159,7 @@ impl AnnotateSnippetEmitter {
track_diagnostics: false,
terminal_url: TerminalUrl::No,
theme: OutputTheme::Ascii,
show_suggestions_with_unavailable_source: false,
}
}

Expand Down Expand Up @@ -319,6 +326,12 @@ impl AnnotateSnippetEmitter {
SuggestionStyle::HideCodeInline
| SuggestionStyle::ShowCode
| SuggestionStyle::ShowAlways => {
// Get the original unavailable spans before `suggestion` is consumed.
let unavailable_source_span = if self.show_suggestions_with_unavailable_source {
self.suggestion_span_with_unavailable_source(sm, &suggestion)
} else {
None
};
let substitutions = suggestion
.substitutions
.into_iter()
Expand Down Expand Up @@ -368,6 +381,30 @@ impl AnnotateSnippetEmitter {
.collect::<Vec<_>>();

if substitutions.is_empty() {
if let Some(span) = unavailable_source_span {
let msg = format_diag_message(&suggestion.msg, args).to_string();
report.push(std::mem::replace(
&mut group,
Group::with_title(
annotate_snippets::Level::HELP.secondary_title(msg),
),
));

let file_ann = collect_annotations(args, &span, sm);
let level = annotate_snippets::Level::HELP;
for (file_idx, (file, annotations)) in file_ann.into_iter().enumerate()
{
group = self.unannotated_messages(
annotations,
&file.name,
sm,
file_idx,
&mut report,
group,
&level,
);
}
}
continue;
}
let mut msg = format_diag_message(&suggestion.msg, args).to_string();
Expand Down Expand Up @@ -652,6 +689,34 @@ impl AnnotateSnippetEmitter {
}
group
}

fn suggestion_span_with_unavailable_source(
&self,
sm: &Arc<SourceMap>,
suggestion: &CodeSuggestion,
) -> Option<MultiSpan> {
// These spans cannot be rendered as source patches because their source
// files are unavailable, but can still be shown as locations.
let spans = suggestion
.substitutions
.iter()
.flat_map(|subst| &subst.parts)
.filter_map(|part| {
if sm.is_valid_span(part.span).is_err() {
debug!("suggestion contains an invalid span: {:?}", part);
return None;
}
let lines = sm.span_to_lines(part.span).ok()?;
if sm.ensure_source_file_source_present(&lines.file) {
None
} else {
Some(part.span)
}
})
.collect::<Vec<_>>();

if spans.is_empty() { None } else { Some(MultiSpan::from_spans(spans)) }
}
}

fn emit_to_destination(
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub struct JsonEmitter {
macro_backtrace: bool,
track_diagnostics: bool,
terminal_url: TerminalUrl,
show_suggestions_with_unavailable_source: bool,
}

impl JsonEmitter {
Expand All @@ -76,6 +77,7 @@ impl JsonEmitter {
macro_backtrace: false,
track_diagnostics: false,
terminal_url: TerminalUrl::No,
show_suggestions_with_unavailable_source: false,
}
}

Expand Down Expand Up @@ -361,6 +363,7 @@ impl Diagnostic {
.terminal_url(je.terminal_url)
.ui_testing(je.ui_testing)
.ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone())
.show_suggestions_with_unavailable_source(je.show_suggestions_with_unavailable_source)
.theme(if je.json_rendered.unicode { OutputTheme::Unicode } else { OutputTheme::Ascii })
.emit_diagnostic(diag);

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2883,6 +2883,8 @@ written to standard error output)"),
"make the current crate share its generic instantiations"),
shell_argfiles: bool = (false, parse_bool, [UNTRACKED],
"allow argument files to be specified with POSIX \"shell-style\" argument quoting"),
show_suggestions_with_unavailable_source: bool = (false, parse_bool, [UNTRACKED],
"show span-only suggestions when the source code is unavailable"),
Comment on lines +2886 to +2887

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a option show_suggestions_with_unavailable_source.

simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
to rust's source base directory. only meant for testing purposes"),
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,8 @@ impl Session {
fn default_emitter(sopts: &config::Options, source_map: Arc<SourceMap>) -> Box<DynEmitter> {
let macro_backtrace = sopts.unstable_opts.macro_backtrace;
let track_diagnostics = sopts.unstable_opts.track_diagnostics;
let show_suggestions_with_unavailable_source =
sopts.unstable_opts.show_suggestions_with_unavailable_source;
let terminal_url = match sopts.unstable_opts.terminal_urls {
TerminalUrl::Auto => {
match (std::env::var("COLORTERM").as_deref(), std::env::var("TERM").as_deref()) {
Expand Down Expand Up @@ -1309,6 +1311,9 @@ fn default_emitter(sopts: &config::Options, source_map: Arc<SourceMap>) -> Box<D
.track_diagnostics(track_diagnostics)
.terminal_url(terminal_url)
.theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii })
.show_suggestions_with_unavailable_source(
show_suggestions_with_unavailable_source,
)
.ignored_directories_in_source_blocks(
sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(),
);
Expand All @@ -1330,7 +1335,8 @@ fn default_emitter(sopts: &config::Options, source_map: Arc<SourceMap>) -> Box<D
.diagnostic_width(sopts.diagnostic_width)
.macro_backtrace(macro_backtrace)
.track_diagnostics(track_diagnostics)
.terminal_url(terminal_url),
.terminal_url(terminal_url)
.show_suggestions_with_unavailable_source(show_suggestions_with_unavailable_source),
),
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,9 @@ impl<'test> TestCx<'test> {
compiler.arg("-Zwrite-long-types-to-disk=no");
// FIXME: use this for other modes too, for perf?
compiler.arg("-Cstrip=debuginfo");
if self.config.suite != TestSuite::UiFullDeps {

@xizheyin xizheyin Oct 9, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I walked around the code, find in stage1 and ui-fulldeps it changes test_compiler to stage0

if suite == "ui-fulldeps" && test_compiler.stage == 1

I did a temp fix, supressing the flag in uifulldeps...but this is a bit strange—do you have any good ideas?@jieyouxu

View changes since the review

compiler.arg("-Zshow-suggestions-with-unavailable-source");
}

if self.config.parallel_frontend_enabled() {
// Currently, we only use multiple threads for the UI test suite,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ LL | if let V = vec![] {}
= note: `Vec<()>` is not usable in patterns
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
help: check for equality instead of pattern matching
--> $SRC_DIR/alloc/src/macros.rs:LL:COL
Comment on lines +150 to +151

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diagnostic bug?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming we end up with a span into the vec![] expansion instead of its callsite.


error: constant of non-structural type `Vec<()>` in a pattern
--> $DIR/suggest_equality_comparison_instead_of_pattern_matching.rs:28:13
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/pin-ergonomics/pinned-drop-check.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -293,36 +293,54 @@ error[E0040]: explicit use of destructor method
|
LL | Drop::pin_drop(todo!());
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error[E0040]: explicit use of destructor method
--> $DIR/pinned-drop-check.rs:156:13
|
LL | Drop::pin_drop(todo!());
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error[E0040]: explicit use of destructor method
--> $DIR/pinned-drop-check.rs:168:13
|
LL | Drop::drop(todo!());
| ^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error[E0040]: explicit use of destructor method
--> $DIR/pinned-drop-check.rs:173:13
|
LL | Drop::drop(todo!());
| ^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error[E0040]: explicit use of destructor method
--> $DIR/pinned-drop-check.rs:183:13
|
LL | Drop::drop(todo!());
| ^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error[E0040]: explicit use of destructor method
--> $DIR/pinned-drop-check.rs:184:13
|
LL | Drop::pin_drop(todo!());
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
help: consider using `drop` function
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL

error: aborting due to 25 previous errors

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/structs/ice-line-bounds-issue-148684.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ LL | A(2, vec![])
| ^^^^^^^^^^^^
|
= note: a struct named `A` exists in another namespace
help: use struct literal syntax instead of calling
--> $SRC_DIR/alloc/src/macros.rs:LL:COL

error: aborting due to 1 previous error

Expand Down
Loading