Skip to content

Commit ff00763

Browse files
committed
Show lib features in -Zls and allow configuring which things are shown
1 parent 369a8ac commit ff00763

File tree

5 files changed

+126
-75
lines changed

5 files changed

+126
-75
lines changed

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,12 +700,14 @@ pub fn list_metadata(
700700
sess: &Session,
701701
metadata_loader: &dyn MetadataLoader,
702702
) -> Compilation {
703-
if sess.opts.unstable_opts.ls {
703+
let ls_kinds = &sess.opts.unstable_opts.ls;
704+
if !ls_kinds.is_empty() {
704705
match sess.io.input {
705706
Input::File(ref ifile) => {
706707
let path = &(*ifile);
707708
let mut v = Vec::new();
708-
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v).unwrap();
709+
locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v, ls_kinds)
710+
.unwrap();
709711
safe_println!("{}", String::from_utf8(v).unwrap());
710712
}
711713
Input::Str { .. } => {

compiler/rustc_metadata/src/locator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,10 +903,11 @@ pub fn list_file_metadata(
903903
path: &Path,
904904
metadata_loader: &dyn MetadataLoader,
905905
out: &mut dyn Write,
906+
ls_kinds: &[String],
906907
) -> IoResult<()> {
907908
let flavor = get_flavor_from_path(path);
908909
match get_metadata_section(target, flavor, path, metadata_loader) {
909-
Ok(metadata) => metadata.list_crate_metadata(out),
910+
Ok(metadata) => metadata.list_crate_metadata(out, ls_kinds),
910911
Err(msg) => write!(out, "{msg}\n"),
911912
}
912913
}

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 116 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -725,78 +725,125 @@ impl MetadataBlob {
725725
LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
726726
}
727727

728-
pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
728+
pub(crate) fn list_crate_metadata(
729+
&self,
730+
out: &mut dyn io::Write,
731+
ls_kinds: &[String],
732+
) -> io::Result<()> {
729733
let root = self.get_root();
730-
writeln!(out, "Crate info:")?;
731-
writeln!(out, "name {}{}", root.name(), root.extra_filename)?;
732-
writeln!(out, "hash {} stable_crate_id {:?}", root.hash(), root.stable_crate_id)?;
733-
writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
734-
writeln!(out, "triple {}", root.header.triple.triple())?;
735-
writeln!(out, "edition {}", root.edition)?;
736-
writeln!(out, "symbol_mangling_version {:?}", root.symbol_mangling_version)?;
737-
writeln!(
738-
out,
739-
"required_panic_strategy {:?} panic_in_drop_strategy {:?}",
740-
root.required_panic_strategy, root.panic_in_drop_strategy
741-
)?;
742-
writeln!(
743-
out,
744-
"has_global_allocator {} has_alloc_error_handler {} has_panic_handler {} has_default_lib_allocator {}",
745-
root.has_global_allocator,
746-
root.has_alloc_error_handler,
747-
root.has_panic_handler,
748-
root.has_default_lib_allocator
749-
)?;
750-
writeln!(
751-
out,
752-
"compiler_builtins {} needs_allocator {} needs_panic_runtime {} no_builtins {} panic_runtime {} profiler_runtime {}",
753-
root.compiler_builtins,
754-
root.needs_allocator,
755-
root.needs_panic_runtime,
756-
root.no_builtins,
757-
root.panic_runtime,
758-
root.profiler_runtime
759-
)?;
760-
761-
writeln!(out, "\n=External Dependencies=")?;
762-
let dylib_dependency_formats =
763-
root.dylib_dependency_formats.decode(self).collect::<Vec<_>>();
764-
for (i, dep) in root.crate_deps.decode(self).enumerate() {
765-
let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = dep;
766-
let number = i + 1;
767-
768-
writeln!(
769-
out,
770-
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{linkage}",
771-
privacy = if is_private { "private" } else { "public" },
772-
linkage = if dylib_dependency_formats.is_empty() {
773-
String::new()
774-
} else {
775-
format!(" linkage {:?}", dylib_dependency_formats[i])
734+
735+
let all_ls_kinds = vec!["root".to_owned(), "lang_items".to_owned(), "features".to_owned()];
736+
let ls_kinds = if ls_kinds.contains(&"all".to_owned()) {
737+
&all_ls_kinds
738+
} else {
739+
ls_kinds
740+
};
741+
742+
for kind in ls_kinds {
743+
match &**kind {
744+
"root" => {
745+
writeln!(out, "Crate info:")?;
746+
writeln!(out, "name {}{}", root.name(), root.extra_filename)?;
747+
writeln!(
748+
out,
749+
"hash {} stable_crate_id {:?}",
750+
root.hash(),
751+
root.stable_crate_id
752+
)?;
753+
writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
754+
writeln!(out, "triple {}", root.header.triple.triple())?;
755+
writeln!(out, "edition {}", root.edition)?;
756+
writeln!(out, "symbol_mangling_version {:?}", root.symbol_mangling_version)?;
757+
writeln!(
758+
out,
759+
"required_panic_strategy {:?} panic_in_drop_strategy {:?}",
760+
root.required_panic_strategy, root.panic_in_drop_strategy
761+
)?;
762+
writeln!(
763+
out,
764+
"has_global_allocator {} has_alloc_error_handler {} has_panic_handler {} has_default_lib_allocator {}",
765+
root.has_global_allocator,
766+
root.has_alloc_error_handler,
767+
root.has_panic_handler,
768+
root.has_default_lib_allocator
769+
)?;
770+
writeln!(
771+
out,
772+
"compiler_builtins {} needs_allocator {} needs_panic_runtime {} no_builtins {} panic_runtime {} profiler_runtime {}",
773+
root.compiler_builtins,
774+
root.needs_allocator,
775+
root.needs_panic_runtime,
776+
root.no_builtins,
777+
root.panic_runtime,
778+
root.profiler_runtime
779+
)?;
780+
781+
writeln!(out, "\n=External Dependencies=")?;
782+
let dylib_dependency_formats =
783+
root.dylib_dependency_formats.decode(self).collect::<Vec<_>>();
784+
for (i, dep) in root.crate_deps.decode(self).enumerate() {
785+
let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } =
786+
dep;
787+
let number = i + 1;
788+
789+
writeln!(
790+
out,
791+
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{linkage}",
792+
privacy = if is_private { "private" } else { "public" },
793+
linkage = if dylib_dependency_formats.is_empty() {
794+
String::new()
795+
} else {
796+
format!(" linkage {:?}", dylib_dependency_formats[i])
797+
}
798+
)?;
799+
}
800+
write!(out, "\n")?;
776801
}
777-
)?;
778-
}
779-
write!(out, "\n")?;
780-
781-
writeln!(out, "\n=Lang items=")?;
782-
for (id, lang_item) in root.lang_items.decode(self) {
783-
writeln!(
784-
out,
785-
"{} = crate{}",
786-
lang_item.name(),
787-
DefPath::make(LOCAL_CRATE, id, |parent| root
788-
.tables
789-
.def_keys
790-
.get(self, parent)
791-
.unwrap()
792-
.decode(self))
793-
.to_string_no_crate_verbose()
794-
)?;
795-
}
796-
for lang_item in root.lang_items_missing.decode(self) {
797-
writeln!(out, "{} = <missing>", lang_item.name())?;
802+
803+
"lang_items" => {
804+
writeln!(out, "\n=Lang items=")?;
805+
for (id, lang_item) in root.lang_items.decode(self) {
806+
writeln!(
807+
out,
808+
"{} = crate{}",
809+
lang_item.name(),
810+
DefPath::make(LOCAL_CRATE, id, |parent| root
811+
.tables
812+
.def_keys
813+
.get(self, parent)
814+
.unwrap()
815+
.decode(self))
816+
.to_string_no_crate_verbose()
817+
)?;
818+
}
819+
for lang_item in root.lang_items_missing.decode(self) {
820+
writeln!(out, "{} = <missing>", lang_item.name())?;
821+
}
822+
write!(out, "\n")?;
823+
}
824+
825+
"features" => {
826+
writeln!(out, "\n=Lib features=")?;
827+
for (feature, since) in root.lib_features.decode(self) {
828+
writeln!(
829+
out,
830+
"{}{}",
831+
feature,
832+
if let Some(since) = since {
833+
format!(" since {since}")
834+
} else {
835+
String::new()
836+
}
837+
)?;
838+
}
839+
write!(out, "\n")?;
840+
}
841+
842+
_ => {
843+
writeln!(out, "unknown -Zls kind. allowed values are: no, all, root, lang_items, features")?;
844+
}
845+
}
798846
}
799-
write!(out, "\n")?;
800847

801848
Ok(())
802849
}

compiler/rustc_session/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ impl Options {
10861086
/// Returns `true` if there will be an output file generated.
10871087
pub fn will_create_output_file(&self) -> bool {
10881088
!self.unstable_opts.parse_only && // The file is just being parsed
1089-
!self.unstable_opts.ls // The file is just being queried
1089+
self.unstable_opts.ls.is_empty() // The file is just being queried
10901090
}
10911091

10921092
#[inline]

compiler/rustc_session/src/options.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,8 +1597,9 @@ options! {
15971597
"what location details should be tracked when using caller_location, either \
15981598
`none`, or a comma separated list of location details, for which \
15991599
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
1600-
ls: bool = (false, parse_bool, [UNTRACKED],
1601-
"list the symbols defined by a library crate (default: no)"),
1600+
ls: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
1601+
"decode and print various part of the crate metadata for a library crate \
1602+
(space separated)"),
16021603
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
16031604
"show macro backtraces (default: no)"),
16041605
maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)