rename -Ztrait-solver
to -Znext-solver
This commit is contained in:
parent
1aa6aefdc9
commit
5d97ada1ec
@ -6,10 +6,9 @@
|
||||
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
|
||||
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
|
||||
FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
|
||||
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options,
|
||||
OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
|
||||
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, TraitSolver,
|
||||
WasiExecModel,
|
||||
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, NextSolverConfig,
|
||||
OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
|
||||
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
|
||||
};
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_session::search_paths::SearchPath;
|
||||
@ -781,6 +780,10 @@ macro_rules! tracked {
|
||||
tracked!(mir_opt_level, Some(4));
|
||||
tracked!(move_size_limit, Some(4096));
|
||||
tracked!(mutable_noalias, false);
|
||||
tracked!(
|
||||
next_solver,
|
||||
Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() })
|
||||
);
|
||||
tracked!(no_generate_arange_section, true);
|
||||
tracked!(no_jump_tables, true);
|
||||
tracked!(no_link, true);
|
||||
@ -822,7 +825,6 @@ macro_rules! tracked {
|
||||
tracked!(thir_unsafeck, true);
|
||||
tracked!(tiny_const_eval_limit, true);
|
||||
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
|
||||
tracked!(trait_solver, TraitSolver::NextCoherence);
|
||||
tracked!(translate_remapped_path_to_local_path, false);
|
||||
tracked!(trap_unreachable, Some(false));
|
||||
tracked!(treat_err_as_bug, NonZeroUsize::new(1));
|
||||
|
@ -2240,15 +2240,11 @@ pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId {
|
||||
}
|
||||
|
||||
pub fn next_trait_solver_globally(self) -> bool {
|
||||
self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
|
||||
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
|
||||
}
|
||||
|
||||
pub fn next_trait_solver_in_coherence(self) -> bool {
|
||||
matches!(
|
||||
self.sess.opts.unstable_opts.trait_solver,
|
||||
rustc_session::config::TraitSolver::Next
|
||||
| rustc_session::config::TraitSolver::NextCoherence
|
||||
)
|
||||
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
|
||||
}
|
||||
|
||||
pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
|
||||
|
@ -755,13 +755,14 @@ pub enum PrintKind {
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum TraitSolver {
|
||||
/// Classic trait solver in `rustc_trait_selection::traits::select`
|
||||
Classic,
|
||||
/// Experimental trait solver in `rustc_trait_selection::solve`
|
||||
Next,
|
||||
/// Use the new trait solver during coherence
|
||||
NextCoherence,
|
||||
pub struct NextSolverConfig {
|
||||
/// Whether the new trait solver should be enabled in coherence.
|
||||
pub coherence: bool,
|
||||
/// Whether the new trait solver should be enabled everywhere.
|
||||
/// This is only `true` if `coherence` is also enabled.
|
||||
pub globally: bool,
|
||||
/// Whether to dump proof trees after computing a proof tree.
|
||||
pub dump_tree: DumpSolverProofTree,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
@ -3220,10 +3221,10 @@ pub(crate) mod dep_tracking {
|
||||
use super::{
|
||||
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
|
||||
ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay,
|
||||
LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType,
|
||||
OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
|
||||
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
|
||||
WasiExecModel,
|
||||
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel,
|
||||
OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks,
|
||||
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
|
||||
TrimmedDefPaths, WasiExecModel,
|
||||
};
|
||||
use crate::lint;
|
||||
use crate::utils::NativeLib;
|
||||
@ -3326,7 +3327,7 @@ fn hash(
|
||||
BranchProtection,
|
||||
OomStrategy,
|
||||
LanguageIdentifier,
|
||||
TraitSolver,
|
||||
NextSolverConfig,
|
||||
Polonius,
|
||||
InliningThreshold,
|
||||
FunctionReturn,
|
||||
|
@ -396,8 +396,7 @@ mod desc {
|
||||
pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
|
||||
pub const parse_unpretty: &str = "`string` or `string=string`";
|
||||
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
|
||||
pub const parse_trait_solver: &str =
|
||||
"one of the supported solver modes (`classic`, `next`, or `next-coherence`)";
|
||||
pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error";
|
||||
pub const parse_lto: &str =
|
||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
|
||||
pub const parse_linker_plugin_lto: &str =
|
||||
@ -429,7 +428,6 @@ mod desc {
|
||||
"a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
|
||||
pub const parse_proc_macro_execution_strategy: &str =
|
||||
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
|
||||
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
|
||||
pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
|
||||
pub const parse_inlining_threshold: &str =
|
||||
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
|
||||
@ -1032,15 +1030,48 @@ pub(crate) fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some("classic") => *slot = TraitSolver::Classic,
|
||||
Some("next") => *slot = TraitSolver::Next,
|
||||
Some("next-coherence") => *slot = TraitSolver::NextCoherence,
|
||||
// default trait solver is subject to change..
|
||||
Some("default") => *slot = TraitSolver::Classic,
|
||||
pub(crate) fn parse_next_solver_config(
|
||||
slot: &mut Option<NextSolverConfig>,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
if let Some(config) = v {
|
||||
let mut coherence = false;
|
||||
let mut globally = true;
|
||||
let mut dump_tree = None;
|
||||
for c in config.split(',') {
|
||||
match c {
|
||||
"globally" => globally = true,
|
||||
"coherence" => {
|
||||
globally = false;
|
||||
coherence = true;
|
||||
}
|
||||
"dump-tree" => {
|
||||
if dump_tree.replace(DumpSolverProofTree::Always).is_some() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
"dump-tree-on-error" => {
|
||||
if dump_tree.replace(DumpSolverProofTree::OnError).is_some() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
|
||||
*slot = Some(NextSolverConfig {
|
||||
coherence: coherence || globally,
|
||||
globally,
|
||||
dump_tree: dump_tree.unwrap_or_default(),
|
||||
});
|
||||
} else {
|
||||
*slot = Some(NextSolverConfig {
|
||||
coherence: true,
|
||||
globally: true,
|
||||
dump_tree: Default::default(),
|
||||
});
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@ -1305,19 +1336,6 @@ pub(crate) fn parse_proc_macro_execution_strategy(
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn parse_dump_solver_proof_tree(
|
||||
slot: &mut DumpSolverProofTree,
|
||||
v: Option<&str>,
|
||||
) -> bool {
|
||||
match v {
|
||||
None | Some("always") => *slot = DumpSolverProofTree::Always,
|
||||
Some("never") => *slot = DumpSolverProofTree::Never,
|
||||
Some("on-error") => *slot = DumpSolverProofTree::OnError,
|
||||
_ => return false,
|
||||
};
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some("always" | "yes") => {
|
||||
@ -1591,9 +1609,6 @@ pub(crate) fn parse_function_return(slot: &mut FunctionReturn, v: Option<&str>)
|
||||
"output statistics about monomorphization collection"),
|
||||
dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
|
||||
"the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
|
||||
dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
|
||||
"dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
|
||||
then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
|
||||
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
|
||||
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
|
||||
dylib_lto: bool = (false, parse_bool, [UNTRACKED],
|
||||
@ -1722,6 +1737,8 @@ pub(crate) fn parse_function_return(slot: &mut FunctionReturn, v: Option<&str>)
|
||||
"the size at which the `large_assignments` lint starts to be emitted"),
|
||||
mutable_noalias: bool = (true, parse_bool, [TRACKED],
|
||||
"emit noalias metadata for mutable references (default: yes)"),
|
||||
next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED],
|
||||
"enable and configure the next generation trait solver used by rustc"),
|
||||
nll_facts: bool = (false, parse_bool, [UNTRACKED],
|
||||
"dump facts from NLL analysis into side files (default: no)"),
|
||||
nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
|
||||
@ -1922,8 +1939,6 @@ pub(crate) fn parse_function_return(slot: &mut FunctionReturn, v: Option<&str>)
|
||||
"for every macro invocation, print its name and arguments (default: no)"),
|
||||
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
|
||||
"tracks where in rustc a diagnostic was emitted"),
|
||||
trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
|
||||
"specify the trait solver mode used by rustc (default: classic)"),
|
||||
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
|
||||
// alongside query results and changes to translation options can affect diagnostics - so
|
||||
// translation options should be tracked.
|
||||
|
@ -200,9 +200,10 @@ fn enter_root<R>(
|
||||
let result = f(&mut ecx);
|
||||
|
||||
let tree = ecx.inspect.finalize();
|
||||
if let (Some(tree), DumpSolverProofTree::Always) =
|
||||
(&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree)
|
||||
{
|
||||
if let (Some(tree), DumpSolverProofTree::Always) = (
|
||||
&tree,
|
||||
infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(),
|
||||
) {
|
||||
let mut lock = std::io::stdout().lock();
|
||||
let _ = lock.write_fmt(format_args!("{tree:?}\n"));
|
||||
let _ = lock.flush();
|
||||
|
@ -265,7 +265,7 @@ pub fn new_maybe_root(
|
||||
GenerateProofTree::Never => ProofTreeBuilder::new_noop(),
|
||||
GenerateProofTree::IfEnabled => {
|
||||
let opts = &tcx.sess.opts.unstable_opts;
|
||||
match opts.dump_solver_proof_tree {
|
||||
match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() {
|
||||
DumpSolverProofTree::Always => ProofTreeBuilder::new_root(),
|
||||
// `OnError` is handled by reevaluating goals in error
|
||||
// reporting with `GenerateProofTree::Yes`.
|
||||
|
@ -25,7 +25,6 @@
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::Variance;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::config::TraitSolver;
|
||||
|
||||
pub trait TraitEngineExt<'tcx> {
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
|
||||
@ -33,18 +32,16 @@ pub trait TraitEngineExt<'tcx> {
|
||||
|
||||
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
|
||||
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
|
||||
match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
|
||||
(TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
|
||||
Box::new(FulfillmentContext::new(infcx))
|
||||
}
|
||||
(TraitSolver::Classic | TraitSolver::Next | TraitSolver::NextCoherence, true) => {
|
||||
if infcx.next_trait_solver() {
|
||||
Box::new(NextFulfillmentCtxt::new(infcx))
|
||||
}
|
||||
(TraitSolver::Next, false) => bug!(
|
||||
"incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})",
|
||||
infcx.tcx.sess.opts.unstable_opts.trait_solver,
|
||||
infcx.next_trait_solver()
|
||||
),
|
||||
} else {
|
||||
let new_solver_globally =
|
||||
infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally);
|
||||
assert!(
|
||||
!new_solver_globally,
|
||||
"using old solver even though new solver is enabled globally"
|
||||
);
|
||||
Box::new(FulfillmentContext::new(infcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
|
||||
TypeVisitable, TypeVisitableExt,
|
||||
};
|
||||
use rustc_session::config::{DumpSolverProofTree, TraitSolver};
|
||||
use rustc_session::config::DumpSolverProofTree;
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::symbol::sym;
|
||||
@ -370,7 +370,9 @@ fn report_selection_error(
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
|
||||
if tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
|
||||
if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
|
||||
== DumpSolverProofTree::OnError
|
||||
{
|
||||
dump_proof_tree(root_obligation, self.infcx);
|
||||
}
|
||||
|
||||
@ -812,23 +814,20 @@ fn report_selection_error(
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
match self.tcx.sess.opts.unstable_opts.trait_solver {
|
||||
TraitSolver::Classic => {
|
||||
// WF predicates cannot themselves make
|
||||
// errors. They can only block due to
|
||||
// ambiguity; otherwise, they always
|
||||
// degenerate into other obligations
|
||||
// (which may fail).
|
||||
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
|
||||
}
|
||||
TraitSolver::Next | TraitSolver::NextCoherence => {
|
||||
if self.tcx.sess.opts.unstable_opts.next_solver.is_some() {
|
||||
// FIXME: we'll need a better message which takes into account
|
||||
// which bounds actually failed to hold.
|
||||
self.tcx.sess.struct_span_err(
|
||||
span,
|
||||
format!("the type `{ty}` is not well-formed"),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// WF predicates cannot themselves make
|
||||
// errors. They can only block due to
|
||||
// ambiguity; otherwise, they always
|
||||
// degenerate into other obligations
|
||||
// (which may fail).
|
||||
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1562,7 +1561,9 @@ fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
|
||||
if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
|
||||
if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
|
||||
== DumpSolverProofTree::OnError
|
||||
{
|
||||
dump_proof_tree(&error.root_obligation, self.infcx);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user