Skip to content

Commit 5d97ada

Browse files
committed
rename -Ztrait-solver to -Znext-solver
1 parent 1aa6aef commit 5d97ada

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;
@@ -781,6 +780,10 @@ fn test_unstable_options_tracking_hash() {
781780
tracked!(mir_opt_level, Some(4));
782781
tracked!(move_size_limit, Some(4096));
783782
tracked!(mutable_noalias, false);
783+
tracked!(
784+
next_solver,
785+
Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() })
786+
);
784787
tracked!(no_generate_arange_section, true);
785788
tracked!(no_jump_tables, true);
786789
tracked!(no_link, true);
@@ -822,7 +825,6 @@ fn test_unstable_options_tracking_hash() {
822825
tracked!(thir_unsafeck, true);
823826
tracked!(tiny_const_eval_limit, true);
824827
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
825-
tracked!(trait_solver, TraitSolver::NextCoherence);
826828
tracked!(translate_remapped_path_to_local_path, false);
827829
tracked!(trap_unreachable, Some(false));
828830
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
@@ -2240,15 +2240,11 @@ impl<'tcx> TyCtxt<'tcx> {
22402240
}
22412241

22422242
pub fn next_trait_solver_globally(self) -> bool {
2243-
self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next
2243+
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
22442244
}
22452245

22462246
pub fn next_trait_solver_in_coherence(self) -> bool {
2247-
matches!(
2248-
self.sess.opts.unstable_opts.trait_solver,
2249-
rustc_session::config::TraitSolver::Next
2250-
| rustc_session::config::TraitSolver::NextCoherence
2251-
)
2247+
self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
22522248
}
22532249

22542250
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)]
@@ -3220,10 +3221,10 @@ pub(crate) mod dep_tracking {
32203221
use super::{
32213222
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
32223223
ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay,
3223-
LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType,
3224-
OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
3225-
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
3226-
WasiExecModel,
3224+
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel,
3225+
OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks,
3226+
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
3227+
TrimmedDefPaths, WasiExecModel,
32273228
};
32283229
use crate::lint;
32293230
use crate::utils::NativeLib;
@@ -3326,7 +3327,7 @@ pub(crate) mod dep_tracking {
33263327
BranchProtection,
33273328
OomStrategy,
33283329
LanguageIdentifier,
3329-
TraitSolver,
3330+
NextSolverConfig,
33303331
Polonius,
33313332
InliningThreshold,
33323333
FunctionReturn,

compiler/rustc_session/src/options.rs

+44-29
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,7 @@ mod desc {
396396
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`";
397397
pub const parse_unpretty: &str = "`string` or `string=string`";
398398
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
399-
pub const parse_trait_solver: &str =
400-
"one of the supported solver modes (`classic`, `next`, or `next-coherence`)";
399+
pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error";
401400
pub const parse_lto: &str =
402401
"either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
403402
pub const parse_linker_plugin_lto: &str =
@@ -429,7 +428,6 @@ mod desc {
429428
"a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
430429
pub const parse_proc_macro_execution_strategy: &str =
431430
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
432-
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
433431
pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
434432
pub const parse_inlining_threshold: &str =
435433
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
@@ -1032,15 +1030,48 @@ mod parse {
10321030
}
10331031
}
10341032

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

@@ -1305,19 +1336,6 @@ mod parse {
13051336
true
13061337
}
13071338

1308-
pub(crate) fn parse_dump_solver_proof_tree(
1309-
slot: &mut DumpSolverProofTree,
1310-
v: Option<&str>,
1311-
) -> bool {
1312-
match v {
1313-
None | Some("always") => *slot = DumpSolverProofTree::Always,
1314-
Some("never") => *slot = DumpSolverProofTree::Never,
1315-
Some("on-error") => *slot = DumpSolverProofTree::OnError,
1316-
_ => return false,
1317-
};
1318-
true
1319-
}
1320-
13211339
pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
13221340
match v {
13231341
Some("always" | "yes") => {
@@ -1591,9 +1609,6 @@ options! {
15911609
"output statistics about monomorphization collection"),
15921610
dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
15931611
"the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
1594-
dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
1595-
"dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
1596-
then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
15971612
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
15981613
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
15991614
dylib_lto: bool = (false, parse_bool, [UNTRACKED],
@@ -1722,6 +1737,8 @@ options! {
17221737
"the size at which the `large_assignments` lint starts to be emitted"),
17231738
mutable_noalias: bool = (true, parse_bool, [TRACKED],
17241739
"emit noalias metadata for mutable references (default: yes)"),
1740+
next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED],
1741+
"enable and configure the next generation trait solver used by rustc"),
17251742
nll_facts: bool = (false, parse_bool, [UNTRACKED],
17261743
"dump facts from NLL analysis into side files (default: no)"),
17271744
nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
@@ -1922,8 +1939,6 @@ written to standard error output)"),
19221939
"for every macro invocation, print its name and arguments (default: no)"),
19231940
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
19241941
"tracks where in rustc a diagnostic was emitted"),
1925-
trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
1926-
"specify the trait solver mode used by rustc (default: classic)"),
19271942
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
19281943
// alongside query results and changes to translation options can affect diagnostics - so
19291944
// 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

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

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

@@ -1562,7 +1561,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15621561

15631562
#[instrument(skip(self), level = "debug")]
15641563
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
1565-
if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree == DumpSolverProofTree::OnError {
1564+
if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default()
1565+
== DumpSolverProofTree::OnError
1566+
{
15661567
dump_proof_tree(&error.root_obligation, self.infcx);
15671568
}
15681569

0 commit comments

Comments
 (0)