Add an error when full metadata was not found

This commit is contained in:
Jakub Beránek 2025-03-14 11:45:22 +01:00
parent 4dca28cfa2
commit 674a7adf9b
3 changed files with 35 additions and 1 deletions

View File

@ -97,6 +97,10 @@ metadata_found_staticlib =
found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
.help = please recompile that crate using --crate-type lib
metadata_full_metadata_not_found =
only metadata stub found for `{$flavor}` dependency `{$crate_name}`
please provide path to the corresponding .rmeta file with full metadata
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

View File

@ -525,6 +525,15 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
}
}
#[derive(Diagnostic)]
#[diag(metadata_full_metadata_not_found)]
pub(crate) struct FullMetadataNotFound {
#[primary_span]
pub span: Span,
pub flavor: CrateFlavor,
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_symbol_conflicts_current, code = E0519)]
pub struct SymbolConflictsCurrent {

View File

@ -654,7 +654,24 @@ impl<'a> CrateLocator<'a> {
continue;
}
}
*slot = Some((hash, metadata, lib.clone()));
// We error eagerly here. If we're locating a rlib, then in theory the full metadata
// could still be in a (later resolved) dylib. In practice, if the rlib and dylib
// were produced in a way where one has full metadata and the other hasn't, it would
// mean that they were compiled using different compiler flags and probably also have
// a different SVH value.
if metadata.get_header().is_stub {
// `is_stub` should never be true for .rmeta files.
assert_ne!(flavor, CrateFlavor::Rmeta);
// Because rmeta files are resolved before rlib/dylib files, if this is a stub and
// we haven't found a slot already, it means that the full metadata is missing.
if slot.is_none() {
return Err(CrateError::FullMetadataNotFound(self.crate_name, flavor));
}
} else {
*slot = Some((hash, metadata, lib.clone()));
}
ret = Some((lib, kind));
}
@ -916,6 +933,7 @@ pub(crate) enum CrateError {
ExternLocationNotExist(Symbol, PathBuf),
ExternLocationNotFile(Symbol, PathBuf),
MultipleCandidates(Symbol, CrateFlavor, Vec<PathBuf>),
FullMetadataNotFound(Symbol, CrateFlavor),
SymbolConflictsCurrent(Symbol),
StableCrateIdCollision(Symbol, Symbol),
DlOpen(String, String),
@ -966,6 +984,9 @@ impl CrateError {
CrateError::MultipleCandidates(crate_name, flavor, candidates) => {
dcx.emit_err(errors::MultipleCandidates { span, crate_name, flavor, candidates });
}
CrateError::FullMetadataNotFound(crate_name, flavor) => {
dcx.emit_err(errors::FullMetadataNotFound { span, crate_name, flavor });
}
CrateError::SymbolConflictsCurrent(root_name) => {
dcx.emit_err(errors::SymbolConflictsCurrent { span, crate_name: root_name });
}