Skip to content

Commit c8e8ab2

Browse files
Rollup merge of rust-lang#119286 - jyn514:linker-output, r=bjorn3
show linker output even if the linker succeeds - show stderr by default - show stdout if `--verbose` is passed - remove both from RUSTC_LOG - hide the linker cli args unless `--verbose` is passed fixes rust-lang#83436. fixes rust-lang#38206. fixes rust-lang#109979. helps with rust-lang#46998. cc https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/uplift.20some.20-Zverbose.20calls.20and.20rename.20to.E2.80.A6.20compiler-team.23706/near/408986134 this is based on rust-lang#119129 for convenience so i didn't have to duplicate the changes around saving `--verbose` in rust-lang@cb6d033#diff-7a49efa20548d6806dbe1c66dd4dc445fda18fcbbf1709520cadecc4841aae12 r? `@bjorn3`
2 parents e1cd05a + aac51d5 commit c8e8ab2

File tree

15 files changed

+225
-149
lines changed

15 files changed

+225
-149
lines changed

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
160160
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
161161
.note = {$error}
162162
163+
codegen_ssa_linker_output = {$inner}
164+
163165
codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
164166
165167
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}

compiler/rustc_codegen_ssa/src/back/link.rs

+25-3
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,14 @@ fn link_dwarf_object<'a>(
730730
}
731731
}
732732

733+
#[derive(Diagnostic)]
734+
#[diag(codegen_ssa_linker_output)]
735+
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
736+
/// end up with inconsistent languages within the same diagnostic.
737+
struct LinkerOutput {
738+
inner: String,
739+
}
740+
733741
/// Create a dynamic library or executable.
734742
///
735743
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
@@ -935,12 +943,12 @@ fn link_natively<'a>(
935943
let mut output = prog.stderr.clone();
936944
output.extend_from_slice(&prog.stdout);
937945
let escaped_output = escape_linker_output(&output, flavor);
938-
// FIXME: Add UI tests for this error.
939946
let err = errors::LinkingFailed {
940947
linker_path: &linker_path,
941948
exit_status: prog.status,
942949
command: &cmd,
943950
escaped_output,
951+
verbose: sess.opts.verbose,
944952
};
945953
sess.dcx().emit_err(err);
946954
// If MSVC's `link.exe` was expected but the return code
@@ -981,8 +989,22 @@ fn link_natively<'a>(
981989

982990
sess.dcx().abort_if_errors();
983991
}
984-
info!("linker stderr:\n{}", escape_string(&prog.stderr));
985-
info!("linker stdout:\n{}", escape_string(&prog.stdout));
992+
993+
if !prog.stderr.is_empty() {
994+
// We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
995+
let stderr = escape_string(&prog.stderr);
996+
debug!("original stderr: {stderr}");
997+
let stderr = stderr
998+
.strip_prefix("warning: ")
999+
.unwrap_or(&stderr)
1000+
.replace(": warning: ", ": ");
1001+
sess.dcx().emit_warn(LinkerOutput { inner: format!("linker stderr: {stderr}") });
1002+
}
1003+
if !prog.stdout.is_empty() && sess.opts.verbose {
1004+
sess.dcx().emit_warn(LinkerOutput {
1005+
inner: format!("linker stdout: {}", escape_string(&prog.stdout)),
1006+
});
1007+
}
9861008
}
9871009
Err(e) => {
9881010
let linker_not_found = e.kind() == io::ErrorKind::NotFound;

compiler/rustc_codegen_ssa/src/errors.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ pub struct LinkingFailed<'a> {
340340
pub exit_status: ExitStatus,
341341
pub command: &'a Command,
342342
pub escaped_output: String,
343+
pub verbose: bool,
343344
}
344345

345346
impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for LinkingFailed<'_> {
@@ -350,7 +351,13 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for LinkingFailed<'_> {
350351

351352
let contains_undefined_ref = self.escaped_output.contains("undefined reference to");
352353

353-
diag.note(format!("{:?}", self.command)).note(self.escaped_output);
354+
if self.verbose {
355+
diag.note(format!("{:?}", self.command));
356+
} else {
357+
diag.note("use `--verbose` to show all linker arguments");
358+
}
359+
360+
diag.note(self.escaped_output);
354361

