about summary refs log tree commit diff
path: root/compiler/rustc_interface/src
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-23 05:56:09 +0800
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-27 23:23:33 +0800
commitcef812bd958d5037224aebe3721f3ffc9c80965e (patch)
tree19351f8407da440738b59892da7c9309b97bb82a /compiler/rustc_interface/src
parentf42f19b6d3d785a74dbe57aa395b6c288437dd51 (diff)
downloadrust-cef812bd958d5037224aebe3721f3ffc9c80965e.tar.gz
rust-cef812bd958d5037224aebe3721f3ffc9c80965e.zip
Provide more context for `rustc +nightly -Zunstable-options` on stable
Diffstat (limited to 'compiler/rustc_interface/src')
-rw-r--r--compiler/rustc_interface/src/interface.rs33
-rw-r--r--compiler/rustc_interface/src/tests.rs95
-rw-r--r--compiler/rustc_interface/src/util.rs45
3 files changed, 106 insertions, 67 deletions
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 54dabb75764..ab5f64b383d 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,12 +14,11 @@ use rustc_middle::{bug, ty};
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
-use rustc_session::config::{self, ErrorOutputType, Input, OutFileName, OutputFilenames};
-use rustc_session::config::{CheckCfg, ExpectedValues};
-use rustc_session::lint;
+use rustc_session::config::{self, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames};
 use rustc_session::parse::{CrateConfig, ParseSess};
+use rustc_session::CompilerIO;
 use rustc_session::Session;
-use rustc_session::{early_error, CompilerIO};
+use rustc_session::{lint, EarlyErrorHandler};
 use rustc_span::source_map::{FileLoader, FileName};
 use rustc_span::symbol::sym;
 use std::path::PathBuf;
@@ -66,7 +65,10 @@ pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) {
 }
 
 /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
-pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
+pub fn parse_cfgspecs(
+    handler: &EarlyErrorHandler,
+    cfgspecs: Vec<String>,
+) -> FxHashSet<(String, Option<String>)> {
     rustc_span::create_default_session_if_not_set_then(move |_| {
         let cfg = cfgspecs
             .into_iter()
@@ -78,10 +80,10 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
 
                 macro_rules! error {
                     ($reason: expr) => {
-                        early_error(
-                            ErrorOutputType::default(),
-                            format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s),
-                        );
+                        handler.early_error(format!(
+                            concat!("invalid `--cfg` argument: `{}` (", $reason, ")"),
+                            s
+                        ));
                     };
                 }
 
@@ -125,7 +127,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
 }
 
 /// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
-pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
+pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
     rustc_span::create_default_session_if_not_set_then(move |_| {
         let mut check_cfg = CheckCfg::default();
 
@@ -137,10 +139,10 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
 
             macro_rules! error {
                 ($reason: expr) => {
-                    early_error(
-                        ErrorOutputType::default(),
-                        format!(concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s),
-                    )
+                    handler.early_error(format!(
+                        concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
+                        s
+                    ))
                 };
             }
 
@@ -294,8 +296,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
 
             let registry = &config.registry;
 
+            let handler = EarlyErrorHandler::new(config.opts.error_format);
+
             let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
             let (mut sess, codegen_backend) = util::create_session(
+                &handler,
                 config.opts,
                 config.crate_cfg,
                 config.crate_check_cfg,
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 9d0c9ec9742..6054b48b0b5 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -21,8 +21,8 @@ use rustc_session::config::{InstrumentCoverage, Passes};
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
 use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
-use rustc_session::CompilerIO;
 use rustc_session::{build_session, getopts, Session};
+use rustc_session::{CompilerIO, EarlyErrorHandler};
 use rustc_span::edition::{Edition, DEFAULT_EDITION};
 use rustc_span::symbol::sym;
 use rustc_span::FileName;
@@ -36,15 +36,18 @@ use std::path::{Path, PathBuf};
 
 type CfgSpecs = FxHashSet<(String, Option<String>)>;
 
-fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
-    let sessopts = build_session_options(&matches);
-    let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
+fn build_session_options_and_crate_config(
+    handler: &mut EarlyErrorHandler,
+    matches: getopts::Matches,
+) -> (Options, CfgSpecs) {
+    let sessopts = build_session_options(handler, &matches);
+    let cfg = parse_cfgspecs(handler, matches.opt_strs("cfg"));
     (sessopts, cfg)
 }
 
-fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
+fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, CfgSpecs) {
     let registry = registry::Registry::new(&[]);
-    let (sessopts, cfg) = build_session_options_and_crate_config(matches);
+    let (sessopts, cfg) = build_session_options_and_crate_config(handler, matches);
     let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
     let io = CompilerIO {
         input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
@@ -52,8 +55,18 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
         output_file: None,
         temps_dir,
     };
-    let sess =
-        build_session(sessopts, io, None, registry, vec![], Default::default(), None, None, "");
+    let sess = build_session(
+        handler,
+        sessopts,
+        io,
+        None,
+        registry,
+        vec![],
+        Default::default(),
+        None,
+        None,
+        "",
+    );
     (sess, cfg)
 }
 
@@ -120,7 +133,8 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) {
 fn test_switch_implies_cfg_test() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["--test".to_string()]).unwrap();
-        let (sess, cfg) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, cfg) = mk_session(&mut handler, matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         assert!(cfg.contains(&(sym::test, None)));
     });
