Rollup merge of #100928 - CleanCut:rustc_metadata_diagnostics, r=davidtwco
Migrate rustc_metadata to SessionDiagnostics Migrate rustc_metadata to SessionDiagnostics. Part of https://github.com/rust-lang/rust/issues/100717
This commit is contained in:
commit
a0056795da
13 changed files with 1197 additions and 455 deletions
|
@ -3509,6 +3509,7 @@ dependencies = [
|
||||||
"rustc_macros",
|
"rustc_macros",
|
||||||
"rustc_serialize",
|
"rustc_serialize",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
|
"rustc_target",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
|
|
272
compiler/rustc_error_messages/locales/en-US/metadata.ftl
Normal file
272
compiler/rustc_error_messages/locales/en-US/metadata.ftl
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
metadata_rlib_required =
|
||||||
|
crate `{$crate_name}` required to be available in rlib format, but was not found in this form
|
||||||
|
|
||||||
|
metadata_lib_required =
|
||||||
|
crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
|
||||||
|
|
||||||
|
metadata_crate_dep_multiple =
|
||||||
|
cannot satisfy dependencies so `{$crate_name}` only shows up once
|
||||||
|
.help = having upstream crates all available in one format will likely make this go away
|
||||||
|
|
||||||
|
metadata_two_panic_runtimes =
|
||||||
|
cannot link together two panic runtimes: {$prev_name} and {$cur_name}
|
||||||
|
|
||||||
|
metadata_bad_panic_strategy =
|
||||||
|
the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`
|
||||||
|
|
||||||
|
metadata_required_panic_strategy =
|
||||||
|
the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
|
||||||
|
|
||||||
|
metadata_incompatible_panic_in_drop_strategy =
|
||||||
|
the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
|
||||||
|
|
||||||
|
metadata_multiple_names_in_link =
|
||||||
|
multiple `name` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_multiple_kinds_in_link =
|
||||||
|
multiple `kind` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_link_name_form =
|
||||||
|
link name must be of the form `name = "string"`
|
||||||
|
|
||||||
|
metadata_link_kind_form =
|
||||||
|
link kind must be of the form `kind = "string"`
|
||||||
|
|
||||||
|
metadata_link_modifiers_form =
|
||||||
|
link modifiers must be of the form `modifiers = "string"`
|
||||||
|
|
||||||
|
metadata_link_cfg_form =
|
||||||
|
link cfg must be of the form `cfg(/* predicate */)`
|
||||||
|
|
||||||
|
metadata_wasm_import_form =
|
||||||
|
wasm import module must be of the form `wasm_import_module = "string"`
|
||||||
|
|
||||||
|
metadata_empty_link_name =
|
||||||
|
link name must not be empty
|
||||||
|
.label = empty link name
|
||||||
|
|
||||||
|
metadata_link_framework_apple =
|
||||||
|
link kind `framework` is only supported on Apple targets
|
||||||
|
|
||||||
|
metadata_framework_only_windows =
|
||||||
|
link kind `raw-dylib` is only supported on Windows targets
|
||||||
|
|
||||||
|
metadata_unknown_link_kind =
|
||||||
|
unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib
|
||||||
|
.label = unknown link kind
|
||||||
|
|
||||||
|
metadata_multiple_link_modifiers =
|
||||||
|
multiple `modifiers` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_multiple_cfgs =
|
||||||
|
multiple `cfg` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_link_cfg_single_predicate =
|
||||||
|
link cfg must have a single predicate argument
|
||||||
|
|
||||||
|
metadata_multiple_wasm_import =
|
||||||
|
multiple `wasm_import_module` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_unexpected_link_arg =
|
||||||
|
unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
|
||||||
|
|
||||||
|
metadata_invalid_link_modifier =
|
||||||
|
invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
|
||||||
|
|
||||||
|
metadata_multiple_modifiers =
|
||||||
|
multiple `{$modifier}` modifiers in a single `modifiers` argument
|
||||||
|
|
||||||
|
metadata_bundle_needs_static =
|
||||||
|
linking modifier `bundle` is only compatible with `static` linking kind
|
||||||
|
|
||||||
|
metadata_whole_archive_needs_static =
|
||||||
|
linking modifier `whole-archive` is only compatible with `static` linking kind
|
||||||
|
|
||||||
|
metadata_as_needed_compatibility =
|
||||||
|
linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
|
||||||
|
|
||||||
|
metadata_unknown_link_modifier =
|
||||||
|
unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
|
||||||
|
|
||||||
|
metadata_incompatible_wasm_link =
|
||||||
|
`wasm_import_module` is incompatible with other arguments in `#[link]` attributes
|
||||||
|
|
||||||
|
metadata_link_requires_name =
|
||||||
|
`#[link]` attribute requires a `name = "string"` argument
|
||||||
|
.label = missing `name` argument
|
||||||
|
|
||||||
|
metadata_raw_dylib_no_nul =
|
||||||
|
link name must not contain NUL characters if link kind is `raw-dylib`
|
||||||
|
|
||||||
|
metadata_link_ordinal_raw_dylib =
|
||||||
|
`#[link_ordinal]` is only supported if link kind is `raw-dylib`
|
||||||
|
|
||||||
|
metadata_lib_framework_apple =
|
||||||
|
library kind `framework` is only supported on Apple targets
|
||||||
|
|
||||||
|
metadata_empty_renaming_target =
|
||||||
|
an empty renaming target was specified for library `{$lib_name}`
|
||||||
|
|
||||||
|
metadata_renaming_no_link =
|
||||||
|
renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library
|
||||||
|
|
||||||
|
metadata_multiple_renamings =
|
||||||
|
multiple renamings were specified for library `{$lib_name}`
|
||||||
|
|
||||||
|
metadata_no_link_mod_override =
|
||||||
|
overriding linking modifiers from command line is not supported
|
||||||
|
|
||||||
|
metadata_unsupported_abi_i686 =
|
||||||
|
ABI not supported by `#[link(kind = "raw-dylib")]` on i686
|
||||||
|
|
||||||
|
metadata_unsupported_abi =
|
||||||
|
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
|
||||||
|
|
||||||
|
metadata_fail_create_file_encoder =
|
||||||
|
failed to create file encoder: {$err}
|
||||||
|
|
||||||
|
metadata_fail_seek_file =
|
||||||
|
failed to seek the file: {$err}
|
||||||
|
|
||||||
|
metadata_fail_write_file =
|
||||||
|
failed to write to the file: {$err}
|
||||||
|
|
||||||
|
metadata_crate_not_panic_runtime =
|
||||||
|
the crate `{$crate_name}` is not a panic runtime
|
||||||
|
|
||||||
|
metadata_no_panic_strategy =
|
||||||
|
the crate `{$crate_name}` does not have the panic strategy `{$strategy}`
|
||||||
|
|
||||||
|
metadata_profiler_builtins_needs_core =
|
||||||
|
`profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
|
||||||
|
|
||||||
|
metadata_not_profiler_runtime =
|
||||||
|
the crate `{$crate_name}` is not a profiler runtime
|
||||||
|
|
||||||
|
metadata_no_multiple_global_alloc =
|
||||||
|
cannot define multiple global allocators
|
||||||
|
.label = cannot define a new global allocator
|
||||||
|
|
||||||
|
metadata_prev_global_alloc =
|
||||||
|
previous global allocator defined here
|
||||||
|
|
||||||
|
metadata_conflicting_global_alloc =
|
||||||
|
the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}
|
||||||
|
|
||||||
|
metadata_global_alloc_required =
|
||||||
|
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
|
||||||
|
|
||||||
|
metadata_no_transitive_needs_dep =
|
||||||
|
the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`
|
||||||
|
|
||||||
|
metadata_failed_write_error =
|
||||||
|
failed to write {$filename}: {$err}
|
||||||
|
|
||||||
|
metadata_failed_create_tempdir =
|
||||||
|
couldn't create a temp dir: {$err}
|
||||||
|
|
||||||
|
metadata_failed_create_file =
|
||||||
|
failed to create the file {$filename}: {$err}
|
||||||
|
|
||||||
|
metadata_failed_create_encoded_metadata =
|
||||||
|
failed to create encoded metadata from file: {$err}
|
||||||
|
|
||||||
|
metadata_non_ascii_name =
|
||||||
|
cannot load a crate with a non-ascii name `{$crate_name}`
|
||||||
|
|
||||||
|
metadata_extern_location_not_exist =
|
||||||
|
extern location for {$crate_name} does not exist: {$location}
|
||||||
|
|
||||||
|
metadata_extern_location_not_file =
|
||||||
|
extern location for {$crate_name} is not a file: {$location}
|
||||||
|
|
||||||
|
metadata_multiple_candidates =
|
||||||
|
multiple {$flavor} candidates for `{$crate_name}` found
|
||||||
|
|
||||||
|
metadata_multiple_matching_crates =
|
||||||
|
multiple matching crates for `{$crate_name}`
|
||||||
|
.note = candidates:{$candidates}
|
||||||
|
|
||||||
|
metadata_symbol_conflicts_current =
|
||||||
|
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
|
||||||
|
|
||||||
|
metadata_symbol_conflicts_others =
|
||||||
|
found two different crates with name `{$crate_name}` that are not distinguished by differing `-C metadata`. This will result in symbol conflicts between the two.
|
||||||
|
|
||||||
|
metadata_stable_crate_id_collision =
|
||||||
|
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
|
||||||
|
|
||||||
|
metadata_dl_error =
|
||||||
|
{$err}
|
||||||
|
|
||||||
|
metadata_newer_crate_version =
|
||||||
|
found possibly newer version of crate `{$crate_name}`{$add_info}
|
||||||
|
.note = perhaps that crate needs to be recompiled?
|
||||||
|
|
||||||
|
metadata_found_crate_versions =
|
||||||
|
the following crate versions were found:{$found_crates}
|
||||||
|
|
||||||
|
metadata_no_crate_with_triple =
|
||||||
|
couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}
|
||||||
|
|
||||||
|
metadata_found_staticlib =
|
||||||
|
found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
|
||||||
|
.help = please recompile that crate using --crate-type lib
|
||||||
|
|
||||||
|
metadata_incompatible_rustc =
|
||||||
|
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
|
||||||
|
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
|
||||||
|
|
||||||
|
metadata_invalid_meta_files =
|
||||||
|
found invalid metadata files for crate `{$crate_name}`{$add_info}
|
||||||
|
|
||||||
|
metadata_cannot_find_crate =
|
||||||
|
can't find crate for `{$crate_name}`{$add_info}
|
||||||
|
|
||||||
|
metadata_no_dylib_plugin =
|
||||||
|
plugin `{$crate_name}` only found in rlib format, but must be available in dylib format
|
||||||
|
|
||||||
|
metadata_target_not_installed =
|
||||||
|
the `{$locator_triple}` target may not be installed
|
||||||
|
|
||||||
|
metadata_target_no_std_support =
|
||||||
|
the `{$locator_triple}` target may not support the standard library
|
||||||
|
|
||||||
|
metadata_consider_downloading_target =
|
||||||
|
consider downloading the target with `rustup target add {$locator_triple}`
|
||||||
|
|
||||||
|
metadata_std_required =
|
||||||
|
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`
|
||||||
|
|
||||||
|
metadata_consider_building_std =
|
||||||
|
consider building the standard library from source with `cargo build -Zbuild-std`
|
||||||
|
|
||||||
|
metadata_compiler_missing_profiler =
|
||||||
|
the compiler may have been built without the profiler runtime
|
||||||
|
|
||||||
|
metadata_install_missing_components =
|
||||||
|
maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
|
||||||
|
|
||||||
|
metadata_cant_find_crate =
|
||||||
|
can't find crate
|
||||||
|
|
||||||
|
metadata_crate_location_unknown_type =
|
||||||
|
extern location for {$crate_name} is of an unknown type: {$path}
|
||||||
|
|
||||||
|
metadata_lib_filename_form =
|
||||||
|
file name should be lib*.rlib or {dll_prefix}*.{dll_suffix}
|
||||||
|
|
||||||
|
metadata_multiple_import_name_type =
|
||||||
|
multiple `import_name_type` arguments in a single `#[link]` attribute
|
||||||
|
|
||||||
|
metadata_import_name_type_form =
|
||||||
|
import name type must be of the form `import_name_type = "string"`
|
||||||
|
|
||||||
|
metadata_import_name_type_x86 =
|
||||||
|
import name type is only supported on x86
|
||||||
|
|
||||||
|
metadata_unknown_import_name_type =
|
||||||
|
unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
|
||||||
|
|
||||||
|
metadata_import_name_type_raw =
|
||||||
|
import name type can only be used with link kind `raw-dylib`
|
|
@ -48,6 +48,7 @@ fluent_messages! {
|
||||||
infer => "../locales/en-US/infer.ftl",
|
infer => "../locales/en-US/infer.ftl",
|
||||||
lint => "../locales/en-US/lint.ftl",
|
lint => "../locales/en-US/lint.ftl",
|
||||||
monomorphize => "../locales/en-US/monomorphize.ftl",
|
monomorphize => "../locales/en-US/monomorphize.ftl",
|
||||||
|
metadata => "../locales/en-US/metadata.ftl",
|
||||||
parser => "../locales/en-US/parser.ftl",
|
parser => "../locales/en-US/parser.ftl",
|
||||||
passes => "../locales/en-US/passes.ftl",
|
passes => "../locales/en-US/passes.ftl",
|
||||||
plugin_impl => "../locales/en-US/plugin_impl.ftl",
|
plugin_impl => "../locales/en-US/plugin_impl.ftl",
|
||||||
|
|
|
@ -15,13 +15,14 @@ rustc_macros = { path = "../rustc_macros" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_hir = { path = "../rustc_hir" }
|
rustc_hir = { path = "../rustc_hir" }
|
||||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||||
|
rustc_target = { path = "../rustc_target" }
|
||||||
unicode-width = "0.1.4"
|
unicode-width = "0.1.4"
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
termcolor = "1.0"
|
termcolor = "1.0"
|
||||||
annotate-snippets = "0.9"
|
annotate-snippets = "0.9"
|
||||||
termize = "0.1.1"
|
termize = "0.1.1"
|
||||||
serde = { version = "1.0.125", features = ["derive"] }
|
serde = { version = "1.0.125", features = [ "derive" ] }
|
||||||
serde_json = "1.0.59"
|
serde_json = "1.0.59"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }
|
winapi = { version = "0.3", features = [ "handleapi", "synchapi", "winbase" ] }
|
||||||
|
|
|
@ -10,6 +10,7 @@ use rustc_lint_defs::{Applicability, LintExpectationId};
|
||||||
use rustc_span::edition::LATEST_STABLE_EDITION;
|
use rustc_span::edition::LATEST_STABLE_EDITION;
|
||||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
||||||
use rustc_span::{edition::Edition, Span, DUMMY_SP};
|
use rustc_span::{edition::Edition, Span, DUMMY_SP};
|
||||||
|
use rustc_target::spec::PanicStrategy;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
@ -144,6 +145,12 @@ impl IntoDiagnosticArg for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoDiagnosticArg for PanicStrategy {
|
||||||
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||||
|
DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
|
impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
|
||||||
fn into(self) -> FluentValue<'source> {
|
fn into(self) -> FluentValue<'source> {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
//! Validates all used crates and extern libraries and loads their metadata
|
//! Validates all used crates and extern libraries and loads their metadata
|
||||||
|
|
||||||
|
use crate::errors::{
|
||||||
|
ConflictingGlobalAlloc, CrateNotPanicRuntime, GlobalAllocRequired, NoMultipleGlobalAlloc,
|
||||||
|
NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore,
|
||||||
|
};
|
||||||
use crate::locator::{CrateError, CrateLocator, CratePaths};
|
use crate::locator::{CrateError, CrateLocator, CratePaths};
|
||||||
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
|
use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob};
|
||||||
|
|
||||||
|
@ -745,15 +749,10 @@ impl<'a> CrateLoader<'a> {
|
||||||
// Sanity check the loaded crate to ensure it is indeed a panic runtime
|
// Sanity check the loaded crate to ensure it is indeed a panic runtime
|
||||||
// and the panic strategy is indeed what we thought it was.
|
// and the panic strategy is indeed what we thought it was.
|
||||||
if !data.is_panic_runtime() {
|
if !data.is_panic_runtime() {
|
||||||
self.sess.err(&format!("the crate `{}` is not a panic runtime", name));
|
self.sess.emit_err(CrateNotPanicRuntime { crate_name: name });
|
||||||
}
|
}
|
||||||
if data.required_panic_strategy() != Some(desired_strategy) {
|
if data.required_panic_strategy() != Some(desired_strategy) {
|
||||||
self.sess.err(&format!(
|
self.sess.emit_err(NoPanicStrategy { crate_name: name, strategy: desired_strategy });
|
||||||
"the crate `{}` does not have the panic \
|
|
||||||
strategy `{}`",
|
|
||||||
name,
|
|
||||||
desired_strategy.desc()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cstore.injected_panic_runtime = Some(cnum);
|
self.cstore.injected_panic_runtime = Some(cnum);
|
||||||
|
@ -773,10 +772,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
|
|
||||||
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
|
let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime);
|
||||||
if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
|
if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) {
|
||||||
self.sess.err(
|
self.sess.emit_err(ProfilerBuiltinsNeedsCore);
|
||||||
"`profiler_builtins` crate (required by compiler options) \
|
|
||||||
is not compatible with crate attribute `#![no_core]`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
|
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
|
||||||
|
@ -784,18 +780,14 @@ impl<'a> CrateLoader<'a> {
|
||||||
|
|
||||||
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
|
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
|
||||||
if !data.is_profiler_runtime() {
|
if !data.is_profiler_runtime() {
|
||||||
self.sess.err(&format!("the crate `{}` is not a profiler runtime", name));
|
self.sess.emit_err(NotProfilerRuntime { crate_name: name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
|
fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
|
||||||
self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
|
self.cstore.has_global_allocator = match &*global_allocator_spans(&self.sess, krate) {
|
||||||
[span1, span2, ..] => {
|
[span1, span2, ..] => {
|
||||||
self.sess
|
self.sess.emit_err(NoMultipleGlobalAlloc { span2: *span2, span1: *span1 });
|
||||||
.struct_span_err(*span2, "cannot define multiple global allocators")
|
|
||||||
.span_label(*span2, "cannot define a new global allocator")
|
|
||||||
.span_label(*span1, "previous global allocator defined here")
|
|
||||||
.emit();
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
spans => !spans.is_empty(),
|
spans => !spans.is_empty(),
|
||||||
|
@ -831,11 +823,10 @@ impl<'a> CrateLoader<'a> {
|
||||||
if data.has_global_allocator() {
|
if data.has_global_allocator() {
|
||||||
match global_allocator {
|
match global_allocator {
|
||||||
Some(other_crate) => {
|
Some(other_crate) => {
|
||||||
self.sess.err(&format!(
|
self.sess.emit_err(ConflictingGlobalAlloc {
|
||||||
"the `#[global_allocator]` in {} conflicts with global allocator in: {}",
|
crate_name: data.name(),
|
||||||
other_crate,
|
other_crate_name: other_crate,
|
||||||
data.name()
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
None => global_allocator = Some(data.name()),
|
None => global_allocator = Some(data.name()),
|
||||||
}
|
}
|
||||||
|
@ -854,10 +845,7 @@ impl<'a> CrateLoader<'a> {
|
||||||
if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator)
|
if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator)
|
||||||
&& !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator())
|
&& !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator())
|
||||||
{
|
{
|
||||||
self.sess.err(
|
self.sess.emit_err(GlobalAllocRequired);
|
||||||
"no global memory allocator found but one is required; link to std or add \
|
|
||||||
`#[global_allocator]` to a static item that implements the GlobalAlloc trait",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.cstore.allocator_kind = Some(AllocatorKind::Default);
|
self.cstore.allocator_kind = Some(AllocatorKind::Default);
|
||||||
}
|
}
|
||||||
|
@ -881,14 +869,11 @@ impl<'a> CrateLoader<'a> {
|
||||||
for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) {
|
for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) {
|
||||||
let data = self.cstore.get_crate_data(dep);
|
let data = self.cstore.get_crate_data(dep);
|
||||||
if needs_dep(&data) {
|
if needs_dep(&data) {
|
||||||
self.sess.err(&format!(
|
self.sess.emit_err(NoTransitiveNeedsDep {
|
||||||
"the crate `{}` cannot depend \
|
crate_name: self.cstore.get_crate_data(krate).name(),
|
||||||
on a crate that needs {}, but \
|
needs_crate_name: what,
|
||||||
it depends on `{}`",
|
deps_crate_name: data.name(),
|
||||||
self.cstore.get_crate_data(krate).name(),
|
});
|
||||||
what,
|
|
||||||
data.name()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,10 @@
|
||||||
//! than finding a number of solutions (there are normally quite a few).
|
//! than finding a number of solutions (there are normally quite a few).
|
||||||
|
|
||||||
use crate::creader::CStore;
|
use crate::creader::CStore;
|
||||||
|
use crate::errors::{
|
||||||
|
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
|
||||||
|
RequiredPanicStrategy, RlibRequired, TwoPanicRuntimes,
|
||||||
|
};
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::CrateNum;
|
use rustc_hir::def_id::CrateNum;
|
||||||
|
@ -136,11 +140,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
||||||
if src.rlib.is_some() {
|
if src.rlib.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sess.err(&format!(
|
sess.emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) });
|
||||||
"crate `{}` required to be available in rlib format, \
|
|
||||||
but was not found in this form",
|
|
||||||
tcx.crate_name(cnum)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
@ -224,12 +224,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
||||||
Linkage::Static => "rlib",
|
Linkage::Static => "rlib",
|
||||||
_ => "dylib",
|
_ => "dylib",
|
||||||
};
|
};
|
||||||
sess.err(&format!(
|
sess.emit_err(LibRequired { crate_name: tcx.crate_name(cnum), kind: kind });
|
||||||
"crate `{}` required to be available in {} format, \
|
|
||||||
but was not found in this form",
|
|
||||||
tcx.crate_name(cnum),
|
|
||||||
kind
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,17 +248,7 @@ fn add_library(
|
||||||
// This error is probably a little obscure, but I imagine that it
|
// This error is probably a little obscure, but I imagine that it
|
||||||
// can be refined over time.
|
// can be refined over time.
|
||||||
if link2 != link || link == RequireStatic {
|
if link2 != link || link == RequireStatic {
|
||||||
tcx.sess
|
tcx.sess.emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum) });
|
||||||
.struct_err(&format!(
|
|
||||||
"cannot satisfy dependencies so `{}` only \
|
|
||||||
shows up once",
|
|
||||||
tcx.crate_name(cnum)
|
|
||||||
))
|
|
||||||
.help(
|
|
||||||
"having upstream crates all available in one format \
|
|
||||||
will likely make this go away",
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -360,11 +345,7 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
|
||||||
if let Some((prev, _)) = panic_runtime {
|
if let Some((prev, _)) = panic_runtime {
|
||||||
let prev_name = tcx.crate_name(prev);
|
let prev_name = tcx.crate_name(prev);
|
||||||
let cur_name = tcx.crate_name(cnum);
|
let cur_name = tcx.crate_name(cnum);
|
||||||
sess.err(&format!(
|
sess.emit_err(TwoPanicRuntimes { prev_name, cur_name });
|
||||||
"cannot link together two \
|
|
||||||
panic runtimes: {} and {}",
|
|
||||||
prev_name, cur_name
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
panic_runtime = Some((
|
panic_runtime = Some((
|
||||||
cnum,
|
cnum,
|
||||||
|
@ -384,13 +365,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
|
||||||
// First up, validate that our selected panic runtime is indeed exactly
|
// First up, validate that our selected panic runtime is indeed exactly
|
||||||
// our same strategy.
|
// our same strategy.
|
||||||
if found_strategy != desired_strategy {
|
if found_strategy != desired_strategy {
|
||||||
sess.err(&format!(
|
sess.emit_err(BadPanicStrategy {
|
||||||
"the linked panic runtime `{}` is \
|
runtime: tcx.crate_name(runtime_cnum),
|
||||||
not compiled with this crate's \
|
strategy: desired_strategy,
|
||||||
panic strategy `{}`",
|
});
|
||||||
tcx.crate_name(runtime_cnum),
|
|
||||||
desired_strategy.desc()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next up, verify that all other crates are compatible with this panic
|
// Next up, verify that all other crates are compatible with this panic
|
||||||
|
@ -407,28 +385,19 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(found_strategy) = tcx.required_panic_strategy(cnum) && desired_strategy != found_strategy {
|
if let Some(found_strategy) = tcx.required_panic_strategy(cnum) && desired_strategy != found_strategy {
|
||||||
sess.err(&format!(
|
sess.emit_err(RequiredPanicStrategy {
|
||||||
"the crate `{}` requires \
|
crate_name: tcx.crate_name(cnum),
|
||||||
panic strategy `{}` which is \
|
found_strategy,
|
||||||
incompatible with this crate's \
|
desired_strategy});
|
||||||
strategy of `{}`",
|
|
||||||
tcx.crate_name(cnum),
|
|
||||||
found_strategy.desc(),
|
|
||||||
desired_strategy.desc()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
|
let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
|
||||||
if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
|
if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
|
||||||
sess.err(&format!(
|
sess.emit_err(IncompatiblePanicInDropStrategy {
|
||||||
"the crate `{}` is compiled with the \
|
crate_name: tcx.crate_name(cnum),
|
||||||
panic-in-drop strategy `{}` which is \
|
found_strategy: found_drop_strategy,
|
||||||
incompatible with this crate's \
|
desired_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
|
||||||
strategy of `{}`",
|
});
|
||||||
tcx.crate_name(cnum),
|
|
||||||
found_drop_strategy.desc(),
|
|
||||||
tcx.sess.opts.unstable_opts.panic_in_drop.desc()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
672
compiler/rustc_metadata/src/errors.rs
Normal file
672
compiler/rustc_metadata/src/errors.rs
Normal file
|
@ -0,0 +1,672 @@
|
||||||
|
use std::{
|
||||||
|
io::Error,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use rustc_errors::{error_code, ErrorGuaranteed};
|
||||||
|
use rustc_macros::SessionDiagnostic;
|
||||||
|
use rustc_session::{config, SessionDiagnostic};
|
||||||
|
use rustc_span::{sym, Span, Symbol};
|
||||||
|
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||||
|
|
||||||
|
use crate::locator::CrateFlavor;
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::rlib_required)]
|
||||||
|
pub struct RlibRequired {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::lib_required)]
|
||||||
|
pub struct LibRequired<'a> {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub kind: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::crate_dep_multiple)]
|
||||||
|
#[help]
|
||||||
|
pub struct CrateDepMultiple {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::two_panic_runtimes)]
|
||||||
|
pub struct TwoPanicRuntimes {
|
||||||
|
pub prev_name: Symbol,
|
||||||
|
pub cur_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::bad_panic_strategy)]
|
||||||
|
pub struct BadPanicStrategy {
|
||||||
|
pub runtime: Symbol,
|
||||||
|
pub strategy: PanicStrategy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::required_panic_strategy)]
|
||||||
|
pub struct RequiredPanicStrategy {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub found_strategy: PanicStrategy,
|
||||||
|
pub desired_strategy: PanicStrategy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::incompatible_panic_in_drop_strategy)]
|
||||||
|
pub struct IncompatiblePanicInDropStrategy {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub found_strategy: PanicStrategy,
|
||||||
|
pub desired_strategy: PanicStrategy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_names_in_link)]
|
||||||
|
pub struct MultipleNamesInLink {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_kinds_in_link)]
|
||||||
|
pub struct MultipleKindsInLink {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_name_form)]
|
||||||
|
pub struct LinkNameForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_kind_form)]
|
||||||
|
pub struct LinkKindForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_modifiers_form)]
|
||||||
|
pub struct LinkModifiersForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_cfg_form)]
|
||||||
|
pub struct LinkCfgForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::wasm_import_form)]
|
||||||
|
pub struct WasmImportForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::empty_link_name, code = "E0454")]
|
||||||
|
pub struct EmptyLinkName {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_framework_apple, code = "E0455")]
|
||||||
|
pub struct LinkFrameworkApple {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::framework_only_windows, code = "E0455")]
|
||||||
|
pub struct FrameworkOnlyWindows {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unknown_link_kind, code = "E0458")]
|
||||||
|
pub struct UnknownLinkKind<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub kind: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_link_modifiers)]
|
||||||
|
pub struct MultipleLinkModifiers {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_cfgs)]
|
||||||
|
pub struct MultipleCfgs {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_cfg_single_predicate)]
|
||||||
|
pub struct LinkCfgSinglePredicate {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_wasm_import)]
|
||||||
|
pub struct MultipleWasmImport {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unexpected_link_arg)]
|
||||||
|
pub struct UnexpectedLinkArg {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::invalid_link_modifier)]
|
||||||
|
pub struct InvalidLinkModifier {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_modifiers)]
|
||||||
|
pub struct MultipleModifiers<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub modifier: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::bundle_needs_static)]
|
||||||
|
pub struct BundleNeedsStatic {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::whole_archive_needs_static)]
|
||||||
|
pub struct WholeArchiveNeedsStatic {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::as_needed_compatibility)]
|
||||||
|
pub struct AsNeededCompatibility {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unknown_link_modifier)]
|
||||||
|
pub struct UnknownLinkModifier<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub modifier: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::incompatible_wasm_link)]
|
||||||
|
pub struct IncompatibleWasmLink {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_requires_name, code = "E0459")]
|
||||||
|
pub struct LinkRequiresName {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::raw_dylib_no_nul)]
|
||||||
|
pub struct RawDylibNoNul {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::link_ordinal_raw_dylib)]
|
||||||
|
pub struct LinkOrdinalRawDylib {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::lib_framework_apple)]
|
||||||
|
pub struct LibFrameworkApple;
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::empty_renaming_target)]
|
||||||
|
pub struct EmptyRenamingTarget<'a> {
|
||||||
|
pub lib_name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::renaming_no_link)]
|
||||||
|
pub struct RenamingNoLink<'a> {
|
||||||
|
pub lib_name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_renamings)]
|
||||||
|
pub struct MultipleRenamings<'a> {
|
||||||
|
pub lib_name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_link_mod_override)]
|
||||||
|
pub struct NoLinkModOverride {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Option<Span>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unsupported_abi_i686)]
|
||||||
|
pub struct UnsupportedAbiI686 {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unsupported_abi)]
|
||||||
|
pub struct UnsupportedAbi {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::fail_create_file_encoder)]
|
||||||
|
pub struct FailCreateFileEncoder {
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::fail_seek_file)]
|
||||||
|
pub struct FailSeekFile {
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::fail_write_file)]
|
||||||
|
pub struct FailWriteFile {
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::crate_not_panic_runtime)]
|
||||||
|
pub struct CrateNotPanicRuntime {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_panic_strategy)]
|
||||||
|
pub struct NoPanicStrategy {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub strategy: PanicStrategy,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::profiler_builtins_needs_core)]
|
||||||
|
pub struct ProfilerBuiltinsNeedsCore;
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::not_profiler_runtime)]
|
||||||
|
pub struct NotProfilerRuntime {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_multiple_global_alloc)]
|
||||||
|
pub struct NoMultipleGlobalAlloc {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span2: Span,
|
||||||
|
#[label(metadata::prev_global_alloc)]
|
||||||
|
pub span1: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::conflicting_global_alloc)]
|
||||||
|
pub struct ConflictingGlobalAlloc {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub other_crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::global_alloc_required)]
|
||||||
|
pub struct GlobalAllocRequired;
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_transitive_needs_dep)]
|
||||||
|
pub struct NoTransitiveNeedsDep<'a> {
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub needs_crate_name: &'a str,
|
||||||
|
pub deps_crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::failed_write_error)]
|
||||||
|
pub struct FailedWriteError {
|
||||||
|
pub filename: PathBuf,
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::failed_create_tempdir)]
|
||||||
|
pub struct FailedCreateTempdir {
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::failed_create_file)]
|
||||||
|
pub struct FailedCreateFile<'a> {
|
||||||
|
pub filename: &'a Path,
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::failed_create_encoded_metadata)]
|
||||||
|
pub struct FailedCreateEncodedMetadata {
|
||||||
|
pub err: Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::non_ascii_name)]
|
||||||
|
pub struct NonAsciiName {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::extern_location_not_exist)]
|
||||||
|
pub struct ExternLocationNotExist<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub location: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::extern_location_not_file)]
|
||||||
|
pub struct ExternLocationNotFile<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub location: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct MultipleCandidates {
|
||||||
|
pub span: Span,
|
||||||
|
pub flavor: CrateFlavor,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub candidates: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionDiagnostic<'_> for MultipleCandidates {
|
||||||
|
fn into_diagnostic(
|
||||||
|
self,
|
||||||
|
sess: &'_ rustc_session::parse::ParseSess,
|
||||||
|
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||||
|
let mut diag = sess.struct_err(rustc_errors::fluent::metadata::multiple_candidates);
|
||||||
|
diag.set_arg("crate_name", self.crate_name);
|
||||||
|
diag.set_arg("flavor", self.flavor);
|
||||||
|
diag.code(error_code!(E0465));
|
||||||
|
diag.set_span(self.span);
|
||||||
|
for (i, candidate) in self.candidates.iter().enumerate() {
|
||||||
|
diag.span_note(self.span, &format!("candidate #{}: {}", i + 1, candidate.display()));
|
||||||
|
}
|
||||||
|
diag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_matching_crates, code = "E0464")]
|
||||||
|
#[note]
|
||||||
|
pub struct MultipleMatchingCrates {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub candidates: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::symbol_conflicts_current, code = "E0519")]
|
||||||
|
pub struct SymbolConflictsCurrent {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::symbol_conflicts_others, code = "E0523")]
|
||||||
|
pub struct SymbolConflictsOthers {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::stable_crate_id_collision)]
|
||||||
|
pub struct StableCrateIdCollision {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name0: Symbol,
|
||||||
|
pub crate_name1: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::dl_error)]
|
||||||
|
pub struct DlError {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub err: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::newer_crate_version, code = "E0460")]
|
||||||
|
#[note]
|
||||||
|
#[note(metadata::found_crate_versions)]
|
||||||
|
pub struct NewerCrateVersion {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub add_info: String,
|
||||||
|
pub found_crates: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_crate_with_triple, code = "E0461")]
|
||||||
|
#[note(metadata::found_crate_versions)]
|
||||||
|
pub struct NoCrateWithTriple<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub locator_triple: &'a str,
|
||||||
|
pub add_info: String,
|
||||||
|
pub found_crates: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::found_staticlib, code = "E0462")]
|
||||||
|
#[note(metadata::found_crate_versions)]
|
||||||
|
#[help]
|
||||||
|
pub struct FoundStaticlib {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub add_info: String,
|
||||||
|
pub found_crates: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::incompatible_rustc, code = "E0514")]
|
||||||
|
#[note(metadata::found_crate_versions)]
|
||||||
|
#[help]
|
||||||
|
pub struct IncompatibleRustc {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub add_info: String,
|
||||||
|
pub found_crates: String,
|
||||||
|
pub rustc_version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InvalidMetadataFiles {
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub add_info: String,
|
||||||
|
pub crate_rejections: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionDiagnostic<'_> for InvalidMetadataFiles {
|
||||||
|
fn into_diagnostic(
|
||||||
|
self,
|
||||||
|
sess: &'_ rustc_session::parse::ParseSess,
|
||||||
|
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||||
|
let mut diag = sess.struct_err(rustc_errors::fluent::metadata::invalid_meta_files);
|
||||||
|
diag.set_arg("crate_name", self.crate_name);
|
||||||
|
diag.set_arg("add_info", self.add_info);
|
||||||
|
diag.code(error_code!(E0786));
|
||||||
|
diag.set_span(self.span);
|
||||||
|
for crate_rejection in self.crate_rejections {
|
||||||
|
diag.note(crate_rejection);
|
||||||
|
}
|
||||||
|
diag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CannotFindCrate {
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
pub add_info: String,
|
||||||
|
pub missing_core: bool,
|
||||||
|
pub current_crate: String,
|
||||||
|
pub is_nightly_build: bool,
|
||||||
|
pub profiler_runtime: Symbol,
|
||||||
|
pub locator_triple: TargetTriple,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionDiagnostic<'_> for CannotFindCrate {
|
||||||
|
fn into_diagnostic(
|
||||||
|
self,
|
||||||
|
sess: &'_ rustc_session::parse::ParseSess,
|
||||||
|
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||||
|
let mut diag = sess.struct_err(rustc_errors::fluent::metadata::cannot_find_crate);
|
||||||
|
diag.set_arg("crate_name", self.crate_name);
|
||||||
|
diag.set_arg("add_info", self.add_info);
|
||||||
|
diag.set_arg("locator_triple", self.locator_triple.triple());
|
||||||
|
diag.code(error_code!(E0463));
|
||||||
|
diag.set_span(self.span);
|
||||||
|
if (self.crate_name == sym::std || self.crate_name == sym::core)
|
||||||
|
&& self.locator_triple != TargetTriple::from_triple(config::host_triple())
|
||||||
|
{
|
||||||
|
if self.missing_core {
|
||||||
|
diag.note(rustc_errors::fluent::metadata::target_not_installed);
|
||||||
|
} else {
|
||||||
|
diag.note(rustc_errors::fluent::metadata::target_no_std_support);
|
||||||
|
}
|
||||||
|
// NOTE: this suggests using rustup, even though the user may not have it installed.
|
||||||
|
// That's because they could choose to install it; or this may give them a hint which
|
||||||
|
// target they need to install from their distro.
|
||||||
|
if self.missing_core {
|
||||||
|
diag.help(rustc_errors::fluent::metadata::consider_downloading_target);
|
||||||
|
}
|
||||||
|
// Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
|
||||||
|
// NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
|
||||||
|
// If it's not a dummy, that means someone added `extern crate std` explicitly and
|
||||||
|
// `#![no_std]` won't help.
|
||||||
|
if !self.missing_core && self.span.is_dummy() {
|
||||||
|
diag.note(rustc_errors::fluent::metadata::std_required);
|
||||||
|
}
|
||||||
|
if self.is_nightly_build {
|
||||||
|
diag.help(rustc_errors::fluent::metadata::consider_building_std);
|
||||||
|
}
|
||||||
|
} else if self.crate_name == self.profiler_runtime {
|
||||||
|
diag.note(rustc_errors::fluent::metadata::compiler_missing_profiler);
|
||||||
|
} else if self.crate_name.as_str().starts_with("rustc_") {
|
||||||
|
diag.help(rustc_errors::fluent::metadata::install_missing_components);
|
||||||
|
}
|
||||||
|
diag.span_label(self.span, rustc_errors::fluent::metadata::cant_find_crate);
|
||||||
|
diag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::no_dylib_plugin, code = "E0457")]
|
||||||
|
pub struct NoDylibPlugin {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::crate_location_unknown_type)]
|
||||||
|
pub struct CrateLocationUnknownType<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub path: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::lib_filename_form)]
|
||||||
|
pub struct LibFilenameForm<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub dll_prefix: &'a str,
|
||||||
|
pub dll_suffix: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::multiple_import_name_type)]
|
||||||
|
pub struct MultipleImportNameType {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::import_name_type_form)]
|
||||||
|
pub struct ImportNameTypeForm {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::import_name_type_x86)]
|
||||||
|
pub struct ImportNameTypeX86 {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::unknown_import_name_type)]
|
||||||
|
pub struct UnknownImportNameType<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub import_name_type: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[diag(metadata::import_name_type_raw)]
|
||||||
|
pub struct ImportNameTypeRaw {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::errors::{
|
||||||
|
FailedCreateEncodedMetadata, FailedCreateFile, FailedCreateTempdir, FailedWriteError,
|
||||||
|
};
|
||||||
use crate::{encode_metadata, EncodedMetadata};
|
use crate::{encode_metadata, EncodedMetadata};
|
||||||
|
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||||
|
@ -23,8 +26,8 @@ pub fn emit_metadata(sess: &Session, metadata: &[u8], tmpdir: &MaybeTempDir) ->
|
||||||
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
|
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
|
||||||
let result = fs::write(&out_filename, metadata);
|
let result = fs::write(&out_filename, metadata);
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(err) = result {
|
||||||
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
|
sess.emit_fatal(FailedWriteError { filename: out_filename, err });
|
||||||
}
|
}
|
||||||
|
|
||||||
out_filename
|
out_filename
|
||||||
|
@ -65,7 +68,7 @@ pub fn encode_and_write_metadata(
|
||||||
let metadata_tmpdir = TempFileBuilder::new()
|
let metadata_tmpdir = TempFileBuilder::new()
|
||||||
.prefix("rmeta")
|
.prefix("rmeta")
|
||||||
.tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
|
.tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new("")))
|
||||||
.unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
|
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailedCreateTempdir { err }));
|
||||||
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
|
let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
|
||||||
let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);
|
let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME);
|
||||||
|
|
||||||
|
@ -73,12 +76,8 @@ pub fn encode_and_write_metadata(
|
||||||
// This simplifies the creation of the output `out_filename` when requested.
|
// This simplifies the creation of the output `out_filename` when requested.
|
||||||
match metadata_kind {
|
match metadata_kind {
|
||||||
MetadataKind::None => {
|
MetadataKind::None => {
|
||||||
std::fs::File::create(&metadata_filename).unwrap_or_else(|e| {
|
std::fs::File::create(&metadata_filename).unwrap_or_else(|err| {
|
||||||
tcx.sess.fatal(&format!(
|
tcx.sess.emit_fatal(FailedCreateFile { filename: &metadata_filename, err });
|
||||||
"failed to create the file {}: {}",
|
|
||||||
metadata_filename.display(),
|
|
||||||
e
|
|
||||||
))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
MetadataKind::Uncompressed | MetadataKind::Compressed => {
|
MetadataKind::Uncompressed | MetadataKind::Compressed => {
|
||||||
|
@ -93,8 +92,8 @@ pub fn encode_and_write_metadata(
|
||||||
// this file always exists.
|
// this file always exists.
|
||||||
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
|
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||||
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
|
let (metadata_filename, metadata_tmpdir) = if need_metadata_file {
|
||||||
if let Err(e) = non_durable_rename(&metadata_filename, &out_filename) {
|
if let Err(err) = non_durable_rename(&metadata_filename, &out_filename) {
|
||||||
tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
|
tcx.sess.emit_fatal(FailedWriteError { filename: out_filename, err });
|
||||||
}
|
}
|
||||||
if tcx.sess.opts.json_artifact_notifications {
|
if tcx.sess.opts.json_artifact_notifications {
|
||||||
tcx.sess
|
tcx.sess
|
||||||
|
@ -109,8 +108,8 @@ pub fn encode_and_write_metadata(
|
||||||
|
|
||||||
// Load metadata back to memory: codegen may need to include it in object files.
|
// Load metadata back to memory: codegen may need to include it in object files.
|
||||||
let metadata =
|
let metadata =
|
||||||
EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|e| {
|
EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| {
|
||||||
tcx.sess.fatal(&format!("failed to create encoded metadata from file: {}", e))
|
tcx.sess.emit_fatal(FailedCreateEncodedMetadata { err });
|
||||||
});
|
});
|
||||||
|
|
||||||
let need_metadata_module = metadata_kind == MetadataKind::Compressed;
|
let need_metadata_module = metadata_kind == MetadataKind::Compressed;
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
@ -37,6 +39,7 @@ mod native_libs;
|
||||||
mod rmeta;
|
mod rmeta;
|
||||||
|
|
||||||
pub mod creader;
|
pub mod creader;
|
||||||
|
pub mod errors;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod locator;
|
pub mod locator;
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,13 @@
|
||||||
//! metadata::locator or metadata::creader for all the juicy details!
|
//! metadata::locator or metadata::creader for all the juicy details!
|
||||||
|
|
||||||
use crate::creader::Library;
|
use crate::creader::Library;
|
||||||
|
use crate::errors::{
|
||||||
|
CannotFindCrate, CrateLocationUnknownType, DlError, ExternLocationNotExist,
|
||||||
|
ExternLocationNotFile, FoundStaticlib, IncompatibleRustc, InvalidMetadataFiles,
|
||||||
|
LibFilenameForm, MultipleCandidates, MultipleMatchingCrates, NewerCrateVersion,
|
||||||
|
NoCrateWithTriple, NoDylibPlugin, NonAsciiName, StableCrateIdCollision, SymbolConflictsCurrent,
|
||||||
|
SymbolConflictsOthers,
|
||||||
|
};
|
||||||
use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
|
use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER};
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
@ -220,18 +227,19 @@ use rustc_data_structures::memmap::Mmap;
|
||||||
use rustc_data_structures::owning_ref::OwningRef;
|
use rustc_data_structures::owning_ref::OwningRef;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_data_structures::sync::MetadataRef;
|
use rustc_data_structures::sync::MetadataRef;
|
||||||
use rustc_errors::{struct_span_err, FatalError};
|
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
|
||||||
use rustc_session::config::{self, CrateType};
|
use rustc_session::config::{self, CrateType};
|
||||||
use rustc_session::cstore::{CrateSource, MetadataLoader};
|
use rustc_session::cstore::{CrateSource, MetadataLoader};
|
||||||
use rustc_session::filesearch::FileSearch;
|
use rustc_session::filesearch::FileSearch;
|
||||||
use rustc_session::search_paths::PathKind;
|
use rustc_session::search_paths::PathKind;
|
||||||
use rustc_session::utils::CanonicalizedPath;
|
use rustc_session::utils::CanonicalizedPath;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::{Target, TargetTriple};
|
use rustc_target::spec::{Target, TargetTriple};
|
||||||
|
|
||||||
use snap::read::FrameDecoder;
|
use snap::read::FrameDecoder;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::io::{Read, Result as IoResult, Write};
|
use std::io::{Read, Result as IoResult, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -287,6 +295,16 @@ impl fmt::Display for CrateFlavor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoDiagnosticArg for CrateFlavor {
|
||||||
|
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||||
|
match self {
|
||||||
|
CrateFlavor::Rlib => DiagnosticArgValue::Str(Cow::Borrowed("rlib")),
|
||||||
|
CrateFlavor::Rmeta => DiagnosticArgValue::Str(Cow::Borrowed("rmeta")),
|
||||||
|
CrateFlavor::Dylib => DiagnosticArgValue::Str(Cow::Borrowed("dylib")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> CrateLocator<'a> {
|
impl<'a> CrateLocator<'a> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
|
@ -937,41 +955,20 @@ impl fmt::Display for MetadataError<'_> {
|
||||||
|
|
||||||
impl CrateError {
|
impl CrateError {
|
||||||
pub(crate) fn report(self, sess: &Session, span: Span, missing_core: bool) {
|
pub(crate) fn report(self, sess: &Session, span: Span, missing_core: bool) {
|
||||||
let mut diag = match self {
|
match self {
|
||||||
CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
|
CrateError::NonAsciiName(crate_name) => {
|
||||||
span,
|
sess.emit_err(NonAsciiName { span, crate_name });
|
||||||
&format!("cannot load a crate with a non-ascii name `{}`", crate_name),
|
}
|
||||||
),
|
CrateError::ExternLocationNotExist(crate_name, loc) => {
|
||||||
CrateError::ExternLocationNotExist(crate_name, loc) => sess.struct_span_err(
|
sess.emit_err(ExternLocationNotExist { span, crate_name, location: &loc });
|
||||||
span,
|
}
|
||||||
&format!("extern location for {} does not exist: {}", crate_name, loc.display()),
|
CrateError::ExternLocationNotFile(crate_name, loc) => {
|
||||||
),
|
sess.emit_err(ExternLocationNotFile { span, crate_name, location: &loc });
|
||||||
CrateError::ExternLocationNotFile(crate_name, loc) => sess.struct_span_err(
|
}
|
||||||
span,
|
|
||||||
&format!("extern location for {} is not a file: {}", crate_name, loc.display()),
|
|
||||||
),
|
|
||||||
CrateError::MultipleCandidates(crate_name, flavor, candidates) => {
|
CrateError::MultipleCandidates(crate_name, flavor, candidates) => {
|
||||||
let mut err = struct_span_err!(
|
sess.emit_err(MultipleCandidates { span, flavor: flavor, crate_name, candidates });
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0465,
|
|
||||||
"multiple {} candidates for `{}` found",
|
|
||||||
flavor,
|
|
||||||
crate_name,
|
|
||||||
);
|
|
||||||
for (i, candidate) in candidates.iter().enumerate() {
|
|
||||||
err.span_note(span, &format!("candidate #{}: {}", i + 1, candidate.display()));
|
|
||||||
}
|
|
||||||
err
|
|
||||||
}
|
}
|
||||||
CrateError::MultipleMatchingCrates(crate_name, libraries) => {
|
CrateError::MultipleMatchingCrates(crate_name, libraries) => {
|
||||||
let mut err = struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0464,
|
|
||||||
"multiple matching crates for `{}`",
|
|
||||||
crate_name
|
|
||||||
);
|
|
||||||
let mut libraries: Vec<_> = libraries.into_values().collect();
|
let mut libraries: Vec<_> = libraries.into_values().collect();
|
||||||
// Make ordering of candidates deterministic.
|
// Make ordering of candidates deterministic.
|
||||||
// This has to `clone()` to work around lifetime restrictions with `sort_by_key()`.
|
// This has to `clone()` to work around lifetime restrictions with `sort_by_key()`.
|
||||||
|
@ -999,223 +996,142 @@ impl CrateError {
|
||||||
s
|
s
|
||||||
})
|
})
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
err.note(&format!("candidates:{}", candidates));
|
sess.emit_err(MultipleMatchingCrates { span, crate_name, candidates });
|
||||||
err
|
}
|
||||||
|
CrateError::SymbolConflictsCurrent(root_name) => {
|
||||||
|
sess.emit_err(SymbolConflictsCurrent { span, crate_name: root_name });
|
||||||
|
}
|
||||||
|
CrateError::SymbolConflictsOthers(root_name) => {
|
||||||
|
sess.emit_err(SymbolConflictsOthers { span, crate_name: root_name });
|
||||||
}
|
}
|
||||||
CrateError::SymbolConflictsCurrent(root_name) => struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0519,
|
|
||||||
"the current crate is indistinguishable from one of its dependencies: it has the \
|
|
||||||
same crate-name `{}` and was compiled with the same `-C metadata` arguments. \
|
|
||||||
This will result in symbol conflicts between the two.",
|
|
||||||
root_name,
|
|
||||||
),
|
|
||||||
CrateError::SymbolConflictsOthers(root_name) => struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0523,
|
|
||||||
"found two different crates with name `{}` that are not distinguished by differing \
|
|
||||||
`-C metadata`. This will result in symbol conflicts between the two.",
|
|
||||||
root_name,
|
|
||||||
),
|
|
||||||
CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
|
CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
|
||||||
let msg = format!(
|
sess.emit_err(StableCrateIdCollision {
|
||||||
"found crates (`{}` and `{}`) with colliding StableCrateId values.",
|
span,
|
||||||
crate_name0, crate_name1
|
crate_name0: crate_name0,
|
||||||
);
|
crate_name1: crate_name1,
|
||||||
sess.struct_span_err(span, &msg)
|
});
|
||||||
|
}
|
||||||
|
CrateError::DlOpen(s) | CrateError::DlSym(s) => {
|
||||||
|
sess.emit_err(DlError { span, err: s });
|
||||||
}
|
}
|
||||||
CrateError::DlOpen(s) | CrateError::DlSym(s) => sess.struct_span_err(span, &s),
|
|
||||||
CrateError::LocatorCombined(locator) => {
|
CrateError::LocatorCombined(locator) => {
|
||||||
let crate_name = locator.crate_name;
|
let crate_name = locator.crate_name;
|
||||||
let add = match &locator.root {
|
let add_info = match &locator.root {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(r) => format!(" which `{}` depends on", r.name),
|
Some(r) => format!(" which `{}` depends on", r.name),
|
||||||
};
|
};
|
||||||
let mut msg = "the following crate versions were found:".to_string();
|
// FIXME: There are no tests for CrateLocationUnknownType or LibFilenameForm
|
||||||
let mut err = if !locator.crate_rejections.via_hash.is_empty() {
|
if !locator.crate_rejections.via_filename.is_empty() {
|
||||||
let mut err = struct_span_err!(
|
let mismatches = locator.crate_rejections.via_filename.iter();
|
||||||
sess,
|
for CrateMismatch { path, .. } in mismatches {
|
||||||
span,
|
sess.emit_err(CrateLocationUnknownType { span, path: &path });
|
||||||
E0460,
|
sess.emit_err(LibFilenameForm {
|
||||||
"found possibly newer version of crate `{}`{}",
|
span,
|
||||||
crate_name,
|
dll_prefix: &locator.dll_prefix,
|
||||||
add,
|
dll_suffix: &locator.dll_suffix,
|
||||||
);
|
});
|
||||||
err.note("perhaps that crate needs to be recompiled?");
|
}
|
||||||
|
}
|
||||||
|
let mut found_crates = String::new();
|
||||||
|
if !locator.crate_rejections.via_hash.is_empty() {
|
||||||
let mismatches = locator.crate_rejections.via_hash.iter();
|
let mismatches = locator.crate_rejections.via_hash.iter();
|
||||||
for CrateMismatch { path, .. } in mismatches {
|
for CrateMismatch { path, .. } in mismatches {
|
||||||
msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display()));
|
found_crates.push_str(&format!(
|
||||||
|
"\ncrate `{}`: {}",
|
||||||
|
crate_name,
|
||||||
|
path.display()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if let Some(r) = locator.root {
|
if let Some(r) = locator.root {
|
||||||
for path in r.source.paths() {
|
for path in r.source.paths() {
|
||||||
msg.push_str(&format!("\ncrate `{}`: {}", r.name, path.display()));
|
found_crates.push_str(&format!(
|
||||||
|
"\ncrate `{}`: {}",
|
||||||
|
r.name,
|
||||||
|
path.display()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.note(&msg);
|
sess.emit_err(NewerCrateVersion {
|
||||||
err
|
|
||||||
} else if !locator.crate_rejections.via_triple.is_empty() {
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
span,
|
||||||
E0461,
|
crate_name: crate_name,
|
||||||
"couldn't find crate `{}` with expected target triple {}{}",
|
add_info,
|
||||||
crate_name,
|
found_crates,
|
||||||
locator.triple,
|
});
|
||||||
add,
|
} else if !locator.crate_rejections.via_triple.is_empty() {
|
||||||
);
|
|
||||||
let mismatches = locator.crate_rejections.via_triple.iter();
|
let mismatches = locator.crate_rejections.via_triple.iter();
|
||||||
for CrateMismatch { path, got } in mismatches {
|
for CrateMismatch { path, got } in mismatches {
|
||||||
msg.push_str(&format!(
|
found_crates.push_str(&format!(
|
||||||
"\ncrate `{}`, target triple {}: {}",
|
"\ncrate `{}`, target triple {}: {}",
|
||||||
crate_name,
|
crate_name,
|
||||||
got,
|
got,
|
||||||
path.display(),
|
path.display(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
err.note(&msg);
|
sess.emit_err(NoCrateWithTriple {
|
||||||
err
|
|
||||||
} else if !locator.crate_rejections.via_kind.is_empty() {
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
span,
|
||||||
E0462,
|
crate_name: crate_name,
|
||||||
"found staticlib `{}` instead of rlib or dylib{}",
|
locator_triple: locator.triple.triple(),
|
||||||
crate_name,
|
add_info,
|
||||||
add,
|
found_crates,
|
||||||
);
|
});
|
||||||
err.help("please recompile that crate using --crate-type lib");
|
} else if !locator.crate_rejections.via_kind.is_empty() {
|
||||||
let mismatches = locator.crate_rejections.via_kind.iter();
|
let mismatches = locator.crate_rejections.via_kind.iter();
|
||||||
for CrateMismatch { path, .. } in mismatches {
|
for CrateMismatch { path, .. } in mismatches {
|
||||||
msg.push_str(&format!("\ncrate `{}`: {}", crate_name, path.display()));
|
found_crates.push_str(&format!(
|
||||||
|
"\ncrate `{}`: {}",
|
||||||
|
crate_name,
|
||||||
|
path.display()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
err.note(&msg);
|
sess.emit_err(FoundStaticlib { span, crate_name, add_info, found_crates });
|
||||||
err
|
|
||||||
} else if !locator.crate_rejections.via_version.is_empty() {
|
} else if !locator.crate_rejections.via_version.is_empty() {
|
||||||
let mut err = struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0514,
|
|
||||||
"found crate `{}` compiled by an incompatible version of rustc{}",
|
|
||||||
crate_name,
|
|
||||||
add,
|
|
||||||
);
|
|
||||||
err.help(&format!(
|
|
||||||
"please recompile that crate using this compiler ({}) \
|
|
||||||
(consider running `cargo clean` first)",
|
|
||||||
rustc_version(),
|
|
||||||
));
|
|
||||||
let mismatches = locator.crate_rejections.via_version.iter();
|
let mismatches = locator.crate_rejections.via_version.iter();
|
||||||
for CrateMismatch { path, got } in mismatches {
|
for CrateMismatch { path, got } in mismatches {
|
||||||
msg.push_str(&format!(
|
found_crates.push_str(&format!(
|
||||||
"\ncrate `{}` compiled by {}: {}",
|
"\ncrate `{}` compiled by {}: {}",
|
||||||
crate_name,
|
crate_name,
|
||||||
got,
|
got,
|
||||||
path.display(),
|
path.display(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
err.note(&msg);
|
sess.emit_err(IncompatibleRustc {
|
||||||
err
|
span,
|
||||||
|
crate_name,
|
||||||
|
add_info,
|
||||||
|
found_crates,
|
||||||
|
rustc_version: rustc_version(),
|
||||||
|
});
|
||||||
} else if !locator.crate_rejections.via_invalid.is_empty() {
|
} else if !locator.crate_rejections.via_invalid.is_empty() {
|
||||||
let mut err = struct_span_err!(
|
let mut crate_rejections = Vec::new();
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0786,
|
|
||||||
"found invalid metadata files for crate `{}`{}",
|
|
||||||
crate_name,
|
|
||||||
add,
|
|
||||||
);
|
|
||||||
for CrateMismatch { path: _, got } in locator.crate_rejections.via_invalid {
|
for CrateMismatch { path: _, got } in locator.crate_rejections.via_invalid {
|
||||||
err.note(&got);
|
crate_rejections.push(got);
|
||||||
}
|
}
|
||||||
err
|
sess.emit_err(InvalidMetadataFiles {
|
||||||
} else {
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
sess,
|
|
||||||
span,
|
span,
|
||||||
E0463,
|
|
||||||
"can't find crate for `{}`{}",
|
|
||||||
crate_name,
|
crate_name,
|
||||||
add,
|
add_info,
|
||||||
);
|
crate_rejections,
|
||||||
|
});
|
||||||
if (crate_name == sym::std || crate_name == sym::core)
|
} else {
|
||||||
&& locator.triple != TargetTriple::from_triple(config::host_triple())
|
sess.emit_err(CannotFindCrate {
|
||||||
{
|
span,
|
||||||
if missing_core {
|
crate_name,
|
||||||
err.note(&format!(
|
add_info,
|
||||||
"the `{}` target may not be installed",
|
missing_core,
|
||||||
locator.triple
|
current_crate: sess
|
||||||
));
|
.opts
|
||||||
} else {
|
.crate_name
|
||||||
err.note(&format!(
|
.clone()
|
||||||
"the `{}` target may not support the standard library",
|
.unwrap_or("<unknown>".to_string()),
|
||||||
locator.triple
|
is_nightly_build: sess.is_nightly_build(),
|
||||||
));
|
profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
|
||||||
}
|
locator_triple: locator.triple,
|
||||||
// NOTE: this suggests using rustup, even though the user may not have it installed.
|
});
|
||||||
// That's because they could choose to install it; or this may give them a hint which
|
|
||||||
// target they need to install from their distro.
|
|
||||||
if missing_core {
|
|
||||||
err.help(&format!(
|
|
||||||
"consider downloading the target with `rustup target add {}`",
|
|
||||||
locator.triple
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
|
|
||||||
// NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
|
|
||||||
// If it's not a dummy, that means someone added `extern crate std` explicitly and `#![no_std]` won't help.
|
|
||||||
if !missing_core && span.is_dummy() {
|
|
||||||
let current_crate =
|
|
||||||
sess.opts.crate_name.as_deref().unwrap_or("<unknown>");
|
|
||||||
err.note(&format!(
|
|
||||||
"`std` is required by `{}` because it does not declare `#![no_std]`",
|
|
||||||
current_crate
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if sess.is_nightly_build() {
|
|
||||||
err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
|
|
||||||
}
|
|
||||||
} else if crate_name
|
|
||||||
== Symbol::intern(&sess.opts.unstable_opts.profiler_runtime)
|
|
||||||
{
|
|
||||||
err.note("the compiler may have been built without the profiler runtime");
|
|
||||||
} else if crate_name.as_str().starts_with("rustc_") {
|
|
||||||
err.help(
|
|
||||||
"maybe you need to install the missing components with: \
|
|
||||||
`rustup component add rust-src rustc-dev llvm-tools-preview`",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
err.span_label(span, "can't find crate");
|
|
||||||
err
|
|
||||||
};
|
|
||||||
|
|
||||||
if !locator.crate_rejections.via_filename.is_empty() {
|
|
||||||
let mismatches = locator.crate_rejections.via_filename.iter();
|
|
||||||
for CrateMismatch { path, .. } in mismatches {
|
|
||||||
err.note(&format!(
|
|
||||||
"extern location for {} is of an unknown type: {}",
|
|
||||||
crate_name,
|
|
||||||
path.display(),
|
|
||||||
))
|
|
||||||
.help(&format!(
|
|
||||||
"file name should be lib*.rlib or {}*.{}",
|
|
||||||
locator.dll_prefix, locator.dll_suffix
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err
|
|
||||||
}
|
}
|
||||||
CrateError::NonDylibPlugin(crate_name) => struct_span_err!(
|
CrateError::NonDylibPlugin(crate_name) => {
|
||||||
sess,
|
sess.emit_err(NoDylibPlugin { span, crate_name });
|
||||||
span,
|
}
|
||||||
E0457,
|
}
|
||||||
"plugin `{}` only found in rlib format, but must be available in dylib format",
|
|
||||||
crate_name,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
diag.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
|
use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::struct_span_err;
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
|
use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
|
||||||
|
@ -12,6 +11,18 @@ use rustc_session::Session;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
|
use crate::errors::{
|
||||||
|
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, EmptyRenamingTarget,
|
||||||
|
FrameworkOnlyWindows, ImportNameTypeForm, ImportNameTypeRaw, ImportNameTypeX86,
|
||||||
|
IncompatibleWasmLink, InvalidLinkModifier, LibFrameworkApple, LinkCfgForm,
|
||||||
|
LinkCfgSinglePredicate, LinkFrameworkApple, LinkKindForm, LinkModifiersForm, LinkNameForm,
|
||||||
|
LinkOrdinalRawDylib, LinkRequiresName, MultipleCfgs, MultipleImportNameType,
|
||||||
|
MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers, MultipleNamesInLink,
|
||||||
|
MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul, RenamingNoLink,
|
||||||
|
UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier, UnsupportedAbi,
|
||||||
|
UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
|
pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
|
||||||
let mut collector = Collector { tcx, libs: Vec::new() };
|
let mut collector = Collector { tcx, libs: Vec::new() };
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
|
@ -66,32 +77,26 @@ impl<'tcx> Collector<'tcx> {
|
||||||
match item.name_or_empty() {
|
match item.name_or_empty() {
|
||||||
sym::name => {
|
sym::name => {
|
||||||
if name.is_some() {
|
if name.is_some() {
|
||||||
let msg = "multiple `name` arguments in a single `#[link]` attribute";
|
sess.emit_err(MultipleNamesInLink { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_name) = item.value_str() else {
|
let Some(link_name) = item.value_str() else {
|
||||||
let msg = "link name must be of the form `name = \"string\"`";
|
sess.emit_err(LinkNameForm { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let span = item.name_value_literal_span().unwrap();
|
let span = item.name_value_literal_span().unwrap();
|
||||||
if link_name.is_empty() {
|
if link_name.is_empty() {
|
||||||
struct_span_err!(sess, span, E0454, "link name must not be empty")
|
sess.emit_err(EmptyLinkName { span });
|
||||||
.span_label(span, "empty link name")
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
name = Some((link_name, span));
|
name = Some((link_name, span));
|
||||||
}
|
}
|
||||||
sym::kind => {
|
sym::kind => {
|
||||||
if kind.is_some() {
|
if kind.is_some() {
|
||||||
let msg = "multiple `kind` arguments in a single `#[link]` attribute";
|
sess.emit_err(MultipleKindsInLink { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_kind) = item.value_str() else {
|
let Some(link_kind) = item.value_str() else {
|
||||||
let msg = "link kind must be of the form `kind = \"string\"`";
|
sess.emit_err(LinkKindForm { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,25 +106,13 @@ impl<'tcx> Collector<'tcx> {
|
||||||
"dylib" => NativeLibKind::Dylib { as_needed: None },
|
"dylib" => NativeLibKind::Dylib { as_needed: None },
|
||||||
"framework" => {
|
"framework" => {
|
||||||
if !sess.target.is_like_osx {
|
if !sess.target.is_like_osx {
|
||||||
struct_span_err!(
|
sess.emit_err(LinkFrameworkApple { span });
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0455,
|
|
||||||
"link kind `framework` is only supported on Apple targets"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
NativeLibKind::Framework { as_needed: None }
|
NativeLibKind::Framework { as_needed: None }
|
||||||
}
|
}
|
||||||
"raw-dylib" => {
|
"raw-dylib" => {
|
||||||
if !sess.target.is_like_windows {
|
if !sess.target.is_like_windows {
|
||||||
struct_span_err!(
|
sess.emit_err(FrameworkOnlyWindows { span });
|
||||||
sess,
|
|
||||||
span,
|
|
||||||
E0455,
|
|
||||||
"link kind `raw-dylib` is only supported on Windows targets"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
} else if !features.raw_dylib {
|
} else if !features.raw_dylib {
|
||||||
feature_err(
|
feature_err(
|
||||||
&sess.parse_sess,
|
&sess.parse_sess,
|
||||||
|
@ -132,13 +125,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
NativeLibKind::RawDylib
|
NativeLibKind::RawDylib
|
||||||
}
|
}
|
||||||
kind => {
|
kind => {
|
||||||
let msg = format!(
|
sess.emit_err(UnknownLinkKind { span, kind });
|
||||||
"unknown link kind `{kind}`, expected one of: \
|
|
||||||
static, dylib, framework, raw-dylib"
|
|
||||||
);
|
|
||||||
struct_span_err!(sess, span, E0458, "{}", msg)
|
|
||||||
.span_label(span, "unknown link kind")
|
|
||||||
.emit();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -146,32 +133,26 @@ impl<'tcx> Collector<'tcx> {
|
||||||
}
|
}
|
||||||
sym::modifiers => {
|
sym::modifiers => {
|
||||||
if modifiers.is_some() {
|
if modifiers.is_some() {
|
||||||
let msg =
|
sess.emit_err(MultipleLinkModifiers { span: item.span() });
|
||||||
"multiple `modifiers` arguments in a single `#[link]` attribute";
|
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_modifiers) = item.value_str() else {
|
let Some(link_modifiers) = item.value_str() else {
|
||||||
let msg = "link modifiers must be of the form `modifiers = \"string\"`";
|
sess.emit_err(LinkModifiersForm { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
|
modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
|
||||||
}
|
}
|
||||||
sym::cfg => {
|
sym::cfg => {
|
||||||
if cfg.is_some() {
|
if cfg.is_some() {
|
||||||
let msg = "multiple `cfg` arguments in a single `#[link]` attribute";
|
sess.emit_err(MultipleCfgs { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_cfg) = item.meta_item_list() else {
|
let Some(link_cfg) = item.meta_item_list() else {
|
||||||
let msg = "link cfg must be of the form `cfg(/* predicate */)`";
|
sess.emit_err(LinkCfgForm { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
|
let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
|
||||||
let msg = "link cfg must have a single predicate argument";
|
sess.emit_err(LinkCfgSinglePredicate { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if !features.link_cfg {
|
if !features.link_cfg {
|
||||||
|
@ -187,33 +168,26 @@ impl<'tcx> Collector<'tcx> {
|
||||||
}
|
}
|
||||||
sym::wasm_import_module => {
|
sym::wasm_import_module => {
|
||||||
if wasm_import_module.is_some() {
|
if wasm_import_module.is_some() {
|
||||||
let msg = "multiple `wasm_import_module` arguments \
|
sess.emit_err(MultipleWasmImport { span: item.span() });
|
||||||
in a single `#[link]` attribute";
|
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_wasm_import_module) = item.value_str() else {
|
let Some(link_wasm_import_module) = item.value_str() else {
|
||||||
let msg = "wasm import module must be of the form \
|
sess.emit_err(WasmImportForm { span: item.span() });
|
||||||
`wasm_import_module = \"string\"`";
|
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
wasm_import_module = Some((link_wasm_import_module, item.span()));
|
wasm_import_module = Some((link_wasm_import_module, item.span()));
|
||||||
}
|
}
|
||||||
sym::import_name_type => {
|
sym::import_name_type => {
|
||||||
if import_name_type.is_some() {
|
if import_name_type.is_some() {
|
||||||
let msg = "multiple `import_name_type` arguments in a single `#[link]` attribute";
|
sess.emit_err(MultipleImportNameType { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(link_import_name_type) = item.value_str() else {
|
let Some(link_import_name_type) = item.value_str() else {
|
||||||
let msg = "import name type must be of the form `import_name_type = \"string\"`";
|
sess.emit_err(ImportNameTypeForm { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if self.tcx.sess.target.arch != "x86" {
|
if self.tcx.sess.target.arch != "x86" {
|
||||||
let msg = "import name type is only supported on x86";
|
sess.emit_err(ImportNameTypeX86 { span: item.span() });
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,11 +196,10 @@ impl<'tcx> Collector<'tcx> {
|
||||||
"noprefix" => PeImportNameType::NoPrefix,
|
"noprefix" => PeImportNameType::NoPrefix,
|
||||||
"undecorated" => PeImportNameType::Undecorated,
|
"undecorated" => PeImportNameType::Undecorated,
|
||||||
import_name_type => {
|
import_name_type => {
|
||||||
let msg = format!(
|
sess.emit_err(UnknownImportNameType {
|
||||||
"unknown import name type `{import_name_type}`, expected one of: \
|
span: item.span(),
|
||||||
decorated, noprefix, undecorated"
|
import_name_type,
|
||||||
);
|
});
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -243,9 +216,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
import_name_type = Some((link_import_name_type, item.span()));
|
import_name_type = Some((link_import_name_type, item.span()));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let msg = "unexpected `#[link]` argument, expected one of: \
|
sess.emit_err(UnexpectedLinkArg { span: item.span() });
|
||||||
name, kind, modifiers, cfg, wasm_import_module, import_name_type";
|
|
||||||
sess.span_err(item.span(), msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,11 +228,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
|
let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
|
||||||
Some(m) => (m, modifier.starts_with('+')),
|
Some(m) => (m, modifier.starts_with('+')),
|
||||||
None => {
|
None => {
|
||||||
sess.span_err(
|
sess.emit_err(InvalidLinkModifier { span });
|
||||||
span,
|
|
||||||
"invalid linking modifier syntax, expected '+' or '-' prefix \
|
|
||||||
before one of: bundle, verbatim, whole-archive, as-needed",
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -279,10 +246,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
}
|
}
|
||||||
let assign_modifier = |dst: &mut Option<bool>| {
|
let assign_modifier = |dst: &mut Option<bool>| {
|
||||||
if dst.is_some() {
|
if dst.is_some() {
|
||||||
let msg = format!(
|
sess.emit_err(MultipleModifiers { span, modifier });
|
||||||
"multiple `{modifier}` modifiers in a single `modifiers` argument"
|
|
||||||
);
|
|
||||||
sess.span_err(span, &msg);
|
|
||||||
} else {
|
} else {
|
||||||
*dst = Some(value);
|
*dst = Some(value);
|
||||||
}
|
}
|
||||||
|
@ -292,11 +256,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
assign_modifier(bundle)
|
assign_modifier(bundle)
|
||||||
}
|
}
|
||||||
("bundle", _) => {
|
("bundle", _) => {
|
||||||
sess.span_err(
|
sess.emit_err(BundleNeedsStatic { span });
|
||||||
span,
|
|
||||||
"linking modifier `bundle` is only compatible with \
|
|
||||||
`static` linking kind",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
("verbatim", _) => {
|
("verbatim", _) => {
|
||||||
|
@ -308,11 +268,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
assign_modifier(whole_archive)
|
assign_modifier(whole_archive)
|
||||||
}
|
}
|
||||||
("whole-archive", _) => {
|
("whole-archive", _) => {
|
||||||
sess.span_err(
|
sess.emit_err(WholeArchiveNeedsStatic { span });
|
||||||
span,
|
|
||||||
"linking modifier `whole-archive` is only compatible with \
|
|
||||||
`static` linking kind",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
("as-needed", Some(NativeLibKind::Dylib { as_needed }))
|
("as-needed", Some(NativeLibKind::Dylib { as_needed }))
|
||||||
|
@ -321,21 +277,11 @@ impl<'tcx> Collector<'tcx> {
|
||||||
assign_modifier(as_needed)
|
assign_modifier(as_needed)
|
||||||
}
|
}
|
||||||
("as-needed", _) => {
|
("as-needed", _) => {
|
||||||
sess.span_err(
|
sess.emit_err(AsNeededCompatibility { span });
|
||||||
span,
|
|
||||||
"linking modifier `as-needed` is only compatible with \
|
|
||||||
`dylib` and `framework` linking kinds",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
sess.span_err(
|
sess.emit_err(UnknownLinkModifier { span, modifier });
|
||||||
span,
|
|
||||||
format!(
|
|
||||||
"unknown linking modifier `{modifier}`, expected one of: \
|
|
||||||
bundle, verbatim, whole-archive, as-needed"
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,36 +289,23 @@ impl<'tcx> Collector<'tcx> {
|
||||||
|
|
||||||
if let Some((_, span)) = wasm_import_module {
|
if let Some((_, span)) = wasm_import_module {
|
||||||
if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
|
if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
|
||||||
let msg = "`wasm_import_module` is incompatible with \
|
sess.emit_err(IncompatibleWasmLink { span });
|
||||||
other arguments in `#[link]` attributes";
|
|
||||||
sess.span_err(span, msg);
|
|
||||||
}
|
}
|
||||||
} else if name.is_none() {
|
} else if name.is_none() {
|
||||||
struct_span_err!(
|
sess.emit_err(LinkRequiresName { span: m.span });
|
||||||
sess,
|
|
||||||
m.span,
|
|
||||||
E0459,
|
|
||||||
"`#[link]` attribute requires a `name = \"string\"` argument"
|
|
||||||
)
|
|
||||||
.span_label(m.span, "missing `name` argument")
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
|
// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
|
||||||
if let Some((_, span)) = import_name_type {
|
if let Some((_, span)) = import_name_type {
|
||||||
if kind != Some(NativeLibKind::RawDylib) {
|
if kind != Some(NativeLibKind::RawDylib) {
|
||||||
let msg = "import name type can only be used with link kind `raw-dylib`";
|
sess.emit_err(ImportNameTypeRaw { span });
|
||||||
sess.span_err(span, msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dll_imports = match kind {
|
let dll_imports = match kind {
|
||||||
Some(NativeLibKind::RawDylib) => {
|
Some(NativeLibKind::RawDylib) => {
|
||||||
if let Some((name, span)) = name && name.as_str().contains('\0') {
|
if let Some((name, span)) = name && name.as_str().contains('\0') {
|
||||||
sess.span_err(
|
sess.emit_err(RawDylibNoNul { span });
|
||||||
span,
|
|
||||||
"link name must not contain NUL characters if link kind is `raw-dylib`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
foreign_mod_items
|
foreign_mod_items
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -401,10 +334,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.find(|a| a.has_name(sym::link_ordinal))
|
.find(|a| a.has_name(sym::link_ordinal))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
sess.span_err(
|
sess.emit_err(LinkOrdinalRawDylib { span: link_ordinal_attr.span });
|
||||||
link_ordinal_attr.span,
|
|
||||||
"`#[link_ordinal]` is only supported if link kind is `raw-dylib`",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +360,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
for lib in &self.tcx.sess.opts.libs {
|
for lib in &self.tcx.sess.opts.libs {
|
||||||
if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx {
|
if let NativeLibKind::Framework { .. } = lib.kind && !self.tcx.sess.target.is_like_osx {
|
||||||
// Cannot check this when parsing options because the target is not yet available.
|
// Cannot check this when parsing options because the target is not yet available.
|
||||||
self.tcx.sess.err("library kind `framework` is only supported on Apple targets");
|
self.tcx.sess.emit_err(LibFrameworkApple);
|
||||||
}
|
}
|
||||||
if let Some(ref new_name) = lib.new_name {
|
if let Some(ref new_name) = lib.new_name {
|
||||||
let any_duplicate = self
|
let any_duplicate = self
|
||||||
|
@ -439,23 +369,11 @@ impl<'tcx> Collector<'tcx> {
|
||||||
.filter_map(|lib| lib.name.as_ref())
|
.filter_map(|lib| lib.name.as_ref())
|
||||||
.any(|n| n.as_str() == lib.name);
|
.any(|n| n.as_str() == lib.name);
|
||||||
if new_name.is_empty() {
|
if new_name.is_empty() {
|
||||||
self.tcx.sess.err(format!(
|
self.tcx.sess.emit_err(EmptyRenamingTarget { lib_name: &lib.name });
|
||||||
"an empty renaming target was specified for library `{}`",
|
|
||||||
lib.name
|
|
||||||
));
|
|
||||||
} else if !any_duplicate {
|
} else if !any_duplicate {
|
||||||
self.tcx.sess.err(format!(
|
self.tcx.sess.emit_err(RenamingNoLink { lib_name: &lib.name });
|
||||||
"renaming of the library `{}` was specified, \
|
|
||||||
however this crate contains no `#[link(...)]` \
|
|
||||||
attributes referencing this library",
|
|
||||||
lib.name
|
|
||||||
));
|
|
||||||
} else if !renames.insert(&lib.name) {
|
} else if !renames.insert(&lib.name) {
|
||||||
self.tcx.sess.err(format!(
|
self.tcx.sess.emit_err(MultipleRenamings { lib_name: &lib.name });
|
||||||
"multiple renamings were \
|
|
||||||
specified for library `{}`",
|
|
||||||
lib.name
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,10 +398,13 @@ impl<'tcx> Collector<'tcx> {
|
||||||
// involved or not, library reordering and kind overriding without
|
// involved or not, library reordering and kind overriding without
|
||||||
// explicit `:rename` in particular.
|
// explicit `:rename` in particular.
|
||||||
if lib.has_modifiers() || passed_lib.has_modifiers() {
|
if lib.has_modifiers() || passed_lib.has_modifiers() {
|
||||||
let msg = "overriding linking modifiers from command line is not supported";
|
|
||||||
match lib.foreign_module {
|
match lib.foreign_module {
|
||||||
Some(def_id) => self.tcx.sess.span_err(self.tcx.def_span(def_id), msg),
|
Some(def_id) => self.tcx.sess.emit_err(NoLinkModOverride {
|
||||||
None => self.tcx.sess.err(msg),
|
span: Some(self.tcx.def_span(def_id)),
|
||||||
|
}),
|
||||||
|
None => {
|
||||||
|
self.tcx.sess.emit_err(NoLinkModOverride { span: None })
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if passed_lib.kind != NativeLibKind::Unspecified {
|
if passed_lib.kind != NativeLibKind::Unspecified {
|
||||||
|
@ -562,20 +483,14 @@ impl<'tcx> Collector<'tcx> {
|
||||||
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
|
DllCallingConvention::Vectorcall(self.i686_arg_list_size(item))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx.sess.emit_fatal(UnsupportedAbiI686 { span: item.span });
|
||||||
item.span,
|
|
||||||
r#"ABI not supported by `#[link(kind = "raw-dylib")]` on i686"#,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match abi {
|
match abi {
|
||||||
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
|
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx.sess.emit_fatal(UnsupportedAbi { span: item.span });
|
||||||
item.span,
|
|
||||||
r#"ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture"#,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile};
|
||||||
use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
|
use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
|
||||||
use crate::rmeta::table::TableBuilder;
|
use crate::rmeta::table::TableBuilder;
|
||||||
use crate::rmeta::*;
|
use crate::rmeta::*;
|
||||||
|
@ -2195,7 +2196,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
|
||||||
|
|
||||||
fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
||||||
let mut encoder = opaque::FileEncoder::new(path)
|
let mut encoder = opaque::FileEncoder::new(path)
|
||||||
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to create file encoder: {}", err)));
|
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailCreateFileEncoder { err }));
|
||||||
encoder.emit_raw_bytes(METADATA_HEADER);
|
encoder.emit_raw_bytes(METADATA_HEADER);
|
||||||
|
|
||||||
// Will be filled with the root position after encoding everything.
|
// Will be filled with the root position after encoding everything.
|
||||||
|
@ -2240,10 +2241,10 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
||||||
// Encode the root position.
|
// Encode the root position.
|
||||||
let header = METADATA_HEADER.len();
|
let header = METADATA_HEADER.len();
|
||||||
file.seek(std::io::SeekFrom::Start(header as u64))
|
file.seek(std::io::SeekFrom::Start(header as u64))
|
||||||
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to seek the file: {}", err)));
|
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err }));
|
||||||
let pos = root.position.get();
|
let pos = root.position.get();
|
||||||
file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
|
file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])
|
||||||
.unwrap_or_else(|err| tcx.sess.fatal(&format!("failed to write to the file: {}", err)));
|
.unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err }));
|
||||||
|
|
||||||
// Return to the position where we are before writing the root position.
|
// Return to the position where we are before writing the root position.
|
||||||
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();
|
file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue