Skip to content

Commit

Permalink
rename -Ztrait-solver to -Znext-solver
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Dec 14, 2023
1 parent 1aa6aef commit 5d97ada
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 89 deletions.
12 changes: 7 additions & 5 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ use rustc_session::config::{
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;
Expand Down Expand Up @@ -781,6 +780,10 @@ fn test_unstable_options_tracking_hash() {
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);
Expand Down Expand Up @@ -822,7 +825,6 @@ fn test_unstable_options_tracking_hash() {
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));
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2240,15 +2240,11 @@ impl<'tcx> TyCtxt<'tcx> {
}

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 {
Expand Down
25 changes: 13 additions & 12 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -3326,7 +3327,7 @@ pub(crate) mod dep_tracking {
BranchProtection,
OomStrategy,
LanguageIdentifier,
TraitSolver,
NextSolverConfig,
Polonius,
InliningThreshold,
FunctionReturn,
Expand Down
73 changes: 44 additions & 29 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -1032,15 +1030,48 @@ mod parse {
}
}

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,
_ => return false,
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
}

Expand Down Expand Up @@ -1305,19 +1336,6 @@ mod parse {
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") => {
Expand Down Expand Up @@ -1591,9 +1609,6 @@ options! {
"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],
Expand Down Expand Up @@ -1722,6 +1737,8 @@ options! {
"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],
Expand Down Expand Up @@ -1922,8 +1939,6 @@ written to standard error output)"),
"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.
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
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();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/inspect/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
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`.
Expand Down
23 changes: 10 additions & 13 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,23 @@ use rustc_middle::ty::ToPredicate;
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>;
}

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) => {
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()
),
if infcx.next_trait_solver() {
Box::new(NextFulfillmentCtxt::new(infcx))
} 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))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use rustc_middle::ty::{
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;
Expand Down Expand Up @@ -370,7 +370,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) {
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);
}

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

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 => {
// 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"),
)
}
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);
}
}

Expand Down Expand Up @@ -1562,7 +1561,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, '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);
}

Expand Down

0 comments on commit 5d97ada

Please sign in to comment.