Skip to content

Commit e385dfc

Browse files
committed
rename -Ztrait-solver to -Znext-solver
1 parent 40aa9f4 commit e385dfc

File tree

8 files changed

+102
-89
lines changed

8 files changed

+102
-89
lines changed

compiler/rustc_interface/src/tests.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use rustc_session::config::{
66
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
77
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
88
FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
9-
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options,
10-
OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
11-
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, TraitSolver,
12-
WasiExecModel,
9+
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, NextSolverConfig,
10+
OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
11+
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
1312
};
1413
use rustc_session::lint::Level;
1514
use rustc_session::search_paths::SearchPath;
@@ -819,7 +818,10 @@ fn test_unstable_options_tracking_hash() {
819818
tracked!(thir_unsafeck, true);
820819
tracked!(tiny_const_eval_limit, true);
821820
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
822-
tracked!(trait_solver, TraitSolver::NextCoherence);
821+
tracked!(
822+
next_solver,
823+
Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() })
824+
);
823825
tracked!(translate_remapped_path_to_local_path, false);
824826
tracked!(trap_unreachable, Some(false));
825827
tracked!(treat_err_as_bug, NonZeroUsize::new(1));

compiler/rustc_middle/src/ty/context.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -2195,15 +2195,11 @@ impl<'tcx> TyCtxt<'tcx> {
21952195
}
21962196

21972197
pub fn next_trait_solver_globally(self) -> bool {
2198-
self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
2198+
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
21992199
}
22002200

22012201
pub fn next_trait_solver_in_coherence(self) -> bool {
2202-
matches!(
2203-
self.sess.opts.unstable_opts.trait_solver,
2204-
rustc_session::config::TraitSolver::Next
2205-
| rustc_session::config::TraitSolver::NextCoherence
2206-
)
2202+
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
22072203
}
22082204

