cargo/compiler/crate_type.rs
1use cargo_util_schemas::core::CrateType;
2
3/// Compiler-specific queries on [`CrateType`].
4pub trait CrateTypeExt {
5 fn can_lto(&self) -> bool;
6
7 fn is_linkable(&self) -> bool;
8
9 fn is_dynamic(&self) -> bool;
10
11 /// Returns whether production of this crate type requires the object files
12 /// from dependencies to be available.
13 ///
14 /// See also [`TargetKind::requires_upstream_objects`].
15 ///
16 /// [`TargetKind::requires_upstream_objects`]: crate::workspace::manifest::TargetKind::requires_upstream_objects
17 fn requires_upstream_objects(&self) -> bool;
18
19 /// Returns whether production of this crate type could benefit from splitting metadata
20 /// into a .rmeta file.
21 ///
22 /// See also [`TargetKind::benefits_from_no_embed_metadata`].
23 ///
24 /// [`TargetKind::benefits_from_no_embed_metadata`]: crate::workspace::manifest::TargetKind::benefits_from_no_embed_metadata
25 fn benefits_from_no_embed_metadata(&self) -> bool;
26}
27
28impl CrateTypeExt for CrateType {
29 fn can_lto(&self) -> bool {
30 match self {
31 CrateType::Bin | CrateType::Staticlib | CrateType::Cdylib => true,
32 CrateType::Lib
33 | CrateType::Rlib
34 | CrateType::Dylib
35 | CrateType::ProcMacro
36 | CrateType::Other(..) => false,
37 }
38 }
39
40 fn is_linkable(&self) -> bool {
41 match self {
42 CrateType::Lib | CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
43 CrateType::Bin | CrateType::Cdylib | CrateType::Staticlib | CrateType::Other(..) => {
44 false
45 }
46 }
47 }
48
49 fn is_dynamic(&self) -> bool {
50 match self {
51 CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => true,
52 CrateType::Lib
53 | CrateType::Rlib
54 | CrateType::Bin
55 | CrateType::Staticlib
56 | CrateType::Other(..) => false,
57 }
58 }
59
60 fn requires_upstream_objects(&self) -> bool {
61 // "lib" == "rlib" and is a compilation that doesn't actually
62 // require upstream object files to exist, only upstream metadata
63 // files. As a result, it doesn't require upstream artifacts
64
65 !matches!(self, CrateType::Lib | CrateType::Rlib)
66 // Everything else, however, is some form of "linkable output" or
67 // something that requires upstream object files.
68 }
69
70 fn benefits_from_no_embed_metadata(&self) -> bool {
71 match self {
72 // rlib/libs generate .rmeta files for pipelined compilation.
73 // If we also include metadata inside of them, we waste disk space, since the metadata
74 // will be located both in the lib/rlib and the .rmeta file.
75 CrateType::Lib |
76 CrateType::Rlib |
77 // Dylibs do not have to contain metadata when they are used as a runtime dependency.
78 // If we split the metadata into a separate .rmeta file, the dylib file (that
79 // can be shipped as a runtime dependency) can be smaller.
80 CrateType::Dylib => true,
81 // Proc macros contain metadata that specifies what macro functions are available in
82 // it, but the metadata is typically very small. The metadata of proc macros is also
83 // self-contained (unlike rlibs/dylibs), so let's not unnecessarily split it into
84 // multiple files.
85 CrateType::ProcMacro |
86 // cdylib and staticlib produce artifacts that are used through the C ABI and do not
87 // contain Rust-specific metadata.
88 CrateType::Cdylib |
89 CrateType::Staticlib |
90 // Binaries also do not contain metadata
91 CrateType::Bin |
92 CrateType::Other(_) => false
93 }
94 }
95}