Skip to content

Commit 4d67032

Browse files
Merge #8117
8117: Turn Obligation into something similar to chalk_ir::DomainGoal r=flodiebold a=flodiebold This includes starting to make use of Chalk's `Cast` trait. Co-authored-by: Florian Diebold <[email protected]>
2 parents 5ac0290 + 7ec3b66 commit 4d67032

File tree

14 files changed

+130
-91
lines changed

14 files changed

+130
-91
lines changed

crates/hir/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ use hir_ty::{
5656
primitive::UintTy,
5757
to_assoc_type_id,
5858
traits::{FnTrait, Solution, SolutionVariables},
59-
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
60-
InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
59+
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex,
60+
InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind,
6161
TyVariableKind, WhereClause,
6262
};
6363
use itertools::Itertools;
@@ -1767,7 +1767,7 @@ impl Type {
17671767
let goal = Canonical {
17681768
value: hir_ty::InEnvironment::new(
17691769
self.ty.environment.clone(),
1770-
hir_ty::Obligation::Trait(trait_ref),
1770+
trait_ref.cast(&Interner),
17711771
),
17721772
kinds: Arc::new([]),
17731773
};
@@ -1789,14 +1789,15 @@ impl Type {
17891789
let goal = Canonical {
17901790
value: InEnvironment::new(
17911791
self.ty.environment.clone(),
1792-
Obligation::AliasEq(AliasEq {
1792+
AliasEq {
17931793
alias: AliasTy::Projection(ProjectionTy {
17941794
associated_ty_id: to_assoc_type_id(alias.id),
17951795
substitution: subst,
17961796
}),
17971797
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
17981798
.intern(&Interner),
1799-
}),
1799+
}
1800+
.cast(&Interner),
18001801
),
18011802
kinds: Arc::new([TyVariableKind::General]),
18021803
};

crates/hir_ty/src/autoderef.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use std::iter::successors;
77

88
use base_db::CrateId;
9+
use chalk_ir::cast::Cast;
910
use hir_def::lang_item::LangItemTarget;
1011
use hir_expand::name::name;
1112
use log::{info, warn};
@@ -15,8 +16,8 @@ use crate::{
1516
to_assoc_type_id, to_chalk_trait_id,
1617
traits::{InEnvironment, Solution},
1718
utils::generics,
18-
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
19-
Substitution, TraitRef, Ty, TyKind,
19+
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution,
20+
TraitRef, Ty, TyKind,
2021
};
2122

2223
const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -74,7 +75,7 @@ fn deref_by_trait(
7475
let implements_goal = Canonical {
7576
kinds: ty.value.kinds.clone(),
7677
value: InEnvironment {
77-
value: Obligation::Trait(trait_ref),
78+
value: trait_ref.cast(&Interner),
7879
environment: ty.environment.clone(),
7980
},
8081
};
@@ -92,7 +93,7 @@ fn deref_by_trait(
9293
.intern(&Interner),
9394
};
9495

95-
let obligation = super::Obligation::AliasEq(projection);
96+
let obligation = projection.cast(&Interner);
9697

9798
let in_env = InEnvironment { value: obligation, environment: ty.environment };
9899

crates/hir_ty/src/chalk_cast.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//! Implementations of the Chalk `Cast` trait for our types.
2+
3+
use chalk_ir::{
4+
cast::{Cast, CastTo},
5+
interner::HasInterner,
6+
};
7+
8+
use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
9+
10+
macro_rules! has_interner {
11+
($t:ty) => {
12+
impl HasInterner for $t {
13+
type Interner = crate::Interner;
14+
}
15+
};
16+
}
17+
18+
has_interner!(WhereClause);
19+
has_interner!(DomainGoal);
20+
21+
impl CastTo<WhereClause> for TraitRef {
22+
fn cast_to(self, _interner: &Interner) -> WhereClause {
23+
WhereClause::Implemented(self)
24+
}
25+
}
26+
27+
impl CastTo<WhereClause> for AliasEq {
28+
fn cast_to(self, _interner: &Interner) -> WhereClause {
29+
WhereClause::AliasEq(self)
30+
}
31+
}
32+
33+
impl CastTo<DomainGoal> for WhereClause {
34+
fn cast_to(self, _interner: &Interner) -> DomainGoal {
35+
DomainGoal::Holds(self)
36+
}
37+
}
38+
39+
macro_rules! transitive_impl {
40+
($a:ty, $b:ty, $c:ty) => {
41+
impl CastTo<$c> for $a {
42+
fn cast_to(self, interner: &Interner) -> $c {
43+
self.cast::<$b>(interner).cast(interner)
44+
}
45+
}
46+
};
47+
}
48+
49+
// In Chalk, these can be done as blanket impls, but that doesn't work here
50+
// because of coherence
51+
52+
transitive_impl!(TraitRef, WhereClause, DomainGoal);
53+
transitive_impl!(AliasEq, WhereClause, DomainGoal);

crates/hir_ty/src/db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
119119
fn trait_solve(
120120
&self,
121121
krate: CrateId,
122-
goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
122+
goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
123123
) -> Option<crate::traits::Solution>;
124124

125125
#[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]

crates/hir_ty/src/display.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use hir_expand::name::Name;
1919
use crate::{
2020
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
2121
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22-
CallableDefId, CallableSig, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
22+
CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
2323
ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
2424
};
2525

@@ -805,22 +805,12 @@ impl HirDisplay for Lifetime {
805805
}
806806
}
807807

808-
impl HirDisplay for Obligation {
808+
impl HirDisplay for DomainGoal {
809809
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
810810
match self {
811-
Obligation::Trait(tr) => {
812-
write!(f, "Implements(")?;
813-
tr.hir_fmt(f)?;
814-
write!(f, ")")
815-
}
816-
Obligation::AliasEq(AliasEq { alias, ty }) => {
817-
write!(f, "Normalize(")?;
818-
match alias {
819-
AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
820-
AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
821-
}
822-
write!(f, " => ")?;
823-
ty.hir_fmt(f)?;
811+
DomainGoal::Holds(wc) => {
812+
write!(f, "Holds(")?;
813+
wc.hir_fmt(f)?;
824814
write!(f, ")")
825815
}
826816
}

crates/hir_ty/src/infer.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::mem;
1818
use std::ops::Index;
1919
use std::sync::Arc;
2020

21-
use chalk_ir::Mutability;
21+
use chalk_ir::{cast::Cast, Mutability};
2222
use hir_def::{
2323
body::Body,
2424
data::{ConstData, FunctionData, StaticData},
@@ -37,7 +37,7 @@ use stdx::impl_from;
3737
use syntax::SmolStr;
3838

3939
use super::{
40-
traits::{Guidance, Obligation, Solution},
40+
traits::{DomainGoal, Guidance, Solution},
4141
InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
4242
};
4343
use crate::{
@@ -204,7 +204,7 @@ struct InferenceContext<'a> {
204204
resolver: Resolver,
205205
table: unify::InferenceTable,
206206
trait_env: Arc<TraitEnvironment>,
207-
obligations: Vec<Obligation>,
207+
obligations: Vec<DomainGoal>,
208208
result: InferenceResult,
209209
/// The return type of the function being inferred, or the closure if we're
210210
/// currently within one.
@@ -403,8 +403,8 @@ impl<'a> InferenceContext<'a> {
403403
}),
404404
ty: ty.clone(),
405405
};
406-
self.obligations.push(Obligation::Trait(trait_ref));
407-
self.obligations.push(Obligation::AliasEq(alias_eq));
406+
self.obligations.push(trait_ref.cast(&Interner));
407+
self.obligations.push(alias_eq.cast(&Interner));
408408
self.resolve_ty_as_possible(ty)
409409
}
410410
None => self.err_ty(),
@@ -430,7 +430,7 @@ impl<'a> InferenceContext<'a> {
430430
fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
431431
let var = self.table.new_type_var();
432432
let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
433-
let obligation = Obligation::AliasEq(alias_eq);
433+
let obligation = alias_eq.cast(&Interner);
434434
self.obligations.push(obligation);
435435
var
436436
}

crates/hir_ty/src/infer/coerce.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
//!
55
//! See: https://doc.rust-lang.org/nomicon/coercions.html
66
7-
use chalk_ir::{Mutability, TyVariableKind};
7+
use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
88
use hir_def::lang_item::LangItemTarget;
99

1010
use crate::{
11-
autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
12-
Ty, TyKind,
11+
autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
1312
};
1413

1514
use super::{InEnvironment, InferenceContext};
@@ -143,7 +142,7 @@ impl<'a> InferenceContext<'a> {
143142
.build();
144143
let trait_ref =
145144
TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
146-
let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref));
145+
let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner));
147146

148147
let canonicalizer = self.canonicalizer();
149148
let canonicalized = canonicalizer.canonicalize_obligation(goal);

crates/hir_ty/src/infer/expr.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::iter::{repeat, repeat_with};
44
use std::{mem, sync::Arc};
55

6-
use chalk_ir::{Mutability, TyVariableKind};
6+
use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
77
use hir_def::{
88
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
99
path::{GenericArg, GenericArgs},
@@ -21,7 +21,7 @@ use crate::{
2121
to_assoc_type_id, to_chalk_trait_id,
2222
traits::{chalk::from_chalk, FnTrait, InEnvironment},
2323
utils::{generics, variant_data, Generics},
24-
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
24+
AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar,
2525
Substitution, TraitRef, Ty, TyKind,
2626
};
2727

@@ -90,10 +90,9 @@ impl<'a> InferenceContext<'a> {
9090
Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
9191

9292
let trait_env = Arc::clone(&self.trait_env);
93-
let implements_fn_trait = Obligation::Trait(TraitRef {
94-
trait_id: to_chalk_trait_id(fn_once_trait),
95-
substitution: substs.clone(),
96-
});
93+
let implements_fn_trait: DomainGoal =
94+
TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
95+
.cast(&Interner);
9796
let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
9897
value: implements_fn_trait.clone(),
9998
environment: trait_env,
@@ -938,22 +937,20 @@ impl<'a> InferenceContext<'a> {
938937
let generic_predicates = self.db.generic_predicates(def.into());
939938
for predicate in generic_predicates.iter() {
940939
let predicate = predicate.clone().subst(parameters);
941-
if let Some(obligation) = Obligation::from_predicate(predicate) {
942-
self.obligations.push(obligation);
943-
}
940+
self.obligations.push(predicate.cast(&Interner));
944941
}
945942
// add obligation for trait implementation, if this is a trait method
946943
match def {
947944
CallableDefId::FunctionId(f) => {
948945
if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
949946
{
950-
// construct a TraitDef
947+
// construct a TraitRef
951948
let substs =
952949
parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
953-
self.obligations.push(Obligation::Trait(TraitRef {
954-
trait_id: to_chalk_trait_id(trait_),
955-
substitution: substs,
956-
}));
950+
self.obligations.push(
951+
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
952+
.cast(&Interner),
953+
);
957954
}
958955
}
959956
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}

crates/hir_ty/src/infer/path.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use std::iter;
44

5+
use chalk_ir::cast::Cast;
56
use hir_def::{
67
path::{Path, PathSegment},
78
resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
@@ -256,10 +257,13 @@ impl<'a> InferenceContext<'a> {
256257
.push(ty.clone())
257258
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
258259
.build();
259-
self.obligations.push(super::Obligation::Trait(TraitRef {
260-
trait_id: to_chalk_trait_id(trait_),
261-
substitution: trait_substs.clone(),
262-
}));
260+
self.obligations.push(
261+
TraitRef {
262+
trait_id: to_chalk_trait_id(trait_),
263+
substitution: trait_substs.clone(),
264+
}
265+
.cast(&Interner),
266+
);
263267
Some(trait_substs)
264268
}
265269
AssocContainerId::ModuleId(_) => None,

crates/hir_ty/src/infer/unify.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::borrow::Cow;
55
use chalk_ir::{FloatTy, IntTy, TyVariableKind};
66
use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
77

8-
use super::{InferenceContext, Obligation};
8+
use super::{DomainGoal, InferenceContext};
99
use crate::{
1010
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar,
1111
Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
@@ -87,14 +87,11 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
8787

8888
pub(crate) fn canonicalize_obligation(
8989
mut self,
90-
obligation: InEnvironment<Obligation>,
91-
) -> Canonicalized<InEnvironment<Obligation>> {
90+
obligation: InEnvironment<DomainGoal>,
91+
) -> Canonicalized<InEnvironment<DomainGoal>> {
9292
let result = match obligation.value {
93-
Obligation::Trait(tr) => {
94-
Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
95-
}
96-
Obligation::AliasEq(alias_eq) => {
97-
Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
93+
DomainGoal::Holds(wc) => {
94+
DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
9895
}
9996
};
10097
self.into_canonicalized(InEnvironment {

crates/hir_ty/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ mod op;
1313
mod lower;
1414
pub(crate) mod infer;
1515
pub(crate) mod utils;
16+
mod chalk_cast;
1617

1718
pub mod display;
1819
pub mod db;
@@ -45,9 +46,11 @@ pub use lower::{
4546
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
4647
TyDefId, TyLoweringContext, ValueTyDefId,
4748
};
48-
pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
49+
pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment};
4950

50-
pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
51+
pub use chalk_ir::{
52+
cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
53+
};
5154

5255
pub use crate::traits::chalk::Interner;
5356

0 commit comments

Comments
 (0)