22092205
pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {

compiler/rustc_session/src/config.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,14 @@ pub enum PrintKind {
755755
}
756756

757757
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
758-
pub enum TraitSolver {
759-
/// Classic trait solver in `rustc_trait_selection::traits::select`
760-
Classic,
761-
/// Experimental trait solver in `rustc_trait_selection::solve`
762-
Next,
763-
/// Use the new trait solver during coherence
764-
NextCoherence,
758+
pub struct NextSolverConfig {
759+
/// Whether the new trait solver should be enabled in coherence.
760+
pub coherence: bool,
761+
/// Whether the new trait solver should be enabled everywhere.
762+
/// This is only `true` if `coherence` is also enabled.
763+
pub globally: bool,
764+
/// Whether to dump proof trees after computing a proof tree.
765+
pub dump_tree: DumpSolverProofTree,
765766
}
766767

767768
#[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -3174,10 +3175,10 @@ pub(crate) mod dep_tracking {
31743175
use super::{
31753176
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
31763177
ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay,
3177-
LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType,
3178-
OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
3179-
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
3180-
WasiExecModel,
3178+
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel,
3179+
OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks,
3180+
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
3181+
TrimmedDefPaths, WasiExecModel,
31813182
};
31823183
use crate::lint;
31833184
use crate::utils::NativeLib;
@@ -3279,7 +3280,7 @@ pub(crate) mod dep_tracking {
32793280
BranchProtection,
32803281
OomStrategy,
32813282
LanguageIdentifier,
3282-
TraitSolver,
3283+
NextSolverConfig,
32833284
Polonius,
32843285
InliningThreshold,
32853286
FunctionReturn,

compiler/rustc_session/src/options.rs

+44-29
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,7 @@ mod desc {
392392
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`";
393393
pub const parse_unpretty: &str = "`string` or `string=string`";
394394
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
395-
pub const parse_trait_solver: &str =
396-
"one of the supported solver modes (`classic`, `next`, or `next-coherence`)";
395+
pub const parse_new_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error";
397396
pub const parse_lto: &str =
398397
"either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
399398
pub const parse_linker_plugin_lto: &str =
@@ -425,7 +424,6 @@ mod desc {
425424
"a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
426425
pub const parse_proc_macro_execution_strategy: &str =
427426
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
428-
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
429427
pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
430428
pub const parse_inlining_threshold: &str =
431429
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
@@ -1028,15 +1026,48 @@ mod parse {
10281026
}
10291027
}
10301028

1031-
pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool {
1032-
match v {
1033-
Some("classic") => *slot = TraitSolver::Classic,
1034-
Some("next") => *slot = TraitSolver::Next,
1035-
Some("next-coherence") => *slot = TraitSolver::NextCoherence,
1036-
// default trait solver is subject to change..
1037-
Some("default") => *slot = TraitSolver::Classic,
1038-
_ => return false,
1029+
pub(crate) fn parse_new_solver_config(
1030+
slot: &mut Option<NextSolverConfig>,
1031+
v: Option<&str>,
1032+
) -> bool {
1033+
if let Some(config) = v {
1034+
let mut coherence = false;
1035+
let mut globally = true;
1036+
let mut dump_tree = None;
1037+
for c in config.split(',') {
1038+
match c {
1039+
"globally" => globally = true,
1040+
"coherence" => {
1041+
globally = false;
1042+
coherence = true;
1043+
}
1044+
"dump-tree" => {
1045+
if dump_tree.replace(DumpSolverProofTree::Always).is_some() {
1046+
return false;
1047+
}
1048+
}
1049+
"dump-tree-on-error" => {
1050+
if dump_tree.replace(DumpSolverProofTree::OnError).is_some() {
1051+
return false;
1052+
}
1053+
}
1054+
_ => return false,
1055+
}
1056+
}
1057+
1058+
*slot = Some(NextSolverConfig {
1059+
coherence: coherence || globally,
1060+
globally,
1061+
dump_tree: dump_tree.unwrap_or_default(),
1062+
});
1063+
} else {
1064+
*slot = Some(NextSolverConfig {
1065+
coherence: true,
1066+
globally: true,
1067+
dump_tree: Default::default(),
1068+
});
10391069
}
1070+
10401071
true
10411072
}
10421073

@@ -1301,19 +1332,6 @@ mod parse {
13011332
true
13021333
}
13031334

1304-
pub(crate) fn parse_dump_solver_proof_tree(
1305-
slot: &mut DumpSolverProofTree,
1306-
v: Option<&str>,
1307-
) -> bool {
1308-
match v {
1309-
None | Some("always") => *slot = DumpSolverProofTree::Always,
1310-
Some("never") => *slot = DumpSolverProofTree::Never,
1311-
Some("on-error") => *slot = DumpSolverProofTree::OnError,
1312-
_ => return false,
1313-
};
1314-
true
1315-
}
1316-
13171335
pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
13181336
match v {
13191337
Some("always" | "yes") => {
@@ -1585,9 +1603,6 @@ options! {
15851603
"output statistics about monomorphization collection"),
15861604
dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
15871605
"the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
1588-
dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
1589-
"dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
1590-
then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
15911606
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
15921607
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
15931608
dylib_lto: bool = (false, parse_bool, [UNTRACKED],
@@ -1714,6 +1729,8 @@ options! {
17141729
"the size at which the `large_assignments` lint starts to be emitted"),
17151730
mutable_noalias: bool = (true, parse_bool, [TRACKED],
17161731
"emit noalias metadata for mutable references (default: yes)"),
1732+
next_solver: Option<NextSolverConfig> = (None, parse_new_solver_config, [TRACKED],
1733+
"enable and configure the next generation trait solver used by rustc"),
17171734
nll_facts: bool = (false, parse_bool, [UNTRACKED],
17181735
"dump facts from NLL analysis into side files (default: no)"),
17191736
nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
@@ -1914,8 +1931,6 @@ written to standard error output)"),
19141931
"for every macro invocation, print its name and arguments (default: no)"),
19151932
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
19161933
"tracks where in rustc a diagnostic was emitted"),
1917-
trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
1918-
"specify the trait solver mode used by rustc (default: classic)"),
19191934
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
19201935
// alongside query results and changes to translation options can affect diagnostics - so
19211936
// translation options should be tracked.

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
200200
let result = f(&mut ecx);
201201

202202
let tree = ecx.inspect.finalize();
203-
if let (Some(tree), DumpSolverProofTree::Always) =
204-
(&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree)
205-
{
203+
if let (Some(tree), DumpSolverProofTree::Always) = (
204+
&tree,
205+
infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(),
206+
) {
206207
let mut lock = std::io::stdout().lock();
207208
let _ = lock.write_fmt(format_args!("{tree:?}\n"));
208209
let _ = lock.flush();

compiler/rustc_trait_selection/src/solve/inspect/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
265265
GenerateProofTree::Never => ProofTreeBuilder::new_noop(),
266266
GenerateProofTree::IfEnabled => {
267267
let opts = &tcx.sess.opts.unstable_opts;
268-
match opts.dump_solver_proof_tree {
268+
match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() {
269269
DumpSolverProofTree::Always => ProofTreeBuilder::new_root(),
270270
// `OnError` is handled by reevaluating goals in error
271271
// reporting with `GenerateProofTree::Yes`.

compiler/rustc_trait_selection/src/traits/engine.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,23 @@ use rustc_middle::ty::ToPredicate;
2525
use rustc_middle::ty::TypeFoldable;
2626
use rustc_middle::ty::Variance;
2727
use rustc_middle::ty::{self, Ty, TyCtxt};
28-
use rustc_session::config::TraitSolver;
2928

3029
pub trait TraitEngineExt<'tcx> {
3130
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self>;
3231
}
3332

3433
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
3534
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
36-
match (infcx.tcx.sess.opts.unstable_opts.trait_solver, infcx.next_trait_solver()) {
37-
(TraitSolver::Classic, false) | (TraitSolver::NextCoherence, false) => {
38-
Box::new(FulfillmentContext::new(infcx))
39-
}
40-
(TraitSolver::Classic | TraitSolver::Next | TraitSolver::NextCoherence, true) => {
41-
Box::new(NextFulfillmentCtxt::new(infcx))
42-
}
43-
(TraitSolver::Next, false) => bug!(
44-
"incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})",
45-
infcx.tcx.sess.opts.unstable_opts.trait_solver,
46-
infcx.next_trait_solver()
47-
),
35+
if infcx.next_trait_solver() {
36+
Box::new(NextFulfillmentCtxt::new(infcx))
37+
} else {
38+
let new_solver_globally =
39+
infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally);
40+
assert!(
41+
!new_solver_globally,
42+
"using old solver even though new solver is enabled globally"
43+
);
44+
Box::new(FulfillmentContext::new(infcx))
4845
}
4946
}
5047
}

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+21-20
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use rustc_middle::ty::{
3737
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
3838
TypeVisitable, TypeVisitableExt,
3939
};
40-
use rustc_session::config::{DumpSolverProofTree, TraitSolver};
40+
use rustc_session::config::DumpSolverProofTree;
4141
use rustc_session::Limit;
4242
use rustc_span::def_id::LOCAL_CRATE;
4343
use rustc_span::symbol::sym;
@@ -370,7 +370,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
370370
) {
371371
let tcx = self.tcx;
372372

373-
if tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
373+
if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
374+
== DumpSolverProofTree::OnError
375+
{
374376
dump_proof_tree(root_obligation, self.infcx);
375377
}
376378

@@ -810,23 +812,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
810812

811813
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
812814
let ty = self.resolve_vars_if_possible(ty);
813-
match self.tcx.sess.opts.unstable_opts.trait_solver {
814-
TraitSolver::Classic => {
815-
// WF predicates cannot themselves make
816-
// errors. They can only block due to
817-
// ambiguity; otherwise, they always
818-
// degenerate into other obligations
819-
// (which may fail).
820-
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
821-
}
822-
TraitSolver::Next | TraitSolver::NextCoherence => {
823-
// FIXME: we'll need a better message which takes into account
824-
// which bounds actually failed to hold.
825-
self.tcx.sess.struct_span_err(
826-
span,
827-
format!("the type `{ty}` is not well-formed"),
828-
)
829-
}
815+
if self.tcx.sess.opts.unstable_opts.next_solver.is_some() {
816+
// FIXME: we'll need a better message which takes into account
817+
// which bounds actually failed to hold.
818+
self.tcx.sess.struct_span_err(
819+
span,
820+
format!("the type `{ty}` is not well-formed"),
821+
)
822+
} else {
823+
// WF predicates cannot themselves make
824+
// errors. They can only block due to
825+
// ambiguity; otherwise, they always
826+
// degenerate into other obligations
827+
// (which may fail).
828+
span_bug!(span, "WF predicate not satisfied for {:?}", ty);
830829
}
831830
}
832831

@@ -1555,7 +1554,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15551554

15561555
#[instrument(skip(self), level = "debug")]
15571556
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
1558-
if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
1557+
if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
1558+
== DumpSolverProofTree::OnError
1559+
{
15591560
dump_proof_tree(&error.root_obligation, self.infcx);
15601561
}
15611562

0 commit comments

Comments
 (0)