use ast::CRATE_NODE_ID;
use rustc_ast::{self as ast, visit};
use rustc_borrowck as mir_borrowck;
-use rustc_codegen_ssa::back::link::emit_metadata;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
-use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, PResult};
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
-use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
+use rustc_hir::def_id::StableCrateId;
use rustc_hir::definitions::Definitions;
-use rustc_hir::Crate;
-use rustc_lint::{EarlyCheckNode, LintStore};
+use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore};
use rustc_metadata::creader::CStore;
-use rustc_metadata::{encode_metadata, EncodedMetadata};
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, MetadataLoaderDyn};
-use rustc_session::output::{filename_for_input, filename_for_metadata};
+use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::FileName;
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
-use tempfile::Builder as TempFileBuilder;
use tracing::{info, warn};
use std::any::Any;
}
})?;
- if sess.opts.debugging_opts.input_stats {
+ if sess.opts.unstable_opts.input_stats {
eprintln!("Lines of code: {}", sess.source_map().count_lines());
eprintln!("Pre-expansion node count: {}", count_nodes(&krate));
}
- if let Some(ref s) = sess.opts.debugging_opts.show_span {
+ if let Some(ref s) = sess.opts.unstable_opts.show_span {
rustc_ast_passes::show_span::run(sess.diagnostic(), s, &krate);
}
- if sess.opts.debugging_opts.hir_stats {
+ if sess.opts.unstable_opts.hir_stats {
hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS");
}
rustc_builtin_macros::cmdline_attrs::inject(
krate,
&sess.parse_sess,
- &sess.opts.debugging_opts.crate_attr,
+ &sess.opts.unstable_opts.crate_attr,
)
});
}
let mut lint_store = rustc_lint::new_lint_store(
- sess.opts.debugging_opts.no_interleave_lints,
- sess.unstable_options(),
+ sess.opts.unstable_opts.no_interleave_lints,
+ sess.enable_internal_lints(),
);
register_lints(sess, &mut lint_store);
let cfg = rustc_expand::expand::ExpansionConfig {
features: Some(features),
recursion_limit,
- trace_mac: sess.opts.debugging_opts.trace_macros,
+ trace_mac: sess.opts.unstable_opts.trace_macros,
should_test: sess.opts.test,
- span_debug: sess.opts.debugging_opts.span_debug,
- proc_macro_backtrace: sess.opts.debugging_opts.proc_macro_backtrace,
+ span_debug: sess.opts.unstable_opts.span_debug,
+ proc_macro_backtrace: sess.opts.unstable_opts.proc_macro_backtrace,
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
};
let lint_store = LintStoreExpandImpl(lint_store);
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store));
-
// Expand macros now!
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
// The rest is error reporting
+ sess.parse_sess.buffered_lints.with_lock(|buffered_lints: &mut Vec<BufferedEarlyLint>| {
+ buffered_lints.append(&mut ecx.buffered_early_lint);
+ });
+
sess.time("check_unused_macros", || {
ecx.check_unused_macros();
});
// Done with macro expansion!
- if sess.opts.debugging_opts.input_stats {
+ if sess.opts.unstable_opts.input_stats {
eprintln!("Post-expansion node count: {}", count_nodes(&krate));
}
- if sess.opts.debugging_opts.hir_stats {
+ if sess.opts.unstable_opts.hir_stats {
hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS");
}
Ok(krate)
}
-fn lower_to_hir<'tcx>(
- sess: &Session,
- definitions: &mut Definitions,
- cstore: &CrateStoreDyn,
- resolutions: &ty::ResolverOutputs,
- resolver: ty::ResolverAstLowering,
- krate: Rc<ast::Crate>,
- arena: &'tcx rustc_ast_lowering::Arena<'tcx>,
-) -> &'tcx Crate<'tcx> {
- // Lower AST to HIR.
- let hir_crate = rustc_ast_lowering::lower_crate(
- sess,
- &krate,
- definitions,
- cstore,
- resolutions,
- resolver,
- arena,
- );
-
- // Drop AST to free memory
- sess.time("drop_ast", || std::mem::drop(krate));
-
- // Discard hygiene data, which isn't required after lowering to HIR.
- if !sess.opts.debugging_opts.keep_hygiene_data {
- rustc_span::hygiene::clear_syntax_context_map();
- }
-
- hir_crate
-}
-
// Returns all the paths that correspond to generated files.
fn generated_output_paths(
sess: &Session,
out_filenames.push(p);
}
}
- OutputType::DepInfo if sess.opts.debugging_opts.dep_info_omit_d_target => {
+ OutputType::DepInfo if sess.opts.unstable_opts.dep_info_omit_d_target => {
// Don't add the dep-info output when omitting it from dep-info targets
}
_ => {
files.extend(extra_tracked_files);
if sess.binary_dep_depinfo() {
- if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
+ if let Some(ref backend) = sess.opts.unstable_opts.codegen_backend {
if backend.contains('.') {
// If the backend name contain a `.`, it is the path to an external dynamic
// library. If not, it is not a path.
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
let providers = &mut Providers::default();
providers.analysis = analysis;
+ providers.hir_crate = rustc_ast_lowering::lower_to_hir;
proc_macro_decls::provide(providers);
rustc_const_eval::provide(providers);
rustc_middle::hir::provide(providers);
pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>,
- krate: Rc<ast::Crate>,
+ krate: Lrc<ast::Crate>,
dep_graph: DepGraph,
resolver: Rc<RefCell<BoxedResolver>>,
outputs: OutputFilenames,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
- hir_arena: &'tcx WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
+ hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
) -> QueryContext<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
- let (mut definitions, cstore, resolver_outputs, resolver_for_lowering) =
+ let (definitions, cstore, resolver_outputs, resolver_for_lowering) =
BoxedResolver::to_resolver_outputs(resolver);
let sess = &compiler.session();
-
- // Lower AST to HIR.
- let krate = lower_to_hir(
- sess,
- &mut definitions,
- &*cstore,
- &resolver_outputs,
- resolver_for_lowering,
- krate,
- hir_arena,
- );
-
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
let codegen_backend = compiler.codegen_backend();
sess,
lint_store,
arena,
+ hir_arena,
definitions,
cstore,
resolver_outputs,
+ resolver_for_lowering,
krate,
dep_graph,
queries.on_disk_cache.as_ref().map(OnDiskCache::as_dyn),
sess.time("MIR_effect_checking", || {
for def_id in tcx.hir().body_owners() {
tcx.ensure().thir_check_unsafety(def_id);
- if !tcx.sess.opts.debugging_opts.thir_unsafeck {
+ if !tcx.sess.opts.unstable_opts.thir_unsafeck {
rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id);
}
+ tcx.ensure().has_ffi_unwind_calls(def_id);
if tcx.hir().body_const_context(def_id).is_some() {
tcx.ensure()
Ok(())
}
-fn encode_and_write_metadata(
- tcx: TyCtxt<'_>,
- outputs: &OutputFilenames,
-) -> (EncodedMetadata, bool) {
- #[derive(PartialEq, Eq, PartialOrd, Ord)]
- enum MetadataKind {
- None,
- Uncompressed,
- Compressed,
- }
-
- let metadata_kind = tcx
- .sess
- .crate_types()
- .iter()
- .map(|ty| match *ty {
- CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => MetadataKind::None,
-
- CrateType::Rlib => MetadataKind::Uncompressed,
-
- CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
- })
- .max()
- .unwrap_or(MetadataKind::None);
-
- let metadata = match metadata_kind {
- MetadataKind::None => EncodedMetadata::new(),
- MetadataKind::Uncompressed | MetadataKind::Compressed => encode_metadata(tcx),
- };
-
- let _prof_timer = tcx.sess.prof.generic_activity("write_crate_metadata");
-
- let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
- if need_metadata_file {
- let crate_name = tcx.crate_name(LOCAL_CRATE);
- let out_filename = filename_for_metadata(tcx.sess, crate_name.as_str(), outputs);
- // To avoid races with another rustc process scanning the output directory,
- // we need to write the file somewhere else and atomically move it to its
- // final destination, with an `fs::rename` call. In order for the rename to
- // always succeed, the temporary file needs to be on the same filesystem,
- // which is why we create it inside the output directory specifically.
- let metadata_tmpdir = TempFileBuilder::new()
- .prefix("rmeta")
- .tempdir_in(out_filename.parent().unwrap())
- .unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)));
- let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps);
- let metadata_filename = emit_metadata(tcx.sess, metadata.raw_data(), &metadata_tmpdir);
- if let Err(e) = util::non_durable_rename(&metadata_filename, &out_filename) {
- tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
- }
- if tcx.sess.opts.json_artifact_notifications {
- tcx.sess
- .parse_sess
- .span_diagnostic
- .emit_artifact_notification(&out_filename, "metadata");
- }
- }
-
- let need_metadata_module = metadata_kind == MetadataKind::Compressed;
-
- (metadata, need_metadata_module)
-}
-
/// Runs the codegen backend, after which the AST and analysis can
/// be discarded.
pub fn start_codegen<'tcx>(
) -> Box<dyn Any> {
info!("Pre-codegen\n{:?}", tcx.debug_stats());
- let (metadata, need_metadata_module) = encode_and_write_metadata(tcx, outputs);
+ let (metadata, need_metadata_module) =
+ rustc_metadata::fs::encode_and_write_metadata(tcx, outputs);
let codegen = tcx.sess.time("codegen_crate", move || {
codegen_backend.codegen_crate(tcx, metadata, need_metadata_module)