Skip to content

Commit 41883fd

Browse files
intern external constraints
1 parent 658fad6 commit 41883fd

File tree

7 files changed

+80
-22
lines changed

7 files changed

+80
-22
lines changed

compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ macro_rules! arena_types {
112112

113113
[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
114114
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
115+
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
115116
]);
116117
)
117118
}

compiler/rustc_middle/src/traits/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
mod chalk;
66
pub mod query;
77
pub mod select;
8+
pub mod solve;
89
pub mod specialization_graph;
910
mod structural_impls;
1011
pub mod util;
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use std::ops::ControlFlow;
2+
3+
use rustc_data_structures::intern::Interned;
4+
5+
use crate::ty::{FallibleTypeFolder, Ty, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor};
6+
7+
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
8+
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
9+
10+
impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
11+
type Target = ExternalConstraintsData<'tcx>;
12+
13+
fn deref(&self) -> &Self::Target {
14+
&*self.0
15+
}
16+
}
17+
18+
/// Additional constraints returned on success.
19+
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
20+
pub struct ExternalConstraintsData<'tcx> {
21+
// FIXME: implement this.
22+
pub regions: (),
23+
pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>,
24+
}
25+
26+
impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> {
27+
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
28+
Ok(FallibleTypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData {
29+
regions: (),
30+
opaque_types: self
31+
.opaque_types
32+
.iter()
33+
.map(|opaque| opaque.try_fold_with(folder))
34+
.collect::<Result<_, F::Error>>()?,
35+
}))
36+
}
37+
38+
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
39+
TypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData {
40+
regions: (),
41+
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
42+
})
43+
}
44+
}
45+
46+
impl<'tcx> TypeVisitable<'tcx> for ExternalConstraints<'tcx> {
47+
fn visit_with<V: TypeVisitor<'tcx>>(
48+
&self,
49+
visitor: &mut V,
50+
) -> std::ops::ControlFlow<V::BreakTy> {
51+
self.regions.visit_with(visitor)?;
52+
self.opaque_types.visit_with(visitor)?;
53+
ControlFlow::Continue(())
54+
}
55+
}

compiler/rustc_middle/src/ty/context.rs

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::mir::{
1717
};
1818
use crate::thir::Thir;
1919
use crate::traits;
20+
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
2021
use crate::ty::query::{self, TyCtxtAt};
2122
use crate::ty::{
2223
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
@@ -148,6 +149,7 @@ pub struct CtxtInterners<'tcx> {
148149
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
149150
layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
150151
adt_def: InternedSet<'tcx, AdtDefData>,
152+
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
151153
}
152154

153155
impl<'tcx> CtxtInterners<'tcx> {
@@ -169,6 +171,7 @@ impl<'tcx> CtxtInterners<'tcx> {
169171
bound_variable_kinds: Default::default(),
170172
layout: Default::default(),
171173
adt_def: Default::default(),
174+
external_constraints: Default::default(),
172175
}
173176
}
174177

@@ -1449,6 +1452,7 @@ direct_interners! {
14491452
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
14501453
layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
14511454
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
1455+
external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>,
14521456
}
14531457

14541458
macro_rules! slice_interners {

compiler/rustc_trait_selection/src/solve/mod.rs

+16-19
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
2424
use rustc_infer::traits::query::NoSolution;
2525
use rustc_infer::traits::Obligation;
2626
use rustc_middle::infer::canonical::Certainty as OldCertainty;
27-
use rustc_middle::ty::{self, Ty, TyCtxt};
27+
use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
28+
use rustc_middle::ty::{self, TyCtxt};
2829
use rustc_middle::ty::{
2930
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
3031
};
@@ -72,8 +73,7 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for Goal<'tcx, P> {
7273
Goal { param_env: obligation.param_env, predicate: obligation.predicate }
7374
}
7475
}
75-
76-
#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable)]
76+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
7777
pub struct Response<'tcx> {
7878
pub var_values: CanonicalVarValues<'tcx>,
7979
/// Additional constraints returned by this query.
@@ -121,14 +121,6 @@ pub enum MaybeCause {
121121
Overflow,
122122
}
123123