@@ -131,7 +145,8 @@ fn test_switch_implies_cfg_test() {
 fn test_switch_implies_cfg_test_unless_cfg_test() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
-        let (sess, cfg) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, cfg) = mk_session(&mut handler, matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
         assert!(test_items.next().is_some());
@@ -143,20 +158,23 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
 fn test_can_print_warnings() {
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(!sess.diagnostic().can_emit_warnings());
     });
 
     rustc_span::create_default_session_globals_then(|| {
         let matches =
             optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 
     rustc_span::create_default_session_globals_then(|| {
         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
-        let (sess, _) = mk_session(matches);
+        let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+        let (sess, _) = mk_session(&mut handler, matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 }
@@ -302,35 +320,36 @@ fn test_search_paths_tracking_hash_different_order() {
     let mut v3 = Options::default();
     let mut v4 = Options::default();
 
+    let handler = EarlyErrorHandler::new(JSON);
     const JSON: ErrorOutputType = ErrorOutputType::Json {
         pretty: false,
         json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
     };
 
     // Reference
-    v1.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v1.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v2.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v2.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v3.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v3.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-
-    v4.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
-    v4.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v1.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v2.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v3.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
+    v4.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
 
     assert_same_hash(&v1, &v2);
     assert_same_hash(&v1, &v3);
@@ -851,7 +870,9 @@ fn test_edition_parsing() {
     let options = Options::default();
     assert!(options.edition == DEFAULT_EDITION);
 
+    let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+
     let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
-    let (sessopts, _) = build_session_options_and_crate_config(matches);
+    let (sessopts, _) = build_session_options_and_crate_config(&mut handler, matches);
     assert!(sessopts.edition == Edition::Edition2018)
 }
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 87252fefb1e..035ea2414f7 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -11,16 +11,16 @@ use rustc_parse::validate_attr;
 use rustc_session as session;
 use rustc_session::config::CheckCfg;
 use rustc_session::config::{self, CrateType};
-use rustc_session::config::{ErrorOutputType, OutFileName, OutputFilenames, OutputTypes};
+use rustc_session::config::{OutFileName, OutputFilenames, OutputTypes};
 use rustc_session::filesearch::sysroot_candidates;
 use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::parse::CrateConfig;
-use rustc_session::{early_error, filesearch, output, Session};
+use rustc_session::{filesearch, output, Session};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::FileLoader;
 use rustc_span::symbol::{sym, Symbol};
-use session::CompilerIO;
+use session::{CompilerIO, EarlyErrorHandler};
 use std::env;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::mem;
@@ -58,6 +58,7 @@ pub fn add_configuration(
 }
 
 pub fn create_session(
+    handler: &EarlyErrorHandler,
     sopts: config::Options,
     cfg: FxHashSet<(String, Option<String>)>,
     check_cfg: CheckCfg,
@@ -73,7 +74,11 @@ pub fn create_session(
     let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
         make_codegen_backend(&sopts)
     } else {
-        get_codegen_backend(&sopts.maybe_sysroot, sopts.unstable_opts.codegen_backend.as_deref())
+        get_codegen_backend(
+            handler,
+            &sopts.maybe_sysroot,
+            sopts.unstable_opts.codegen_backend.as_deref(),
+        )
     };
 
     // target_override is documented to be called before init(), so this is okay
@@ -88,7 +93,7 @@ pub fn create_session(
     ) {
         Ok(bundle) => bundle,
         Err(e) => {
-            early_error(sopts.error_format, format!("failed to load fluent bundle: {e}"));
+            handler.early_error(format!("failed to load fluent bundle: {e}"));
         }
     };
 
@@ -96,6 +101,7 @@ pub fn create_session(
     locale_resources.push(codegen_backend.locale_resource());
 
     let mut sess = session::build_session(
+        handler,
         sopts,
         io,
         bundle,
@@ -218,16 +224,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
     })
 }
 
-fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
+fn load_backend_from_dylib(handler: &EarlyErrorHandler, path: &Path) -> MakeBackendFn {
     let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
         let err = format!("couldn't load codegen backend {path:?}: {err}");
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
 
     let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
         .unwrap_or_else(|e| {
             let err = format!("couldn't load codegen backend: {e}");
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         });
 
     // Intentionally leak the dynamic library. We can't ever unload it
@@ -242,6 +248,7 @@ fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
 ///
 /// A name of `None` indicates that the default backend should be used.
 pub fn get_codegen_backend(
+    handler: &EarlyErrorHandler,
     maybe_sysroot: &Option<PathBuf>,
     backend_name: Option<&str>,
 ) -> Box<dyn CodegenBackend> {
@@ -251,10 +258,12 @@ pub fn get_codegen_backend(
         let default_codegen_backend = option_env!("CFG_DEFAULT_CODEGEN_BACKEND").unwrap_or("llvm");
 
         match backend_name.unwrap_or(default_codegen_backend) {
-            filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
+            filename if filename.contains('.') => {
+                load_backend_from_dylib(handler, filename.as_ref())
+            }
             #[cfg(feature = "llvm")]
             "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
-            backend_name => get_codegen_sysroot(maybe_sysroot, backend_name),
+            backend_name => get_codegen_sysroot(handler, maybe_sysroot, backend_name),
         }
     });
 
@@ -286,7 +295,11 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
     })
 }
 
-fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
+fn get_codegen_sysroot(
+    handler: &EarlyErrorHandler,
+    maybe_sysroot: &Option<PathBuf>,
+    backend_name: &str,
+) -> MakeBackendFn {
     // For now we only allow this function to be called once as it'll dlopen a
     // few things, which seems to work best if we only do that once. In
     // general this assertion never trips due to the once guard in `get_codegen_backend`,
@@ -321,7 +334,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
             "failed to find a `codegen-backends` folder \
                            in the sysroot candidates:\n* {candidates}"
         );
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
     info!("probing {} for a codegen backend", sysroot.display());
 
@@ -332,7 +345,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
             sysroot.display(),
             e
         );
-        early_error(ErrorOutputType::default(), err);
+        handler.early_error(err);
     });
 
     let mut file: Option<PathBuf> = None;
@@ -360,16 +373,16 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
                 prev.display(),
                 path.display()
             );
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         }
         file = Some(path.clone());
     }
 
     match file {
-        Some(ref s) => load_backend_from_dylib(s),
+        Some(ref s) => load_backend_from_dylib(handler, s),
         None => {
             let err = format!("unsupported builtin codegen backend `{backend_name}`");
-            early_error(ErrorOutputType::default(), err);
+            handler.early_error(err);
         }
     }
 }