Skip to content

Commit b7bc6f8

Browse files
committed
Auto merge of rust-lang#113330 - matthiaskrgr:rollup-zm3owin, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#113192 (`assemble_candidates_after_normalizing_self_ty` docs) - rust-lang#113251 (Use scoped-tls for SMIR to map between TyCtxt and SMIR datastructures) - rust-lang#113282 (Update platform-support.md to improve ARM target descriptions) - rust-lang#113296 (add flag for enabling global cache usage for proof trees and printing proof trees on error) - rust-lang#113324 (implement `ConstEvaluatable` goals in new solver) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f20afcc + 7996908 commit b7bc6f8

File tree

20 files changed

+298
-93
lines changed

20 files changed

+298
-93
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3937,6 +3937,7 @@ dependencies = [
39373937
"rustc_hir",
39383938
"rustc_middle",
39393939
"rustc_span",
3940+
"scoped-tls",
39403941
"tracing",
39413942
]
39423943

Diff for: compiler/rustc_session/src/config.rs

+8
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,14 @@ pub enum TraitSolver {
743743
NextCoherence,
744744
}
745745

746+
#[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)]
747+
pub enum DumpSolverProofTree {
748+
Always,
749+
OnError,
750+
#[default]
751+
Never,
752+
}
753+
746754
pub enum Input {
747755
/// Load source code from a file.
748756
File(PathBuf),

Diff for: compiler/rustc_session/src/options.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ mod desc {
418418
"a `,` separated combination of `bti`, `b-key`, `pac-ret`, or `leaf`";
419419
pub const parse_proc_macro_execution_strategy: &str =
420420
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
421+
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
421422
}
422423

423424
mod parse {
@@ -1237,6 +1238,19 @@ mod parse {
12371238
};
12381239
true
12391240
}
1241+
1242+
pub(crate) fn parse_dump_solver_proof_tree(
1243+
slot: &mut DumpSolverProofTree,
1244+
v: Option<&str>,
1245+
) -> bool {
1246+
match v {
1247+
None | Some("always") => *slot = DumpSolverProofTree::Always,
1248+
Some("never") => *slot = DumpSolverProofTree::Never,
1249+
Some("on-error") => *slot = DumpSolverProofTree::OnError,
1250+
_ => return false,
1251+
};
1252+
true
1253+
}
12401254
}
12411255

12421256
options! {
@@ -1462,8 +1476,11 @@ options! {
14621476
"output statistics about monomorphization collection"),
14631477
dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
14641478
"the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
1465-
dump_solver_proof_tree: bool = (false, parse_bool, [UNTRACKED],
1466-
"dump a proof tree for every goal evaluated by the new trait solver"),
1479+
dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
1480+
"dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
1481+
then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
1482+
dump_solver_proof_tree_use_cache: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
1483+
"determines whether dumped proof trees use the global cache"),
14671484
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
14681485
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
14691486
dylib_lto: bool = (false, parse_bool, [UNTRACKED],

Diff for: compiler/rustc_smir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rustc_hir = { path = "../rustc_hir" }
88
rustc_middle = { path = "../rustc_middle", optional = true }
99
rustc_span = { path = "../rustc_span", optional = true }
1010
tracing = "0.1"
11+
scoped-tls = "1.0"
1112

1213
[features]
1314
default = [

Diff for: compiler/rustc_smir/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ pub mod stable_mir;
1919

2020
// Make this module private for now since external users should not call these directly.
2121
mod rustc_smir;
22+
23+
#[macro_use]
24+
extern crate scoped_tls;

Diff for: compiler/rustc_smir/src/stable_mir/mod.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -100,28 +100,28 @@ pub trait Context {
100100
fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
101101
}
102102

103-
thread_local! {
104-
/// A thread local variable that stores a pointer to the tables mapping between TyCtxt
105-
/// datastructures and stable MIR datastructures.
106-
static TLV: Cell<*mut ()> = const { Cell::new(std::ptr::null_mut()) };
107-
}
103+
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
104+
// datastructures and stable MIR datastructures
105+
scoped_thread_local! (static TLV: Cell<*mut ()>);
108106

109107
pub fn run(mut context: impl Context, f: impl FnOnce()) {
110-
assert!(TLV.get().is_null());
108+
assert!(!TLV.is_set());
111109
fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
112-
TLV.set(&mut context as *mut &mut _ as _);
113-
f();
114-
TLV.replace(std::ptr::null_mut());
110+
let ptr: *mut () = &mut context as *mut &mut _ as _;
111+
TLV.set(&Cell::new(ptr), || {
112+
f();
113+
});
115114
}
116115
g(&mut context, f);
117116
}
118117

119118
/// Loads the current context and calls a function with it.
120119
/// Do not nest these, as that will ICE.
121120
pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
122-
let ptr = TLV.replace(std::ptr::null_mut()) as *mut &mut dyn Context;
123-
assert!(!ptr.is_null());
124-
let ret = f(unsafe { *ptr });
125-
TLV.set(ptr as _);
126-
ret
121+
assert!(TLV.is_set());
122+
TLV.with(|tlv| {
123+
let ptr = tlv.get();
124+
assert!(!ptr.is_null());
125+
f(unsafe { *(ptr as *mut &mut dyn Context) })
126+
})
127127
}

