diff --git a/Cargo.lock b/Cargo.lock index 1b0516f71613e..04044c79bdaf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3567,7 +3567,6 @@ dependencies = [ "rustc_ast", "rustc_attr", "rustc_codegen_ssa", - "rustc_codegen_utils", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -3598,37 +3597,21 @@ dependencies = [ "rustc_apfloat", "rustc_ast", "rustc_attr", - "rustc_codegen_utils", "rustc_data_structures", "rustc_errors", "rustc_fs_util", "rustc_hir", "rustc_incremental", "rustc_index", + "rustc_metadata", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "serialize", "tempfile", ] -[[package]] -name = "rustc_codegen_utils" -version = "0.0.0" -dependencies = [ - "log", - "punycode", - "rustc", - "rustc-demangle", - "rustc_ast", - "rustc_data_structures", - "rustc_hir", - "rustc_metadata", - "rustc_session", - "rustc_span", - "rustc_target", -] - [[package]] name = "rustc_data_structures" version = "0.0.0" @@ -3665,7 +3648,6 @@ dependencies = [ "rustc_ast", "rustc_ast_pretty", "rustc_codegen_ssa", - "rustc_codegen_utils", "rustc_data_structures", "rustc_error_codes", "rustc_errors", @@ -3814,7 +3796,6 @@ dependencies = [ "rustc_builtin_macros", "rustc_codegen_llvm", "rustc_codegen_ssa", - "rustc_codegen_utils", "rustc_data_structures", "rustc_errors", "rustc_expand", @@ -3832,6 +3813,7 @@ dependencies = [ "rustc_resolve", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "rustc_trait_selection", "rustc_traits", @@ -4071,7 +4053,6 @@ dependencies = [ "rustc", "rustc_ast", "rustc_ast_pretty", - "rustc_codegen_utils", "rustc_data_structures", "rustc_hir", "rustc_parse", @@ -4112,6 +4093,23 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "rustc_symbol_mangling" +version = "0.0.0" +dependencies = [ + "log", + "punycode", + "rustc", + "rustc-demangle", + "rustc_ast", + "rustc_data_structures", + "rustc_hir", + "rustc_metadata", + "rustc_session", + "rustc_span", + "rustc_target", +] + [[package]] name = "rustc_target" version = "0.0.0" diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9e3853c51af13..eeacd6a6d83f6 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3148,6 +3148,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); layout::provide(providers); + super::util::bug::provide(providers); *providers = ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, all_local_trait_impls: trait_def::all_local_trait_impls, diff --git a/src/librustc/util/bug.rs b/src/librustc/util/bug.rs index c12b2859f728e..54cd8a29f9474 100644 --- a/src/librustc/util/bug.rs +++ b/src/librustc/util/bug.rs @@ -1,6 +1,6 @@ // These functions are used by macro expansion for bug! and span_bug! -use crate::ty::tls; +use crate::ty::{tls, TyCtxt}; use rustc_span::{MultiSpan, Span}; use std::fmt; @@ -39,3 +39,17 @@ fn opt_span_bug_fmt>( }); unreachable!(); } + +/// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a +/// `delay_span_bug`, so what is the point of this? It exists to help us test `delay_span_bug`'s +/// interactions with the query system and incremental. +pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) { + tcx.sess.delay_span_bug( + tcx.def_span(key), + "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]", + ); +} + +pub fn provide(providers: &mut crate::ty::query::Providers<'_>) { + *providers = crate::ty::query::Providers { trigger_delay_span_bug, ..*providers }; +} diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 0776cb19760d5..16ed0854abe6e 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -20,7 +20,6 @@ rustc = { path = "../librustc" } rustc-demangle = "0.1" rustc_attr = { path = "../librustc_attr" } rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index fa730d289b16b..e36c80e15a5e0 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -27,7 +27,6 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::{CodegenResults, CompiledModule}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_errors::{FatalError, Handler}; use rustc_serialize::json; use rustc_session::config::{self, OptLevel, OutputFilenames, PrintRequest}; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 3181d568b013a..299f4d2c66998 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -25,7 +25,7 @@ rustc_span = { path = "../librustc_span" } rustc = { path = "../librustc" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_attr = { path = "../librustc_attr" } -rustc_codegen_utils = { path = "../librustc_codegen_utils" } +rustc_symbol_mangling = { path = "../librustc_symbol_mangling" } rustc_data_structures = { path = "../librustc_data_structures"} rustc_errors = { path = "../librustc_errors" } rustc_fs_util = { path = "../librustc_fs_util" } @@ -34,3 +34,4 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_index = { path = "../librustc_index" } rustc_target = { path = "../librustc_target" } rustc_session = { path = "../librustc_session" } +rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index af413d3cdfe68..672b6e4aa4600 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -6,6 +6,7 @@ use rustc_hir::def_id::CrateNum; use rustc_session::config::{ self, CFGuard, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer, }; +use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. @@ -36,8 +37,6 @@ use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; use std::str; -pub use rustc_codegen_utils::link::*; - pub fn remove(sess: &Session, path: &Path) { if let Err(e) = fs::remove_file(path) { sess.err(&format!("failed to remove {}: {}", path.display(), e)); diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 8368d98884a5d..8a2503ce16730 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -8,7 +8,6 @@ use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::Instance; use rustc::ty::{SymbolName, TyCtxt}; use rustc_ast::expand::allocator::ALLOCATOR_METHODS; -use rustc_codegen_utils::symbol_names; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; @@ -423,17 +422,21 @@ pub fn symbol_name_for_instance_in_crate<'tcx>( // This is something instantiated in an upstream crate, so we have to use // the slower (because uncached) version of computing the symbol name. match symbol { - ExportedSymbol::NonGeneric(def_id) => symbol_names::symbol_name_for_instance_in_crate( - tcx, - Instance::mono(tcx, def_id), - instantiating_crate, - ), - ExportedSymbol::Generic(def_id, substs) => symbol_names::symbol_name_for_instance_in_crate( - tcx, - Instance::new(def_id, substs), - instantiating_crate, - ), - ExportedSymbol::DropGlue(ty) => symbol_names::symbol_name_for_instance_in_crate( + ExportedSymbol::NonGeneric(def_id) => { + rustc_symbol_mangling::symbol_name_for_instance_in_crate( + tcx, + Instance::mono(tcx, def_id), + instantiating_crate, + ) + } + ExportedSymbol::Generic(def_id, substs) => { + rustc_symbol_mangling::symbol_name_for_instance_in_crate( + tcx, + Instance::new(def_id, substs), + instantiating_crate, + ) + } + ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, Instance::resolve_drop_in_place(tcx, ty), instantiating_crate, diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index e57cae30b7795..2c31d7b8c100c 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -36,7 +36,6 @@ use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use rustc::ty::query::Providers; use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc_attr as attr; -use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::print_time_passes_entry; use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator}; @@ -47,6 +46,7 @@ use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, EntryFnType, Lto}; use rustc_session::Session; use rustc_span::Span; +use rustc_symbol_mangling::test as symbol_names_test; use std::cmp; use std::ops::{Deref, DerefMut}; @@ -514,8 +514,6 @@ pub fn codegen_crate( metadata: EncodedMetadata, need_metadata_module: bool, ) -> OngoingCodegen { - check_for_rustc_errors_attr(tcx); - // Skip crate items and just output metadata in -Z no-codegen mode. if tcx.sess.opts.debugging_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { let ongoing_codegen = start_async_codegen(backend, tcx, metadata, 1); diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 7acae300a2f02..4e861f45ff7a5 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -2,15 +2,22 @@ use super::write::WriteBackendMethods; use super::CodegenObject; use crate::ModuleCodegen; -use rustc::middle::cstore::EncodedMetadata; +use rustc::dep_graph::DepGraph; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout}; -use rustc::ty::Ty; -use rustc::ty::TyCtxt; +use rustc::ty::query::Providers; +use rustc::ty::{Ty, TyCtxt}; +use rustc::util::common::ErrorReported; use rustc_ast::expand::allocator::AllocatorKind; -use rustc_codegen_utils::codegen_backend::CodegenBackend; -use rustc_session::{config, Session}; +use rustc_session::{ + config::{self, OutputFilenames, PrintRequest}, + Session, +}; use rustc_span::symbol::Symbol; +pub use rustc_data_structures::sync::MetadataRef; + +use std::any::Any; use std::sync::Arc; pub trait BackendTypes { @@ -37,6 +44,50 @@ impl<'tcx, T> Backend<'tcx> for T where { } +pub trait CodegenBackend { + fn init(&self, _sess: &Session) {} + fn print(&self, _req: PrintRequest, _sess: &Session) {} + fn target_features(&self, _sess: &Session) -> Vec { + vec![] + } + fn print_passes(&self) {} + fn print_version(&self) {} + + fn metadata_loader(&self) -> Box; + fn provide(&self, _providers: &mut Providers<'_>); + fn provide_extern(&self, _providers: &mut Providers<'_>); + fn codegen_crate<'tcx>( + &self, + tcx: TyCtxt<'tcx>, + metadata: EncodedMetadata, + need_metadata_module: bool, + ) -> Box; + + /// This is called on the returned `Box` from `codegen_backend` + /// + /// # Panics + /// + /// Panics when the passed `Box` was not returned by `codegen_backend`. + fn join_codegen( + &self, + ongoing_codegen: Box, + sess: &Session, + dep_graph: &DepGraph, + ) -> Result, ErrorReported>; + + /// This is called on the returned `Box` from `join_codegen` + /// + /// # Panics + /// + /// Panics when the passed `Box` was not returned by `join_codegen`. + fn link( + &self, + sess: &Session, + codegen_results: Box, + outputs: &OutputFilenames, + ) -> Result<(), ErrorReported>; +} + pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync { fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module; fn write_compressed_metadata<'tcx>( diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index d03ff8d4d37d8..1bc9f297ea1b1 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -29,7 +29,7 @@ mod write; pub use self::abi::AbiBuilderMethods; pub use self::asm::{AsmBuilderMethods, AsmMethods}; -pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods}; +pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; pub use self::consts::ConstMethods; pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods}; diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs deleted file mode 100644 index 561692e70669a..0000000000000 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! The Rust compiler. -//! -//! # Note -//! -//! This API is completely unstable and subject to change. - -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - -use std::any::Any; - -use rustc::dep_graph::DepGraph; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; -use rustc::ty::query::Providers; -use rustc::ty::TyCtxt; -use rustc::util::common::ErrorReported; -use rustc_session::config::{OutputFilenames, PrintRequest}; -use rustc_session::Session; -use rustc_span::symbol::Symbol; - -pub use rustc_data_structures::sync::MetadataRef; - -pub trait CodegenBackend { - fn init(&self, _sess: &Session) {} - fn print(&self, _req: PrintRequest, _sess: &Session) {} - fn target_features(&self, _sess: &Session) -> Vec { - vec![] - } - fn print_passes(&self) {} - fn print_version(&self) {} - - fn metadata_loader(&self) -> Box; - fn provide(&self, _providers: &mut Providers<'_>); - fn provide_extern(&self, _providers: &mut Providers<'_>); - fn codegen_crate<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - metadata: EncodedMetadata, - need_metadata_module: bool, - ) -> Box; - - /// This is called on the returned `Box` from `codegen_backend` - /// - /// # Panics - /// - /// Panics when the passed `Box` was not returned by `codegen_backend`. - fn join_codegen( - &self, - ongoing_codegen: Box, - sess: &Session, - dep_graph: &DepGraph, - ) -> Result, ErrorReported>; - - /// This is called on the returned `Box` from `join_codegen` - /// - /// # Panics - /// - /// Panics when the passed `Box` was not returned by `join_codegen`. - fn link( - &self, - sess: &Session, - codegen_results: Box, - outputs: &OutputFilenames, - ) -> Result<(), ErrorReported>; -} diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs deleted file mode 100644 index 38906bbaef810..0000000000000 --- a/src/librustc_codegen_utils/lib.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! # Note -//! -//! This API is completely unstable and subject to change. - -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(never_type)] -#![feature(nll)] -#![feature(in_band_lifetimes)] -#![recursion_limit = "256"] - -#[macro_use] -extern crate rustc; - -use rustc::ty::query::Providers; -use rustc::ty::TyCtxt; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::symbol::sym; - -pub mod codegen_backend; -pub mod link; -pub mod symbol_names; -pub mod symbol_names_test; - -pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: DefId) { - tcx.sess.delay_span_bug( - tcx.def_span(key), - "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]", - ); -} - -/// check for the #[rustc_error] annotation, which forces an -/// error in codegen. This is used to write compile-fail tests -/// that actually test that compilation succeeds without -/// reporting an error. -pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { - if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { - let attrs = &*tcx.get_attrs(def_id); - for attr in attrs { - if attr.check_name(sym::rustc_error) { - match attr.meta_item_list() { - // check if there is a #[rustc_error(delayed)] - Some(list) => { - if list.iter().any(|list_item| { - list_item.ident().map(|i| i.name) - == Some(sym::delay_span_bug_from_inside_query) - }) { - tcx.ensure().trigger_delay_span_bug(def_id); - } - } - // bare #[rustc_error] - None => { - tcx.sess.span_fatal( - tcx.def_span(def_id), - "fatal error triggered by #[rustc_error]", - ); - } - } - } - } - } -} - -pub fn provide(providers: &mut Providers<'_>) { - crate::symbol_names::provide(providers); - *providers = Providers { trigger_delay_span_bug, ..*providers }; -} diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 3e6449582319f..aec10ee5ef537 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -27,13 +27,12 @@ rustc_parse = { path = "../librustc_parse" } rustc_plugin_impl = { path = "../librustc_plugin_impl" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_codegen_utils = { path = "../librustc_codegen_utils" } +rustc_session = { path = "../librustc_session" } rustc_error_codes = { path = "../librustc_error_codes" } rustc_interface = { path = "../librustc_interface" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } -rustc_session = { path = "../librustc_session" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 34f0c182499db..8f849367a126c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -21,8 +21,8 @@ pub extern crate rustc_plugin_impl as plugin; use rustc::middle::cstore::MetadataLoader; use rustc::ty::TyCtxt; use rustc::util::common::ErrorReported; -use rustc_codegen_ssa::CodegenResults; -use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_ast::ast; +use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults}; use rustc_data_structures::profiling::print_time_passes_entry; use rustc_data_structures::sync::SeqCst; use rustc_errors::{ @@ -43,6 +43,8 @@ use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest}; use rustc_session::lint::{Lint, LintId}; use rustc_session::{config, DiagnosticOutput, Session}; use rustc_session::{early_error, early_warn}; +use rustc_span::source_map::{FileLoader, FileName}; +use rustc_span::symbol::sym; use std::borrow::Cow; use std::cmp::max; @@ -58,11 +60,6 @@ use std::process::{self, Command, Stdio}; use std::str; use std::time::Instant; -use rustc_ast::ast; -use rustc_span::source_map::FileLoader; -use rustc_span::symbol::sym; -use rustc_span::FileName; - mod args; pub mod pretty; @@ -693,16 +690,15 @@ impl RustcDefaultCalls { let t_outputs = rustc_interface::util::build_output_filenames( input, odir, ofile, attrs, sess, ); - let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input); + let id = rustc_session::output::find_crate_name(Some(sess), attrs, input); if *req == PrintRequest::CrateName { println!("{}", id); continue; } let crate_types = collect_crate_types(sess, attrs); for &style in &crate_types { - let fname = rustc_codegen_utils::link::filename_for_input( - sess, style, &id, &t_outputs, - ); + let fname = + rustc_session::output::filename_for_input(sess, style, &id, &t_outputs); println!("{}", fname.file_name().unwrap().to_string_lossy()); } } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index e84181f1d75e7..2e055ff183f2c 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -28,7 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_traits = { path = "../librustc_traits" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } -rustc_codegen_utils = { path = "../librustc_codegen_utils" } +rustc_symbol_mangling = { path = "../librustc_symbol_mangling" } rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true } rustc_hir = { path = "../librustc_hir" } rustc_infer = { path = "../librustc_infer" } diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index c5ebcf0696fba..65a7a48d440bd 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -5,7 +5,7 @@ use rustc::ty; use rustc::util::common::ErrorReported; use rustc_ast::ast::{self, MetaItemKind}; use rustc_ast::token; -use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::OnDrop; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index ee323b204b7a0..b7a5f2f4531e5 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -14,8 +14,7 @@ use rustc::util::common::ErrorReported; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::{self, ast, visit}; use rustc_codegen_ssa::back::link::emit_metadata; -use rustc_codegen_utils::codegen_backend::CodegenBackend; -use rustc_codegen_utils::link::filename_for_metadata; +use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::sync::{par_iter, Lrc, Once, ParallelIterator, WorkerLocal}; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; use rustc_errors::PResult; @@ -29,9 +28,11 @@ use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_resolve::{Resolver, ResolverArenas}; -use rustc_session::config::{self, CrateType, Input, OutputFilenames, OutputType}; -use rustc_session::config::{PpMode, PpSourceMode}; +use rustc_session::config::{ + self, CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode, +}; use rustc_session::lint; +use rustc_session::output::{filename_for_input, filename_for_metadata}; use rustc_session::search_paths::PathKind; use rustc_session::Session; use rustc_span::symbol::Symbol; @@ -477,12 +478,7 @@ fn generated_output_paths( // by appending `.rlib`, `.exe`, etc., so we can skip this transformation. OutputType::Exe if !exact_name => { for crate_type in sess.crate_types.borrow().iter() { - let p = ::rustc_codegen_utils::link::filename_for_input( - sess, - *crate_type, - crate_name, - outputs, - ); + let p = filename_for_input(sess, *crate_type, crate_name, outputs); out_filenames.push(p); } } @@ -682,7 +678,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { rustc_ty::provide(providers); rustc_metadata::provide(providers); rustc_lint::provide(providers); - rustc_codegen_utils::provide(providers); + rustc_symbol_mangling::provide(providers); rustc_codegen_ssa::provide(providers); } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 3514829dca7f7..3ca92216003d1 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -4,17 +4,18 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::ty::steal::Steal; -use rustc::ty::{GlobalCtxt, ResolverOutputs}; +use rustc::ty::{GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_ast::{self, ast}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::Crate; use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use rustc_session::config::{OutputFilenames, OutputType}; -use rustc_session::Session; +use rustc_session::{output::find_crate_name, Session}; +use rustc_span::symbol::sym; use std::any::Any; use std::cell::{Ref, RefCell, RefMut}; use std::mem; @@ -157,11 +158,7 @@ impl<'tcx> Queries<'tcx> { None => { let parse_result = self.parse()?; let krate = parse_result.peek(); - rustc_codegen_utils::link::find_crate_name( - Some(self.session()), - &krate.attrs, - &self.compiler.input, - ) + find_crate_name(Some(self.session()), &krate.attrs, &self.compiler.input) } }) }) @@ -277,11 +274,58 @@ impl<'tcx> Queries<'tcx> { // Don't do code generation if there were any errors self.session().compile_status()?; + // Hook for compile-fail tests. + Self::check_for_rustc_errors_attr(tcx); + Ok(passes::start_codegen(&***self.codegen_backend(), tcx, &*outputs.peek())) }) }) } + /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used + /// to write compile-fail tests that actually test that compilation succeeds without reporting + /// an error. + fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { + let def_id = match tcx.entry_fn(LOCAL_CRATE) { + Some((def_id, _)) => def_id, + _ => return, + }; + + let attrs = &*tcx.get_attrs(def_id); + let attrs = attrs.iter().filter(|attr| attr.check_name(sym::rustc_error)); + for attr in attrs { + match attr.meta_item_list() { + // Check if there is a `#[rustc_error(delay_span_bug_from_inside_query)]`. + Some(list) + if list.iter().any(|list_item| { + matches!( + list_item.ident().map(|i| i.name), + Some(sym::delay_span_bug_from_inside_query) + ) + }) => + { + tcx.ensure().trigger_delay_span_bug(def_id); + } + + // Bare `#[rustc_error]`. + None => { + tcx.sess.span_fatal( + tcx.def_span(def_id), + "fatal error triggered by #[rustc_error]", + ); + } + + // Some other attribute. + Some(_) => { + tcx.sess.span_warn( + tcx.def_span(def_id), + "unexpected annotation used with `#[rustc_error(...)]!", + ); + } + } + } + } + pub fn linker(&'tcx self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 5c4de9e7155c6..c6f2d1b82fcf4 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -5,7 +5,7 @@ use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *}; use rustc_ast::ptr::P; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_ast::{self, ast}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[cfg(parallel_compiler)] @@ -20,7 +20,7 @@ use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::parse::CrateConfig; use rustc_session::CrateDisambiguator; -use rustc_session::{config, early_error, filesearch, DiagnosticOutput, Session}; +use rustc_session::{config, early_error, filesearch, output, DiagnosticOutput, Session}; use rustc_span::edition::Edition; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap}; use rustc_span::symbol::{sym, Symbol}; @@ -505,7 +505,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Vec CrateLoader<'a> { ); let name = match orig_name { Some(orig_name) => { - crate::validate_crate_name( - Some(self.sess), - &orig_name.as_str(), - Some(item.span), - ); + validate_crate_name(Some(self.sess), &orig_name.as_str(), Some(item.span)); orig_name } None => item.ident.name, diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index e401dc0f6e7d4..2993aed2f8ab4 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -29,37 +29,3 @@ mod rmeta; pub mod creader; pub mod dynamic_lib; pub mod locator; - -pub fn validate_crate_name( - sess: Option<&rustc_session::Session>, - s: &str, - sp: Option, -) { - let mut err_count = 0; - { - let mut say = |s: &str| { - match (sp, sess) { - (_, None) => bug!("{}", s), - (Some(sp), Some(sess)) => sess.span_err(sp, s), - (None, Some(sess)) => sess.err(s), - } - err_count += 1; - }; - if s.is_empty() { - say("crate name must not be empty"); - } - for c in s.chars() { - if c.is_alphanumeric() { - continue; - } - if c == '_' { - continue; - } - say(&format!("invalid character `{}` in crate name: `{}`", c, s)); - } - } - - if err_count > 0 { - sess.unwrap().abort_if_errors(); - } -} diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 4717664b6ba80..de851d9772727 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -13,12 +13,11 @@ log = "0.4" rustc = { path = "../librustc" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_codegen_utils = { path = "../librustc_codegen_utils" } +rustc_session = { path = "../librustc_session" } rustc_hir = { path = "../librustc_hir" } rustc_parse = { path = "../librustc_parse" } serde_json = "1" rustc_ast = { path = "../librustc_ast" } -rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rls-data = "0.19" rls-span = "0.5" diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 98d81c6252242..cb983a3098c56 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -16,12 +16,12 @@ use rustc_ast::ast::{self, Attribute, NodeId, PatKind, DUMMY_NODE_ID}; use rustc_ast::util::comments::strip_doc_comment_decoration; use rustc_ast::visit::{self, Visitor}; use rustc_ast_pretty::pprust::{self, param_to_string, ty_to_string}; -use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind as HirDefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::Node; use rustc_session::config::{CrateType, Input, OutputType}; +use rustc_session::output::{filename_for_metadata, out_filename}; use rustc_span::source_map::Spanned; use rustc_span::*; diff --git a/src/librustc_session/lib.rs b/src/librustc_session/lib.rs index 4101c32d547aa..cc4d525d62887 100644 --- a/src/librustc_session/lib.rs +++ b/src/librustc_session/lib.rs @@ -21,3 +21,5 @@ pub mod search_paths; mod session; pub use session::*; + +pub mod output; diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_session/output.rs similarity index 83% rename from src/librustc_codegen_utils/link.rs rename to src/librustc_session/output.rs index 1f53eec514bbf..ba3d08cfc7c14 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_session/output.rs @@ -1,6 +1,7 @@ +//! Related to out filenames of compilation (e.g. save analysis, binaries). +use crate::config::{self, Input, OutputFilenames, OutputType}; +use crate::Session; use rustc_ast::{ast, attr}; -use rustc_session::config::{self, Input, OutputFilenames, OutputType}; -use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::Span; use std::path::{Path, PathBuf}; @@ -24,9 +25,9 @@ pub fn out_filename( out_filename } -// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers -// check this already -- however, the Linux linker will happily overwrite a -// read-only file. We should be consistent. +/// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers +/// check this already -- however, the Linux linker will happily overwrite a +/// read-only file. We should be consistent. pub fn check_file_is_writeable(file: &Path, sess: &Session) { if !is_writeable(file) { sess.fatal(&format!( @@ -46,7 +47,7 @@ fn is_writeable(p: &Path) -> bool { pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { - rustc_metadata::validate_crate_name(sess, &s, span); + validate_crate_name(sess, &s, span); s }; @@ -96,6 +97,36 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: "rust_out".to_string() } +pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option) { + let mut err_count = 0; + { + let mut say = |s: &str| { + match (sp, sess) { + (_, None) => panic!("{}", s), + (Some(sp), Some(sess)) => sess.span_err(sp, s), + (None, Some(sess)) => sess.err(s), + } + err_count += 1; + }; + if s.is_empty() { + say("crate name must not be empty"); + } + for c in s.chars() { + if c.is_alphanumeric() { + continue; + } + if c == '_' { + continue; + } + say(&format!("invalid character `{}` in crate name: `{}`", c, s)); + } + } + + if err_count > 0 { + sess.unwrap().abort_if_errors(); + } +} + pub fn filename_for_metadata( sess: &Session, crate_name: &str, diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_symbol_mangling/Cargo.toml similarity index 87% rename from src/librustc_codegen_utils/Cargo.toml rename to src/librustc_symbol_mangling/Cargo.toml index 7ab59029bc8a9..1e4fc8f7e6842 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_symbol_mangling/Cargo.toml @@ -1,13 +1,13 @@ [package] authors = ["The Rust Project Developers"] -name = "rustc_codegen_utils" +name = "rustc_symbol_mangling" version = "0.0.0" edition = "2018" [lib] -name = "rustc_codegen_utils" +name = "rustc_symbol_mangling" path = "lib.rs" -test = false +doctest = false [dependencies] log = "0.4" diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_symbol_mangling/legacy.rs similarity index 100% rename from src/librustc_codegen_utils/symbol_names/legacy.rs rename to src/librustc_symbol_mangling/legacy.rs diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_symbol_mangling/lib.rs similarity index 98% rename from src/librustc_codegen_utils/symbol_names.rs rename to src/librustc_symbol_mangling/lib.rs index eb3fe49a5e9cc..26cb341050027 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_symbol_mangling/lib.rs @@ -87,6 +87,15 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(never_type)] +#![feature(nll)] +#![feature(in_band_lifetimes)] +#![recursion_limit = "256"] + +#[macro_use] +extern crate rustc; + use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::ty::query::Providers; @@ -103,6 +112,8 @@ use log::debug; mod legacy; mod v0; +pub mod test; + /// This function computes the symbol name for the given `instance` and the /// given instantiating crate. That is, if you know that instance X is /// instantiated in crate Y, this is the symbol name this instance would have. diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_symbol_mangling/test.rs similarity index 100% rename from src/librustc_codegen_utils/symbol_names_test.rs rename to src/librustc_symbol_mangling/test.rs diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_symbol_mangling/v0.rs similarity index 100% rename from src/librustc_codegen_utils/symbol_names/v0.rs rename to src/librustc_symbol_mangling/v0.rs diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index d975af52f5bb8..0e6c39e0affca 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -1,36 +1,38 @@ #![feature(rustc_private)] extern crate rustc; -extern crate rustc_codegen_utils; +extern crate rustc_codegen_ssa; #[macro_use] extern crate rustc_data_structures; -extern crate rustc_hir; -extern crate rustc_target; extern crate rustc_driver; +extern crate rustc_hir; extern crate rustc_session; extern crate rustc_span; +extern crate rustc_symbol_mangling; +extern crate rustc_target; -use std::any::Any; -use std::sync::Arc; -use std::path::Path; -use rustc::ty::TyCtxt; -use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; use rustc::dep_graph::DepGraph; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use rustc::util::common::ErrorReported; -use rustc_codegen_utils::codegen_backend::CodegenBackend; -use rustc_data_structures::sync::MetadataRef; +use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::owning_ref::OwningRef; -use rustc_session::Session; +use rustc_data_structures::sync::MetadataRef; use rustc_session::config::OutputFilenames; +use rustc_session::Session; use rustc_span::symbol::Symbol; use rustc_target::spec::Target; +use std::any::Any; +use std::path::Path; +use std::sync::Arc; pub struct NoLlvmMetadataLoader; impl MetadataLoader for NoLlvmMetadataLoader { fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { - let buf = std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?; + let buf = + std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?; let buf: OwningRef, [u8]> = OwningRef::new(buf); Ok(rustc_erase_owner!(buf.map_owner_box())) } @@ -48,7 +50,7 @@ impl CodegenBackend for TheBackend { } fn provide(&self, providers: &mut Providers) { - rustc_codegen_utils::symbol_names::provide(providers); + rustc_symbol_mangling::provide(providers); providers.target_features_whitelist = |tcx, _cnum| { tcx.arena.alloc(Default::default()) // Just a dummy @@ -78,7 +80,8 @@ impl CodegenBackend for TheBackend { _sess: &Session, _dep_graph: &DepGraph, ) -> Result, ErrorReported> { - let crate_name = ongoing_codegen.downcast::() + let crate_name = ongoing_codegen + .downcast::() .expect("in join_codegen: ongoing_codegen is not a Symbol"); Ok(crate_name) } @@ -89,17 +92,15 @@ impl CodegenBackend for TheBackend { codegen_results: Box, outputs: &OutputFilenames, ) -> Result<(), ErrorReported> { + use rustc_session::{config::CrateType, output::out_filename}; use std::io::Write; - use rustc_session::config::CrateType; - use rustc_codegen_utils::link::out_filename; - let crate_name = codegen_results.downcast::() - .expect("in link: codegen_results is not a Symbol"); + let crate_name = + codegen_results.downcast::().expect("in link: codegen_results is not a Symbol"); for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { sess.fatal(&format!("Crate type is {:?}", crate_type)); } - let output_name = - out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); + let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); let mut out_file = ::std::fs::File::create(output_name).unwrap(); write!(out_file, "This has been \"compiled\" successfully.").unwrap(); }