Skip to content

Commit a213bb3

Browse files
committed
implement the skeleton of the updated trait solver
1 parent 4653c93 commit a213bb3

File tree

21 files changed

+1569
-87
lines changed

21 files changed

+1569
-87
lines changed

compiler/rustc_infer/src/infer/canonical/query_response.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ impl<'tcx> InferCtxt<'tcx> {
151151
})
152152
}
153153

154-
fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> {
154+
/// FIXME: This method should only be used for canonical queries and therefore be private.
155+
///
156+
/// As the new solver does canonicalization slightly differently, this is also used there
157+
/// for now. This should hopefully change fairly soon.
158+
pub fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> {
155159
self.inner
156160
.borrow_mut()
157161
.opaque_type_storage

compiler/rustc_middle/src/infer/canonical.rs

+10
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ impl<'tcx, V> Canonical<'tcx, V> {
300300
let Canonical { max_universe, variables, value } = self;
301301
Canonical { max_universe, variables, value: map_op(value) }
302302
}
303+
304+
/// Allows you to map the `value` of a canonical while keeping the same set of
305+
/// bound variables.
306+
///
307+
/// **WARNING:** This function is very easy to mis-use, hence the name! See
308+
/// the comment of [Canonical::unchecked_map] for more details.
309+
pub fn unchecked_rebind<W>(self, value: W) -> Canonical<'tcx, W> {
310+
let Canonical { max_universe, variables, value: _ } = self;
311+
Canonical { max_universe, variables, value }
312+
}
303313
}
304314

305315
pub type QueryOutlivesConstraint<'tcx> = (

compiler/rustc_middle/src/traits/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
9696
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
9797
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
9898

99-
#[derive(Copy, Clone, Debug, HashStable)]
99+
#[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)]
100100
pub struct NoSolution;
101101

102102
pub type Fallible<T> = Result<T, NoSolution>;

compiler/rustc_middle/src/traits/specialization_graph.rs

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ impl Iterator for Ancestors<'_> {
180180
}
181181

182182
/// Information about the most specialized definition of an associated item.
183+
#[derive(Debug)]
183184
pub struct LeafDef {
184185
/// The associated item described by this `LeafDef`.
185186
pub item: ty::AssocItem,

compiler/rustc_middle/src/ty/mod.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,17 @@ impl<'tcx> Predicate<'tcx> {
535535
self
536536
}
537537

538+
#[instrument(level = "debug", skip(tcx), ret)]
539+
pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool {
540+
match self.kind().skip_binder() {
541+
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
542+
tcx.trait_is_coinductive(data.def_id())
543+
}
544+
ty::PredicateKind::WellFormed(_) => true,
545+
_ => false,
546+
}
547+
}
548+
538549
/// Whether this projection can be soundly normalized.
539550
///
540551
/// Wf predicates must not be normalized, as normalization
@@ -1018,6 +1029,24 @@ pub struct ProjectionPredicate<'tcx> {
10181029
pub term: Term<'tcx>,
10191030
}
10201031

1032+
impl<'tcx> ProjectionPredicate<'tcx> {
1033+
pub fn self_ty(self) -> Ty<'tcx> {
1034+
self.projection_ty.self_ty()
1035+
}
1036+
1037+
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> {
1038+
Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self }
1039+
}
1040+
1041+
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
1042+
self.projection_ty.trait_def_id(tcx)
1043+
}
1044+
1045+
pub fn def_id(self) -> DefId {
1046+
self.projection_ty.def_id
1047+
}
1048+
}
1049+
10211050
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
10221051

10231052
impl<'tcx> PolyProjectionPredicate<'tcx> {
@@ -1054,18 +1083,6 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
10541083
}
10551084
}
10561085

1057-
impl<'tcx> ProjectionPredicate<'tcx> {
1058-
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
1059-
Self {
1060-
projection_ty: tcx.mk_alias_ty(
1061-
self.projection_ty.def_id,
1062-
[self_ty.into()].into_iter().chain(self.projection_ty.substs.iter().skip(1)),
1063-
),
1064-
..self
1065-
}
1066-
}
1067-
}
1068-
10691086
pub trait ToPolyTraitRef<'tcx> {
10701087
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
10711088
}

compiler/rustc_middle/src/ty/sty.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ pub struct AliasTy<'tcx> {
11691169
}
11701170

11711171
impl<'tcx> AliasTy<'tcx> {
1172-
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
1172+
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
11731173
match tcx.def_kind(self.def_id) {
11741174
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
11751175
DefKind::ImplTraitPlaceholder => {
@@ -1183,7 +1183,7 @@ impl<'tcx> AliasTy<'tcx> {
11831183
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
11841184
/// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
11851185
pub fn trait_ref_and_own_substs(
1186-
&self,
1186+
self,
11871187
tcx: TyCtxt<'tcx>,
11881188
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
11891189
debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst));
@@ -1202,14 +1202,18 @@ impl<'tcx> AliasTy<'tcx> {
12021202
/// WARNING: This will drop the substs for generic associated types
12031203
/// consider calling [Self::trait_ref_and_own_substs] to get those
12041204
/// as well.
1205-
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
1205+
pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
12061206
let def_id = self.trait_def_id(tcx);
12071207
tcx.mk_trait_ref(def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id)))
12081208
}
12091209

1210-
pub fn self_ty(&self) -> Ty<'tcx> {
1210+
pub fn self_ty(self) -> Ty<'tcx> {
12111211
self.substs.type_at(0)
12121212
}
1213+
1214+
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
1215+
tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)))
1216+
}
12131217
}
12141218

12151219
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]

compiler/rustc_middle/src/ty/subst.rs

+4
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ impl<T> EarlyBinder<T> {
573573
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
574574
EarlyBinder(value)
575575
}
576+
577+
pub fn skip_binder(self) -> T {
578+
self.0
579+
}
576580
}
577581

578582
impl<T> EarlyBinder<Option<T>> {

compiler/rustc_trait_selection/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#![feature(let_chains)]
2020
#![feature(if_let_guard)]
2121
#![feature(never_type)]
22+
#![feature(result_option_inspect)]
2223
#![feature(type_alias_impl_trait)]
2324
#![recursion_limit = "512"] // For rustdoc
2425

@@ -37,4 +38,5 @@ extern crate smallvec;
3738
pub mod autoderef;
3839
pub mod errors;
3940
pub mod infer;
41+
pub mod solve;
4042
pub mod traits;

0 commit comments

Comments
 (0)