Skip to content

Commit 4be1c94

Browse files
authored
Rollup merge of rust-lang#102612 - JhonnyBillM:migrate-codegen-ssa-to-diagnostics-structs, r=davidtwco
Migrate `codegen_ssa` to diagnostics structs - [Part 1] Initial migration of `codegen_ssa`. Going to split this crate migration in at least two PRs in order to avoid a huge PR and to quick off some questions around: 1. Translating messages from "external" crates. 2. Interfacing with OS messages. 3. Adding UI tests while migrating diagnostics. _See comments below._
2 parents 16914c9 + 13d4f27 commit 4be1c94

File tree

7 files changed

+535
-92
lines changed

7 files changed

+535
-92
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+30-52
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ use super::command::Command;
3131
use super::linker::{self, Linker};
3232
use super::metadata::{create_rmeta_file, MetadataPosition};
3333
use super::rpath::{self, RPathConfig};
34-
use crate::{looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib};
34+
use crate::{
35+
errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib,
36+
};
3537

3638
use cc::windows_registry;
3739
use regex::Regex;
@@ -93,7 +95,7 @@ pub fn link_binary<'a>(
9395
let tmpdir = TempFileBuilder::new()
9496
.prefix("rustc")
9597
.tempdir()
96-
.unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
98+
.unwrap_or_else(|error| sess.emit_fatal(errors::CreateTempDir { error }));
9799
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);
98100
let out_filename = out_filename(
99101
sess,
@@ -208,7 +210,7 @@ pub fn link_binary<'a>(
208210
pub fn each_linked_rlib(
209211
info: &CrateInfo,
210212
f: &mut dyn FnMut(CrateNum, &Path),
211-
) -> Result<(), String> {
213+
) -> Result<(), errors::LinkRlibError> {
212214
let crates = info.used_crates.iter();
213215
let mut fmts = None;
214216
for (ty, list) in info.dependency_formats.iter() {
@@ -224,26 +226,23 @@ pub fn each_linked_rlib(
224226
}
225227
}
226228
let Some(fmts) = fmts else {
227-
return Err("could not find formats for rlibs".to_string());
229+
return Err(errors::LinkRlibError::MissingFormat);
228230
};
229231
for &cnum in crates {
230232
match fmts.get(cnum.as_usize() - 1) {
231233
Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue,
232234
Some(_) => {}
233-
None => return Err("could not find formats for rlibs".to_string()),
235+
None => return Err(errors::LinkRlibError::MissingFormat),
234236
}
235-
let name = info.crate_name[&cnum];
237+
let crate_name = info.crate_name[&cnum];
236238
let used_crate_source = &info.used_crate_source[&cnum];
237239
if let Some((path, _)) = &used_crate_source.rlib {
238240
f(cnum, &path);
239241
} else {
240242
if used_crate_source.rmeta.is_some() {
241-
return Err(format!(
242-
"could not find rlib for: `{}`, found rmeta (metadata) file",
243-
name
244-
));
243+
return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
245244
} else {
246-
return Err(format!("could not find rlib for: `{}`", name));
245+
return Err(errors::LinkRlibError::NotFound { crate_name });
247246
}
248247
}
249248
}
@@ -340,10 +339,7 @@ fn link_rlib<'a>(
340339
// -whole-archive and it isn't clear how we can currently handle such a
341340
// situation correctly.
342341
// See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
343-
sess.err(
344-
"the linking modifiers `+bundle` and `+whole-archive` are not compatible \
345-
with each other when generating rlibs",
346-
);
342+
sess.emit_err(errors::IncompatibleLinkingModifiers);
347343
}
348344
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
349345
NativeLibKind::Static { bundle: Some(false), .. }
@@ -365,12 +361,8 @@ fn link_rlib<'a>(
365361
));
366362
continue;
367363
}
368-
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
369-
sess.fatal(&format!(
370-
"failed to add native library {}: {}",
371-
location.to_string_lossy(),
372-
e
373-
));
364+
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| {
365+
sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error });
374366
});
375367
}
376368
}
@@ -385,8 +377,8 @@ fn link_rlib<'a>(
385377
tmpdir.as_ref(),
386378
);
387379

388-
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
389-
sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e));
380+
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
381+
sess.emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
390382
});
391383
}
392384

@@ -451,14 +443,11 @@ fn collate_raw_dylibs(
451443
// FIXME: when we add support for ordinals, figure out if we need to do anything
452444
// if we have two DllImport values with the same name but different ordinals.
453445
if import.calling_convention != old_import.calling_convention {
454-
sess.span_err(
455-
import.span,
456-
&format!(
457-
"multiple declarations of external function `{}` from \
458-
library `{}` have different calling conventions",
459-
import.name, name,
460-
),
461-
);
446+
sess.emit_err(errors::MultipleExternalFuncDecl {
447+
span: import.span,
448+
function: import.name,
449+
library_name: &name,
450+
});
462451
}
463452
}
464453
}
@@ -560,7 +549,7 @@ fn link_staticlib<'a>(
560549
all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
561550
});
562551
if let Err(e) = res {
563-
sess.fatal(&e);
552+
sess.emit_fatal(e);
564553
}
565554