124-
/// Additional constraints returned on success.
125-
#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable, Default)]
126-
pub struct ExternalConstraints<'tcx> {
127-
// FIXME: implement this.
128-
regions: (),
129-
opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>,
130-
}
131-
132124
type CanonicalGoal<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, Goal<'tcx, T>>;
133125
type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
134126
/// The result of evaluating a canonical query.
@@ -218,15 +210,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
218210
EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false };
219211
let result = ecx.compute_goal(goal);
220212

221-
// FIXME: `Response` should be `Copy`
222-
if search_graph.try_finalize_goal(tcx, canonical_goal, result.clone()) {
213+
if search_graph.try_finalize_goal(tcx, canonical_goal, result) {
223214
return result;
224215
}
225216
}
226217
}
227218

228219
fn make_canonical_response(&self, certainty: Certainty) -> QueryResult<'tcx> {
229-
let external_constraints = take_external_constraints(self.infcx)?;
220+
let external_constraints = compute_external_query_constraints(self.infcx)?;
230221

231222
Ok(self.infcx.canonicalize_response(Response {
232223
var_values: self.var_values,
@@ -461,18 +452,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
461452
}
462453

463454
#[instrument(level = "debug", skip(infcx), ret)]
464-
fn take_external_constraints<'tcx>(
455+
fn compute_external_query_constraints<'tcx>(
465456
infcx: &InferCtxt<'tcx>,
466457
) -> Result<ExternalConstraints<'tcx>, NoSolution> {
467458
let region_obligations = infcx.take_registered_region_obligations();
468459
let opaque_types = infcx.take_opaque_types_for_query_response();
469-
Ok(ExternalConstraints {
460+
Ok(infcx.tcx.intern_external_constraints(ExternalConstraintsData {
470461
// FIXME: Now that's definitely wrong :)
471462
//
472463
// Should also do the leak check here I think
473464
regions: drop(region_obligations),
474465
opaque_types,
475-
})
466+
}))
476467
}
477468

478469
fn instantiate_canonical_query_response<'tcx>(
@@ -492,7 +483,10 @@ fn instantiate_canonical_query_response<'tcx>(
492483
Certainty::Yes => OldCertainty::Proven,
493484
Certainty::Maybe(_) => OldCertainty::Ambiguous,
494485
},
495-
opaque_types: resp.external_constraints.opaque_types,
486+
// FIXME: This to_owned makes me sad, but we should eventually impl
487+
// `instantiate_query_response_and_region_obligations` separately
488+
// instead of piggybacking off of the old implementation.
489+
opaque_types: resp.external_constraints.opaque_types.to_owned(),
496490
value: resp.certainty,
497491
}),
498492
) else { bug!(); };
@@ -510,7 +504,10 @@ pub(super) fn response_no_constraints<'tcx>(
510504
variables: goal.variables,
511505
value: Response {
512506
var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
513-
external_constraints: Default::default(),
507+
// FIXME: maybe we should store the "no response" version in tcx, like
508+
// we do for tcx.types and stuff.
509+
external_constraints: tcx
510+
.intern_external_constraints(ExternalConstraintsData::default()),
514511
certainty,
515512
},
516513
})

compiler/rustc_trait_selection/src/solve/search_graph/cache.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ impl<'tcx> ProvisionalCache<'tcx> {
9595
}
9696

9797
pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> QueryResult<'tcx> {
98-
// FIXME: Responses should probably be `Copy` as well
99-
self.entries[entry_index].response.clone()
98+
self.entries[entry_index].response
10099
}
101100
}
102101

triagebot.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@ new_pr = true
250250

251251
[autolabel."WG-trait-system-refactor"]
252252
trigger_files = [
253-
"compiler/rustc_trait_selection/src/solve"
253+
"compiler/rustc_trait_selection/src/solve",
254+
"compiler/rustc_middle/src/traits/solve.rs"
254255
]
255256

256257
[notify-zulip."I-prioritize"]

0 commit comments

Comments
 (0)