rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.8k stars 12.5k forks source link

`-Zalways-encode-mir=yes` misses MIR for statics #85401

Closed jsgf closed 2 years ago

jsgf commented 3 years ago

I tried this code:

foo.rs:

pub static FOO: &str = "foo";

pub fn foo() {
    println!("foo");
}

bar.rs:

pub fn bar() {
    println!("bar {}", foo::FOO);
    foo::foo();
}
rustc --crate-type rlib --crate-name foo -Crelocation-model=pic --edition=2018 foo.rs -Zalways-encode-mir=yes --emit metadata -o out/libfoo.rmeta
rustc --crate-type rlib --crate-name bar -Crelocation-model=pic --edition=2018 bar.rs --emit link=out/libbar.rlib --extern=foo=out/libfoo.rmeta

I expected to see this happen: generate libbar.rlib

Instead, this happened:

error: internal compiler error: compiler/rustc_mir/src/monomorphize/collector.rs:865:9: no MIR available for DefId(19:3 ~ foo[8787]::FOO)

thread 'rustc' panicked at 'Box<Any>', /rustc/9d9c2c92b834c430f102ea96f65119e37320776e/library/std/src/panic.rs:59:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.53.0-nightly (9d9c2c92b 2021-04-19) running on x86_64-unknown-linux-gnu

note: compiler flags: -C relocation-model=pic --crate-type rlib

query stack during panic:
#0 [collect_and_partition_mono_items] collect_and_partition_mono_items
#1 [exported_symbols] exported_symbols
end of query stack

Meta

rustc --version --verbose:

rustc 1.54.0-nightly (fe72845f7 2021-05-16)
binary: rustc
commit-hash: fe72845f7bb6a77b9e671e6a4f32fe714962cec4
commit-date: 2021-05-16
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.1
Backtrace

``` stack backtrace: 0: std::panicking::begin_panic 1: std::panic::panic_any 2: rustc_errors::HandlerInner::bug 3: rustc_errors::Handler::bug 4: rustc_middle::ty::context::tls::with_opt 5: rustc_middle::util::bug::opt_span_bug_fmt 6: rustc_middle::util::bug::bug_fmt 7: rustc_mir::monomorphize::collector::should_codegen_locally 8: rustc_mir::monomorphize::collector::collect_miri 9: ::visit_constant 10: ::visit_rvalue 11: rustc_mir::monomorphize::collector::collect_neighbours 12: rustc_mir::monomorphize::collector::collect_items_rec 13: rustc_session::utils::::time 14: rustc_mir::monomorphize::collector::collect_crate_mono_items 15: rustc_mir::monomorphize::partitioning::collect_and_partition_mono_items 16: rustc_query_impl:: for rustc_query_impl::queries::collect_and_partition_mono_items>::compute 17: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 18: rustc_data_structures::stack::ensure_sufficient_stack 19: rustc_query_system::query::plumbing::force_query_with_job 20: rustc_query_system::query::plumbing::get_query_impl 21: ::collect_and_partition_mono_items 22: rustc_codegen_ssa::back::symbol_export::exported_symbols_provider_local 23: rustc_query_system::dep_graph::graph::DepGraph::with_task_impl 24: rustc_data_structures::stack::ensure_sufficient_stack 25: rustc_query_system::query::plumbing::force_query_with_job 26: rustc_query_system::query::plumbing::get_query_impl 27: ::exported_symbols 28: rustc_metadata::rmeta::encoder::EncodeContext::encode_crate_root 29: rustc_metadata::rmeta::encoder::encode_metadata_impl 30: rustc_data_structures::sync::join 31: rustc_metadata::rmeta::decoder::cstore_impl::::encode_metadata 32: rustc_middle::ty::context::TyCtxt::encode_metadata 33: rustc_interface::passes::QueryContext::enter 34: rustc_interface::queries::Queries::ongoing_codegen 35: rustc_interface::queries::::enter 36: rustc_span::with_source_map 37: rustc_interface::interface::create_compiler_and_run 38: scoped_tls::ScopedKey::set note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ```

RalfJung commented 3 years ago

This is strange, Miri uses -Zalways-encode-mir but statics seem to work fine for us?

jsgf commented 3 years ago

@RalfJung Does the test case I gave work for Miri?

I notice that -Zalways-encode-mir=yes produces much larger rmeta files than --emit metadata,link would, which are in turn larger than --emit metadata's rmetas (as expected).

It would be nice to have an option to make lone --emit metadata produce the same output as --emit metadata,link, and I was hoping that it would just be a matter of stabilizing -Zalways-encode-mir, but they don't seem to be equivalent. Ideally they'd produce the same output, but I'd be happy with functionally interchangable - which is what this issue is about.

Overall, I'm finding it hard to work out what controls what goes into a .rmeta file. I audited all the places where either or both of tcx.sess.opts.debugging_opts.always_encode_mir and/or opts.output_types.should_codegen() are checked, and unifying them does not produce an output where -Zalways-encode-mir=yes and --emit metadata together produce the same as metadata,link.

I guess I haven't confirmed that MIR is the only difference between the two cases.

RalfJung commented 3 years ago

Does the test case I gave work for Miri?

Yes: when I set up a 2-crate workspace matching your 2 files and then do cargo miri run, it works as expected.

jsgf commented 3 years ago

PR #85793 adds -Zmetadata-link so that --emit metadata generates equivalent rmetas to --emit metadata,link.