566555
ab.build(out_filename);
@@ -673,9 +662,7 @@ fn link_dwarf_object<'a>(
673662
}) {
674663
Ok(()) => {}
675664
Err(e) => {
676-
sess.struct_err("linking dwarf objects with thorin failed")
677-
.note(&format!("{:?}", e))
678-
.emit();
665+
sess.emit_err(errors::ThorinErrorWrapper(e));
679666
sess.abort_if_errors();
680667
}
681668
}
@@ -879,23 +866,14 @@ fn link_natively<'a>(
879866
let mut output = prog.stderr.clone();
880867
output.extend_from_slice(&prog.stdout);
881868
let escaped_output = escape_string(&output);
882-
let mut err = sess.struct_err(&format!(
883-
"linking with `{}` failed: {}",
884-
linker_path.display(),
885-
prog.status
886-
));
887-
err.note(&format!("{:?}", &cmd)).note(&escaped_output);
888-
if escaped_output.contains("undefined reference to") {
889-
err.help(
890-
"some `extern` functions couldn't be found; some native libraries may \
891-
need to be installed or have their path specified",
892-
);
893-
err.note("use the `-l` flag to specify native libraries to link");
894-
err.note("use the `cargo:rustc-link-lib` directive to specify the native \
895-
libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)");
896-
}
897-
err.emit();
898-
869+
// FIXME: Add UI tests for this error.
870+
let err = errors::LinkingFailed {
871+
linker_path: &linker_path,
872+
exit_status: prog.status,
873+
command: &cmd,
874+
escaped_output: &escaped_output,
875+
};
876+
sess.diagnostic().emit_err(err);
899877
// If MSVC's `link.exe` was expected but the return code
900878
// is not a Microsoft LNK error then suggest a way to fix or
901879
// install the Visual Studio build tools.

compiler/rustc_codegen_ssa/src/back/linker.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::command::Command;
22
use super::symbol_export;
3+
use crate::errors;
34
use rustc_span::symbol::sym;
45