Diff for: compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
331331
candidates
332332
}
333333

334-
/// If the self type of a goal is an alias, computing the relevant candidates is difficult.
334+
/// If the self type of a goal is an alias we first try to normalize the self type
335+
/// and compute the candidates for the normalized self type in case that succeeds.
335336
///
336-
/// To deal with this, we first try to normalize the self type and add the candidates for the normalized
337-
/// self type to the list of candidates in case that succeeds. We also have to consider candidates with the
338-
/// projection as a self type as well
337+
/// These candidates are used in addition to the ones with the alias as a self type.
338+
/// We do this to simplify both builtin candidates and for better performance.
339+
///
340+
/// We generate the builtin candidates on the fly by looking at the self type, e.g.
341+
/// add `FnPtr` candidates if the self type is a function pointer. Handling builtin
342+
/// candidates while the self type is still an alias seems difficult. This is similar
343+
/// to `try_structurally_resolve_type` during hir typeck (FIXME once implemented).
344+
///
345+
/// Looking at all impls for some trait goal is prohibitively expensive. We therefore
346+
/// only look at implementations with a matching self type. Because of this function,
347+
/// we can avoid looking at all existing impls if the self type is an alias.
339348
#[instrument(level = "debug", skip_all)]
340349
fn assemble_candidates_after_normalizing_self_ty<G: GoalKind<'tcx>>(
341350
&mut self,

Diff for: compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+28-13
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use rustc_middle::ty::{
1919
self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
2020
TypeVisitableExt, TypeVisitor,
2121
};
22+
use rustc_session::config::DumpSolverProofTree;
2223
use rustc_span::DUMMY_SP;
24+
use std::io::Write;
2325
use std::ops::ControlFlow;
2426

2527
use crate::traits::specialization_graph;
@@ -113,9 +115,23 @@ impl NestedGoals<'_> {
113115

114116
#[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
115117
pub enum GenerateProofTree {
118+
Yes(UseGlobalCache),
119+
No,
120+
}
121+
122+
#[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
123+
pub enum UseGlobalCache {
116124
Yes,
117125
No,
118126
}
127+
impl UseGlobalCache {
128+
pub fn from_bool(use_cache: bool) -> Self {
129+
match use_cache {
130+
true => UseGlobalCache::Yes,
131+
false => UseGlobalCache::No,
132+
}
133+
}
134+
}
119135

120136
pub trait InferCtxtEvalExt<'tcx> {
121137
/// Evaluates a goal from **outside** of the trait solver.
@@ -177,17 +193,17 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
177193
var_values: CanonicalVarValues::dummy(),
178194
nested_goals: NestedGoals::new(),
179195
tainted: Ok(()),
180-
inspect: (infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree
181-
|| matches!(generate_proof_tree, GenerateProofTree::Yes))
182-
.then(ProofTreeBuilder::new_root)
183-
.unwrap_or_else(ProofTreeBuilder::new_noop),
196+
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree),
184197
};
185198
let result = f(&mut ecx);
186199

187200
let tree = ecx.inspect.finalize();
188-
if let Some(tree) = &tree {
189-
// module to allow more granular RUSTC_LOG filtering to just proof tree output
190-
super::inspect::dump::print_tree(tree);
201+
if let (Some(tree), DumpSolverProofTree::Always) =
202+
(&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree)
203+
{
204+
let mut lock = std::io::stdout().lock();
205+
let _ = lock.write_fmt(format_args!("{tree:?}"));
206+
let _ = lock.flush();
191207
}
192208

193209
assert!(
@@ -425,12 +441,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
425441
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
426442
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
427443
}
428-
ty::PredicateKind::Ambiguous => {
429-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
430-
}
431-
// FIXME: implement this predicate :)
432-
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => {
433-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
444+
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
445+
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
434446
}
435447
ty::PredicateKind::ConstEquate(_, _) => {
436448
bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active")
@@ -440,6 +452,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
440452
param_env,
441453
predicate: (lhs, rhs, direction),
442454
}),
455+
ty::PredicateKind::Ambiguous => {
456+
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
457+
}
443458
}
444459
} else {
445460
let kind = self.infcx.instantiate_binder_with_placeholders(kind);

0 commit comments

Comments
 (0)