Provide more context for rustc +nightly -Zunstable-options on stable

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2023-06-23 05:56:09 +08:00
parent f42f19b6d3
commit cef812bd95
No known key found for this signature in database
GPG key ID: C5FD5D32014FDB47
19 changed files with 509 additions and 471 deletions

View file

@ -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,

View file

@ -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));
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("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));
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("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));
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("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));
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)
}

View file

@ -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);
}
}
}