56
use std::ffi::{OsStr, OsString};
@@ -434,11 +435,11 @@ impl<'a> Linker for GccLinker<'a> {
434435
// FIXME(81490): ld64 doesn't support these flags but macOS 11
435436
// has -needed-l{} / -needed_library {}
436437
// but we have no way to detect that here.
437-
self.sess.warn("`as-needed` modifier not implemented yet for ld64");
438+
self.sess.emit_warning(errors::Ld64UnimplementedModifier);
438439
} else if self.is_gnu && !self.sess.target.is_like_windows {
439440
self.linker_arg("--no-as-needed");
440441
} else {
441-
self.sess.warn("`as-needed` modifier not supported for current linker");
442+
self.sess.emit_warning(errors::LinkerUnsupportedModifier);
442443
}
443444
}
444445
self.hint_dynamic();
@@ -492,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> {
492493
// FIXME(81490): ld64 as of macOS 11 supports the -needed_framework
493494
// flag but we have no way to detect that here.
494495
// self.cmd.arg("-needed_framework").arg(framework);
495-
self.sess.warn("`as-needed` modifier not implemented yet for ld64");
496+
self.sess.emit_warning(errors::Ld64UnimplementedModifier);
496497
}
497498
self.cmd.arg("-framework").arg(framework);
498499
}
@@ -665,8 +666,8 @@ impl<'a> Linker for GccLinker<'a> {
665666
writeln!(f, "_{}", sym)?;
666667
}
667668
};
668-
if let Err(e) = res {
669-
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
669+
if let Err(error) = res {
670+
self.sess.emit_fatal(errors::LibDefWriteFailure { error });
670671
}
671672
} else if is_windows {
672673
let res: io::Result<()> = try {
@@ -680,8 +681,8 @@ impl<'a> Linker for GccLinker<'a> {
680681
writeln!(f, " {}", symbol)?;
681682
}
682683
};
683-
if let Err(e) = res {
684-
self.sess.fatal(&format!("failed to write list.def file: {}", e));
684+
if let Err(error) = res {
685+
self.sess.emit_fatal(errors::LibDefWriteFailure { error });
685686
}
686687
} else {
687688
// Write an LD version script
@@ -697,8 +698,8 @@ impl<'a> Linker for GccLinker<'a> {
697698
}
698699
writeln!(f, "\n local:\n *;\n}};")?;
699700
};
700-
if let Err(e) = res {
701-
self.sess.fatal(&format!("failed to write version script: {}", e));
701+
if let Err(error) = res {
702+
self.sess.emit_fatal(errors::VersionScriptWriteFailure { error });
702703
}
703704
}
704705

@@ -915,9 +916,8 @@ impl<'a> Linker for MsvcLinker<'a> {
915916
self.cmd.arg(arg);
916917
}
917918
}
918-
Err(err) => {
919-
self.sess
920-
.warn(&format!("error enumerating natvis directory: {}", err));
919+
Err(error) => {
920+
self.sess.emit_warning(errors::NoNatvisDirectory { error });
921921
}
922922
}
923923
}
@@ -971,8 +971,8 @@ impl<'a> Linker for MsvcLinker<'a> {
971971
writeln!(f, " {}", symbol)?;
972972
}
973973
};
974-
if let Err(e) = res {
975-
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
974+
if let Err(error) = res {
975+
self.sess.emit_fatal(errors::LibDefWriteFailure { error });
976976
}
977977
let mut arg = OsString::from("/DEF:");
978978
arg.push(path);
@@ -1435,7 +1435,7 @@ impl<'a> Linker for L4Bender<'a> {
14351435

14361436
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
14371437
// ToDo, not implemented, copy from GCC
1438-
self.sess.warn("exporting symbols not implemented yet for L4Bender");
1438+
self.sess.emit_warning(errors::L4BenderExportingSymbolsUnimplemented);
14391439
return;
14401440
}
14411441

@@ -1727,8 +1727,8 @@ impl<'a> Linker for BpfLinker<'a> {
17271727
writeln!(f, "{}", sym)?;
17281728
}
17291729
};
1730-
if let Err(e) = res {
1731-
self.sess.fatal(&format!("failed to write symbols file: {}", e));
1730+
if let Err(error) = res {
1731+
self.sess.emit_fatal(errors::SymbolFileWriteFailure { error });
17321732
} else {
17331733
self.cmd.arg("--export-symbols").arg(&path);
17341734
}

compiler/rustc_codegen_ssa/src/back/write.rs

+12-22
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use super::link::{self, ensure_removed};
22
use super::lto::{self, SerializedModule};
33
use super::symbol_export::symbol_name_for_instance_in_crate;
44

5+
use crate::errors;
6+
use crate::traits::*;
57
use crate::{
68
CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
79
};
8-
9-
use crate::traits::*;
1010
use jobserver::{Acquired, Client};
1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_data_structures::memmap::Mmap;
@@ -530,7 +530,7 @@ fn produce_final_output_artifacts(
530530
// Produce final compile outputs.
531531
let copy_gracefully = |from: &Path, to: &Path| {
532532
if let Err(e) = fs::copy(from, to) {
533-
sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e));
533+
sess.emit_err(errors::CopyPath::new(from, to, e));
534534
}
535535
};
536536

@@ -546,7 +546,7 @@ fn produce_final_output_artifacts(
546546
ensure_removed(sess.diagnostic(), &path);
547547
}
548548
} else {
549-
let ext = crate_output
549+
let extension = crate_output
550550
.temp_path(output_type, None)
551551
.extension()
552552
.unwrap()
@@ -557,19 +557,11 @@ fn produce_final_output_artifacts(
557557
if crate_output.outputs.contains_key(&output_type) {
558558
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
559559
// no good solution for this case, so warn the user.
560-
sess.warn(&format!(
561-
"ignoring emit path because multiple .{} files \
562-
were produced",
563-
ext
564-
));
560+
sess.emit_warning(errors::IgnoringEmitPath { extension });
565561
} else if crate_output.single_output_file.is_some() {
566562
// 3) Multiple codegen units, with `-o some_name`. We have
567563
// no good solution for this case, so warn the user.
568-
sess.warn(&format!(
569-
"ignoring -o because multiple .{} files \
570-
were produced",
571-
ext
572-
));
564+
sess.emit_warning(errors::IgnoringOutput { extension });
573565
} else {
574566
// 4) Multiple codegen units, but no explicit name. We
575567
// just leave the `foo.0.x` files in place.
@@ -880,14 +872,12 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
880872
);
881873
match link_or_copy(&source_file, &output_path) {
882874
Ok(_) => Some(output_path),
883-
Err(err) => {
884-
let diag_handler = cgcx.create_diag_handler();
885-
diag_handler.err(&format!(
886-
"unable to copy {} to {}: {}",
887-
source_file.display(),
888-
output_path.display(),
889-
err
890-
));
875+
Err(error) => {
876+
cgcx.create_diag_handler().emit_err(errors::CopyPathBuf {
877+
source_file,
878+
output_path,
879+
error,
880+
});
891881
None
892882
}
893883
}

0 commit comments

Comments
 (0)