rustc_metadata/
errors.rs

1use std::io::Error;
2use std::path::{Path, PathBuf};
3
4use rustc_errors::codes::*;
5use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
6use rustc_macros::{Diagnostic, Subdiagnostic};
7use rustc_span::{Span, Symbol, sym};
8use rustc_target::spec::{PanicStrategy, TargetTuple};
9
10use crate::fluent_generated as fluent;
11use crate::locator::CrateFlavor;
12
13#[derive(Diagnostic)]
14#[diag(metadata_rlib_required)]
15pub struct RlibRequired {
16    pub crate_name: Symbol,
17}
18
19#[derive(Diagnostic)]
20#[diag(metadata_lib_required)]
21pub struct LibRequired<'a> {
22    pub crate_name: Symbol,
23    pub kind: &'a str,
24}
25
26#[derive(Diagnostic)]
27#[diag(metadata_rustc_lib_required)]
28#[help]
29pub struct RustcLibRequired<'a> {
30    pub crate_name: Symbol,
31    pub kind: &'a str,
32}
33
34#[derive(Diagnostic)]
35#[diag(metadata_crate_dep_multiple)]
36#[help]
37pub struct CrateDepMultiple {
38    pub crate_name: Symbol,
39    #[subdiagnostic]
40    pub non_static_deps: Vec<NonStaticCrateDep>,
41    #[subdiagnostic]
42    pub rustc_driver_help: Option<RustcDriverHelp>,
43}
44
45#[derive(Subdiagnostic)]
46#[note(metadata_crate_dep_not_static)]
47pub struct NonStaticCrateDep {
48    /// It's different from `crate_name` in main Diagnostic.
49    pub crate_name_: Symbol,
50}
51
52#[derive(Subdiagnostic)]
53#[help(metadata_crate_dep_rustc_driver)]
54pub struct RustcDriverHelp;
55
56#[derive(Diagnostic)]
57#[diag(metadata_two_panic_runtimes)]
58pub struct TwoPanicRuntimes {
59    pub prev_name: Symbol,
60    pub cur_name: Symbol,
61}
62
63#[derive(Diagnostic)]
64#[diag(metadata_bad_panic_strategy)]
65pub struct BadPanicStrategy {
66    pub runtime: Symbol,
67    pub strategy: PanicStrategy,
68}
69
70#[derive(Diagnostic)]
71#[diag(metadata_required_panic_strategy)]
72pub struct RequiredPanicStrategy {
73    pub crate_name: Symbol,
74    pub found_strategy: PanicStrategy,
75    pub desired_strategy: PanicStrategy,
76}
77
78#[derive(Diagnostic)]
79#[diag(metadata_incompatible_panic_in_drop_strategy)]
80pub struct IncompatiblePanicInDropStrategy {
81    pub crate_name: Symbol,
82    pub found_strategy: PanicStrategy,
83    pub desired_strategy: PanicStrategy,
84}
85
86#[derive(Diagnostic)]
87#[diag(metadata_link_ordinal_raw_dylib)]
88pub struct LinkOrdinalRawDylib {
89    #[primary_span]
90    pub span: Span,
91}
92
93#[derive(Diagnostic)]
94#[diag(metadata_lib_framework_apple)]
95pub struct LibFrameworkApple;
96
97#[derive(Diagnostic)]
98#[diag(metadata_empty_renaming_target)]
99pub struct EmptyRenamingTarget<'a> {
100    pub lib_name: &'a str,
101}
102
103#[derive(Diagnostic)]
104#[diag(metadata_renaming_no_link)]
105pub struct RenamingNoLink<'a> {
106    pub lib_name: &'a str,
107}
108
109#[derive(Diagnostic)]
110#[diag(metadata_multiple_renamings)]
111pub struct MultipleRenamings<'a> {
112    pub lib_name: &'a str,
113}
114
115#[derive(Diagnostic)]
116#[diag(metadata_no_link_mod_override)]
117pub struct NoLinkModOverride {
118    #[primary_span]
119    pub span: Option<Span>,
120}
121
122#[derive(Diagnostic)]
123#[diag(metadata_raw_dylib_unsupported_abi)]
124pub struct RawDylibUnsupportedAbi {
125    #[primary_span]
126    pub span: Span,
127}
128
129#[derive(Diagnostic)]
130#[diag(metadata_fail_create_file_encoder)]
131pub struct FailCreateFileEncoder {
132    pub err: Error,
133}
134
135#[derive(Diagnostic)]
136#[diag(metadata_fail_write_file)]
137pub struct FailWriteFile<'a> {
138    pub path: &'a Path,
139    pub err: Error,
140}
141
142#[derive(Diagnostic)]
143#[diag(metadata_crate_not_panic_runtime)]
144pub struct CrateNotPanicRuntime {
145    pub crate_name: Symbol,
146}
147
148#[derive(Diagnostic)]
149#[diag(metadata_crate_not_compiler_builtins)]
150pub struct CrateNotCompilerBuiltins {
151    pub crate_name: Symbol,
152}
153
154#[derive(Diagnostic)]
155#[diag(metadata_no_panic_strategy)]
156pub struct NoPanicStrategy {
157    pub crate_name: Symbol,
158    pub strategy: PanicStrategy,
159}
160
161#[derive(Diagnostic)]
162#[diag(metadata_not_profiler_runtime)]
163pub struct NotProfilerRuntime {
164    pub crate_name: Symbol,
165}
166
167#[derive(Diagnostic)]
168#[diag(metadata_no_multiple_global_alloc)]
169pub struct NoMultipleGlobalAlloc {
170    #[primary_span]
171    #[label]
172    pub span2: Span,
173    #[label(metadata_prev_global_alloc)]
174    pub span1: Span,
175}
176
177#[derive(Diagnostic)]
178#[diag(metadata_no_multiple_alloc_error_handler)]
179pub struct NoMultipleAllocErrorHandler {
180    #[primary_span]
181    #[label]
182    pub span2: Span,
183    #[label(metadata_prev_alloc_error_handler)]
184    pub span1: Span,
185}
186
187#[derive(Diagnostic)]
188#[diag(metadata_conflicting_global_alloc)]
189pub struct ConflictingGlobalAlloc {
190    pub crate_name: Symbol,
191    pub other_crate_name: Symbol,
192}
193
194#[derive(Diagnostic)]
195#[diag(metadata_conflicting_alloc_error_handler)]
196pub struct ConflictingAllocErrorHandler {
197    pub crate_name: Symbol,
198    pub other_crate_name: Symbol,
199}
200
201#[derive(Diagnostic)]
202#[diag(metadata_global_alloc_required)]
203pub struct GlobalAllocRequired;
204
205#[derive(Diagnostic)]
206#[diag(metadata_no_transitive_needs_dep)]
207pub struct NoTransitiveNeedsDep<'a> {
208    pub crate_name: Symbol,
209    pub needs_crate_name: &'a str,
210    pub deps_crate_name: Symbol,
211}
212
213#[derive(Diagnostic)]
214#[diag(metadata_failed_write_error)]
215pub struct FailedWriteError {
216    pub filename: PathBuf,
217    pub err: Error,
218}
219
220#[derive(Diagnostic)]
221#[diag(metadata_failed_copy_to_stdout)]
222pub struct FailedCopyToStdout {
223    pub filename: PathBuf,
224    pub err: Error,
225}
226
227#[derive(Diagnostic)]
228#[diag(metadata_binary_output_to_tty)]
229pub struct BinaryOutputToTty;
230
231#[derive(Diagnostic)]
232#[diag(metadata_missing_native_library)]
233pub struct MissingNativeLibrary<'a> {
234    libname: &'a str,
235    #[subdiagnostic]
236    suggest_name: Option<SuggestLibraryName<'a>>,
237}
238
239impl<'a> MissingNativeLibrary<'a> {
240    pub fn new(libname: &'a str, verbatim: bool) -> Self {
241        // if it looks like the user has provided a complete filename rather just the bare lib name,
242        // then provide a note that they might want to try trimming the name
243        let suggested_name = if !verbatim {
244            if let Some(libname) = libname.strip_prefix("lib")
245                && let Some(libname) = libname.strip_suffix(".a")
246            {
247                // this is a unix style filename so trim prefix & suffix
248                Some(libname)
249            } else if let Some(libname) = libname.strip_suffix(".lib") {
250                // this is a Windows style filename so just trim the suffix
251                Some(libname)
252            } else {
253                None
254            }
255        } else {
256            None
257        };
258
259        Self {
260            libname,
261            suggest_name: suggested_name
262                .map(|suggested_name| SuggestLibraryName { suggested_name }),
263        }
264    }
265}
266
267#[derive(Subdiagnostic)]
268#[help(metadata_only_provide_library_name)]
269pub struct SuggestLibraryName<'a> {
270    suggested_name: &'a str,
271}
272
273#[derive(Diagnostic)]
274#[diag(metadata_failed_create_tempdir)]
275pub struct FailedCreateTempdir {
276    pub err: Error,
277}
278
279#[derive(Diagnostic)]
280#[diag(metadata_failed_create_file)]
281pub struct FailedCreateFile<'a> {
282    pub filename: &'a Path,
283    pub err: Error,
284}
285
286#[derive(Diagnostic)]
287#[diag(metadata_failed_create_encoded_metadata)]
288pub struct FailedCreateEncodedMetadata {
289    pub err: Error,
290}
291
292#[derive(Diagnostic)]
293#[diag(metadata_non_ascii_name)]
294pub struct NonAsciiName {
295    #[primary_span]
296    pub span: Span,
297    pub crate_name: Symbol,
298}
299
300#[derive(Diagnostic)]
301#[diag(metadata_extern_location_not_exist)]
302pub struct ExternLocationNotExist<'a> {
303    #[primary_span]
304    pub span: Span,
305    pub crate_name: Symbol,
306    pub location: &'a Path,
307}
308
309#[derive(Diagnostic)]
310#[diag(metadata_extern_location_not_file)]
311pub struct ExternLocationNotFile<'a> {
312    #[primary_span]
313    pub span: Span,
314    pub crate_name: Symbol,
315    pub location: &'a Path,
316}
317
318pub(crate) struct MultipleCandidates {
319    pub span: Span,
320    pub flavor: CrateFlavor,
321    pub crate_name: Symbol,
322    pub candidates: Vec<PathBuf>,
323}
324
325impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
326    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
327        let mut diag = Diag::new(dcx, level, fluent::metadata_multiple_candidates);
328        diag.arg("crate_name", self.crate_name);
329        diag.arg("flavor", self.flavor);
330        diag.code(E0464);
331        diag.span(self.span);
332        for (i, candidate) in self.candidates.iter().enumerate() {
333            // FIXME: make this translatable
334            #[allow(rustc::untranslatable_diagnostic)]
335            diag.note(format!("candidate #{}: {}", i + 1, candidate.display()));
336        }
337        diag
338    }
339}
340
341#[derive(Diagnostic)]
342#[diag(metadata_full_metadata_not_found)]
343pub(crate) struct FullMetadataNotFound {
344    #[primary_span]
345    pub span: Span,
346    pub flavor: CrateFlavor,
347    pub crate_name: Symbol,
348}
349
350#[derive(Diagnostic)]
351#[diag(metadata_symbol_conflicts_current, code = E0519)]
352pub struct SymbolConflictsCurrent {
353    #[primary_span]
354    pub span: Span,
355    pub crate_name: Symbol,
356}
357
358#[derive(Diagnostic)]
359#[diag(metadata_stable_crate_id_collision)]
360pub struct StableCrateIdCollision {
361    #[primary_span]
362    pub span: Span,
363    pub crate_name0: Symbol,
364    pub crate_name1: Symbol,
365}
366
367#[derive(Diagnostic)]
368#[diag(metadata_dl_error)]
369pub struct DlError {
370    #[primary_span]
371    pub span: Span,
372    pub path: String,
373    pub err: String,
374}
375
376#[derive(Diagnostic)]
377#[diag(metadata_newer_crate_version, code = E0460)]
378#[note]
379#[note(metadata_found_crate_versions)]
380pub struct NewerCrateVersion {
381    #[primary_span]
382    pub span: Span,
383    pub crate_name: Symbol,
384    pub add_info: String,
385    pub found_crates: String,
386}
387
388#[derive(Diagnostic)]
389#[diag(metadata_no_crate_with_triple, code = E0461)]
390#[note(metadata_found_crate_versions)]
391pub struct NoCrateWithTriple<'a> {
392    #[primary_span]
393    pub span: Span,
394    pub crate_name: Symbol,
395    pub locator_triple: &'a str,
396    pub add_info: String,
397    pub found_crates: String,
398}
399
400#[derive(Diagnostic)]
401#[diag(metadata_found_staticlib, code = E0462)]
402#[note(metadata_found_crate_versions)]
403#[help]
404pub struct FoundStaticlib {
405    #[primary_span]
406    pub span: Span,
407    pub crate_name: Symbol,
408    pub add_info: String,
409    pub found_crates: String,
410}
411
412#[derive(Diagnostic)]
413#[diag(metadata_incompatible_rustc, code = E0514)]
414#[note(metadata_found_crate_versions)]
415#[help]
416pub struct IncompatibleRustc {
417    #[primary_span]
418    pub span: Span,
419    pub crate_name: Symbol,
420    pub add_info: String,
421    pub found_crates: String,
422    pub rustc_version: String,
423}
424
425pub struct InvalidMetadataFiles {
426    pub span: Span,
427    pub crate_name: Symbol,
428    pub add_info: String,
429    pub crate_rejections: Vec<String>,
430}
431
432impl<G: EmissionGuarantee> Diagnostic<'_, G> for InvalidMetadataFiles {
433    #[track_caller]
434    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
435        let mut diag = Diag::new(dcx, level, fluent::metadata_invalid_meta_files);
436        diag.arg("crate_name", self.crate_name);
437        diag.arg("add_info", self.add_info);
438        diag.code(E0786);
439        diag.span(self.span);
440        for crate_rejection in self.crate_rejections {
441            // FIXME: make this translatable
442            #[allow(rustc::untranslatable_diagnostic)]
443            diag.note(crate_rejection);
444        }
445        diag
446    }
447}
448
449pub struct CannotFindCrate {
450    pub span: Span,
451    pub crate_name: Symbol,
452    pub add_info: String,
453    pub missing_core: bool,
454    pub current_crate: String,
455    pub is_nightly_build: bool,
456    pub profiler_runtime: Symbol,
457    pub locator_triple: TargetTuple,
458    pub is_ui_testing: bool,
459}
460
461impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
462    #[track_caller]
463    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
464        let mut diag = Diag::new(dcx, level, fluent::metadata_cannot_find_crate);
465        diag.arg("crate_name", self.crate_name);
466        diag.arg("current_crate", self.current_crate);
467        diag.arg("add_info", self.add_info);
468        diag.arg("locator_triple", self.locator_triple.tuple());
469        diag.code(E0463);
470        diag.span(self.span);
471        if self.crate_name == sym::std || self.crate_name == sym::core {
472            if self.missing_core {
473                diag.note(fluent::metadata_target_not_installed);
474            } else {
475                diag.note(fluent::metadata_target_no_std_support);
476            }
477
478            if self.missing_core {
479                if env!("CFG_RELEASE_CHANNEL") == "dev" && !self.is_ui_testing {
480                    // Note: Emits the nicer suggestion only for the dev channel.
481                    diag.help(fluent::metadata_consider_adding_std);
482                } else {
483                    // NOTE: this suggests using rustup, even though the user may not have it installed.
484                    // That's because they could choose to install it; or this may give them a hint which
485                    // target they need to install from their distro.
486                    diag.help(fluent::metadata_consider_downloading_target);
487                }
488            }
489
490            // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
491            // NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
492            // If it's not a dummy, that means someone added `extern crate std` explicitly and
493            // `#![no_std]` won't help.
494            if !self.missing_core && self.span.is_dummy() {
495                diag.note(fluent::metadata_std_required);
496            }
497            if self.is_nightly_build {
498                diag.help(fluent::metadata_consider_building_std);
499            }
500        } else if self.crate_name == self.profiler_runtime {
501            diag.note(fluent::metadata_compiler_missing_profiler);
502        } else if self.crate_name.as_str().starts_with("rustc_") {
503            diag.help(fluent::metadata_install_missing_components);
504        }
505        diag.span_label(self.span, fluent::metadata_cant_find_crate);
506        diag
507    }
508}
509
510#[derive(Diagnostic)]
511#[diag(metadata_crate_location_unknown_type)]
512pub struct CrateLocationUnknownType<'a> {
513    #[primary_span]
514    pub span: Span,
515    pub path: &'a Path,
516    pub crate_name: Symbol,
517}
518
519#[derive(Diagnostic)]
520#[diag(metadata_lib_filename_form)]
521pub struct LibFilenameForm<'a> {
522    #[primary_span]
523    pub span: Span,
524    pub dll_prefix: &'a str,
525    pub dll_suffix: &'a str,
526}
527
528#[derive(Diagnostic)]
529#[diag(metadata_wasm_c_abi)]
530pub(crate) struct WasmCAbi {
531    #[primary_span]
532    pub span: Span,
533}
534
535#[derive(Diagnostic)]
536#[diag(metadata_incompatible_target_modifiers)]
537#[help]
538#[note]
539#[help(metadata_incompatible_target_modifiers_help_fix)]
540#[help(metadata_incompatible_target_modifiers_help_allow)]
541pub struct IncompatibleTargetModifiers {
542    #[primary_span]
543    pub span: Span,
544    pub extern_crate: Symbol,
545    pub local_crate: Symbol,
546    pub flag_name: String,
547    pub flag_name_prefixed: String,
548    pub local_value: String,
549    pub extern_value: String,
550}
551
552#[derive(Diagnostic)]
553#[diag(metadata_incompatible_target_modifiers_l_missed)]
554#[help]
555#[note]
556#[help(metadata_incompatible_target_modifiers_help_fix_l_missed)]
557#[help(metadata_incompatible_target_modifiers_help_allow)]
558pub struct IncompatibleTargetModifiersLMissed {
559    #[primary_span]
560    pub span: Span,
561    pub extern_crate: Symbol,
562    pub local_crate: Symbol,
563    pub flag_name: String,
564    pub flag_name_prefixed: String,
565    pub extern_value: String,
566}
567
568#[derive(Diagnostic)]
569#[diag(metadata_incompatible_target_modifiers_r_missed)]
570#[help]
571#[note]
572#[help(metadata_incompatible_target_modifiers_help_fix_r_missed)]
573#[help(metadata_incompatible_target_modifiers_help_allow)]
574pub struct IncompatibleTargetModifiersRMissed {
575    #[primary_span]
576    pub span: Span,
577    pub extern_crate: Symbol,
578    pub local_crate: Symbol,
579    pub flag_name: String,
580    pub flag_name_prefixed: String,
581    pub local_value: String,
582}
583
584#[derive(Diagnostic)]
585#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
586pub struct UnknownTargetModifierUnsafeAllowed {
587    #[primary_span]
588    pub span: Span,
589    pub flag_name: String,
590}
591
592#[derive(Diagnostic)]
593#[diag(metadata_async_drop_types_in_dependency)]
594#[help]
595pub struct AsyncDropTypesInDependency {
596    #[primary_span]
597    pub span: Span,
598    pub extern_crate: Symbol,
599    pub local_crate: Symbol,
600}
601
602#[derive(Diagnostic)]
603#[diag(metadata_raw_dylib_malformed)]
604pub struct RawDylibMalformed {
605    #[primary_span]
606    pub span: Span,
607}