355362
// Trying to match an error from OS linkers
356363
// which by now we have no way to translate.

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ impl DiagnosticDeriveVariantBuilder {
249249
let mut field_binding = binding_info.binding.clone();
250250
field_binding.set_span(field.ty.span());
251251

252-
let ident = field.ident.as_ref().unwrap();
252+
let Some(ident) = field.ident.as_ref() else {
253+
span_err(field.span().unwrap(), "tuple structs are not supported").emit();
254+
return TokenStream::new();
255+
};
253256
let ident = format_ident!("{}", ident); // strip `r#` prefix, if present
254257

255258
quote! {

compiler/rustc_macros/src/diagnostics/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn path_to_string(path: &syn::Path) -> String {
5555
/// Returns an error diagnostic on span `span` with msg `msg`.
5656
#[must_use]
5757
pub(crate) fn span_err<T: Into<String>>(span: impl MultiSpan, msg: T) -> Diagnostic {
58-
Diagnostic::spanned(span, Level::Error, msg)
58+
Diagnostic::spanned(span, Level::Error, format!("derive(Diagnostic): {}", msg.into()))
5959
}
6060

6161
/// Emit a diagnostic on span `$span` with msg `$msg` (optionally performing additional decoration

compiler/rustc_macros/src/diagnostics/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<T> SetOnce<T> for SpannedOption<T> {
242242
*self = Some((value, span));
243243
}
244244
Some((_, prev_span)) => {
245-
span_err(span, "specified multiple times")
245+
span_err(span, "attribute specified multiple times")
246246
.span_note(*prev_span, "previously specified here")
247247
.emit();
248248
}

src/etc/cat-and-grep.sh

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ while getopts ':vieh' OPTION; do
3333
case "$OPTION" in
3434
v)
3535
INVERT=1
36-
ERROR_MSG='should not be found'
3736
;;
3837
i)
3938
GREPFLAGS="i$GREPFLAGS"

tests/run-make/link-args-order/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ RUSTC_FLAGS = -C linker-flavor=ld -C link-arg=a -C link-args="b c" -C link-args=
66
RUSTC_FLAGS_PRE = -C linker-flavor=ld -Z pre-link-arg=a -Z pre-link-args="b c" -Z pre-link-args="d e" -Z pre-link-arg=f
77

88
all:
9-
$(RUSTC) $(RUSTC_FLAGS) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"'
10-
$(RUSTC) $(RUSTC_FLAGS_PRE) empty.rs 2>&1 | $(CGREP) '"a" "b" "c" "d" "e" "f"'
9+
$(RUSTC) $(RUSTC_FLAGS) empty.rs --print=link-args | $(CGREP) '"a" "b" "c" "d" "e" "f"'
10+
$(RUSTC) $(RUSTC_FLAGS_PRE) empty.rs --print=link-args | $(CGREP) '"a" "b" "c" "d" "e" "f"'

tests/run-make/link-dedup/Makefile

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ all:
66
$(RUSTC) depa.rs
77
$(RUSTC) depb.rs
88
$(RUSTC) depc.rs
9-
$(RUSTC) empty.rs --cfg bar 2>&1 | $(CGREP) '"-ltesta" "-ltestb" "-ltesta"'
10-
$(RUSTC) empty.rs 2>&1 | $(CGREP) '"-ltesta"'
11-
$(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltestb"'
12-
$(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltesta" "-ltesta" "-ltesta"'
9+
$(RUSTC) empty.rs --cfg bar --print=link-args | $(CGREP) '"-ltesta" "-ltestb" "-ltesta"'
10+
$(RUSTC) empty.rs --print=link-args | $(CGREP) '"-ltesta"'
11+
$(RUSTC) empty.rs --print=link-args | $(CGREP) -v '"-ltestb"'
12+
$(RUSTC) empty.rs --print=link-args | $(CGREP) -v '"-ltesta" "-ltesta" "-ltesta"'
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
include ../tools.mk
2+
3+
RUN_RUSTC := $(RUSTC_ORIGINAL) main.rs -o $(TMPDIR)/main -C linker=./fake-linker.sh
4+
5+
all: succeeds_with_warnings errors linker_args
6+
7+
succeeds_with_warnings:
8+
# Run rustc with our fake linker, and make sure it shows warnings
9+
$(RUN_RUSTC) -C link-arg=run_make_warn 2>&1 | $(CGREP) "warning: linker stderr: bar"
10+
11+
# Make sure it shows stdout, but only when --verbose is passed
12+
$(RUN_RUSTC) -C link-arg=run_make_info --verbose 2>&1 | $(CGREP) "warning: linker stdout: foo"
13+
$(RUN_RUSTC) -C link-arg=run_make_info 2>&1 | $(CGREP) -v "warning: linker stdout: foo"
14+
15+
errors:
16+
# Make sure we short-circuit this new path if the linker exits with an error (so the diagnostic is less verbose)
17+
rm -f $(TMPDIR)/main
18+
$(RUN_RUSTC) -C link-arg=run_make_error 2>&1 | $(CGREP) "note: error: baz"
19+
! [ -e $(TMPDIR)/main ]
20+
21+
linker_args:
22+
# Make sure we don't show the linker args unless `--verbose` is passed
23+
$(RUN_RUSTC) --verbose -C link-arg=run_make_error 2>&1 | $(CGREP) -e "PATH=.*fake-linker.sh.*run_make_error"
24+
$(RUN_RUSTC) -C link-arg=run_make_error 2>&1 | $(CGREP) -v -e "PATH=.*fake-linker.sh.*run_make_error"
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
3+
code=0
4+
while ! [ $# = 0 ]; do
5+
case "$1" in
6+
run_make_info) echo "foo"
7+
;;
8+
run_make_warn) echo "warning: bar" >&2
9+
;;
10+
run_make_error) echo "error: baz" >&2; code=1
11+
;;
12+
*) ;; # rustc passes lots of args we don't care about
13+
esac
14+
shift
15+
done
16+
17+
exit $code

tests/run-make/linker-warning/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}

0 commit comments

Comments
 (0)