Skip to main content

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}