Skip to content

Commit f822ca2

Browse files
committed
Doc work for hir-analysis::ty module
1 parent 3b17efb commit f822ca2

File tree

10 files changed

+197
-54
lines changed

10 files changed

+197
-54
lines changed

crates/hir-analysis/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ pub struct Jar(
3232
ty::def_analysis::analyze_trait,
3333
ty::def_analysis::analyze_impl_trait,
3434
/// Trait system.
35-
ty::trait_::TraitDef,
36-
ty::trait_::TraitInstId,
37-
ty::trait_::Implementor,
38-
ty::trait_::ingot_trait_env,
39-
ty::trait_::trait_implementors,
35+
ty::trait_def::TraitDef,
36+
ty::trait_def::TraitInstId,
37+
ty::trait_def::Implementor,
38+
ty::trait_def::ingot_trait_env,
39+
ty::trait_def::trait_implementors,
4040
ty::constraint::collect_super_traits,
4141
ty::constraint::collect_trait_constraints,
4242
ty::constraint::collect_adt_constraints,
@@ -48,7 +48,7 @@ pub struct Jar(
4848
ty::constraint::PredicateId,
4949
ty::constraint::PredicateListId,
5050
ty::constraint_solver::is_goal_satisfiable,
51-
ty::constraint_solver::check_ty_sat,
51+
ty::constraint_solver::check_ty_app_sat,
5252
ty::constraint_solver::check_trait_inst_sat,
5353
/// Diagnostic accumulators.
5454
ty::diagnostics::AdtDefDiagAccumulator,

crates/hir-analysis/src/ty/constraint.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//! This module contains the implementation of the constraint collection
2+
//! algorithms.
3+
14
use std::collections::BTreeSet;
25

36
use hir::hir_def::{scope_graph::ScopeId, GenericParam, GenericParamOwner, IngotId, TypeBound};
@@ -11,12 +14,24 @@ use crate::{
1114

1215
use super::{
1316
constraint_solver::{is_goal_satisfiable, GoalSatisfiability},
14-
trait_::{Implementor, TraitDef, TraitInstId},
17+
trait_def::{Implementor, TraitDef, TraitInstId},
1518
trait_lower::lower_trait_ref,
1619
ty_def::{AdtDef, Subst, TyConcrete, TyData, TyId},
1720
ty_lower::{collect_generic_params, lower_hir_ty, GenericParamOwnerId},
1821
};
1922

23+
/// Returns a constraints list which is derived from the given type.
24+
/// # Returns
25+
///
26+
/// ## The first `AssumptionListId`
27+
/// This is a list of assumptions that should be merged to the context where the
28+
/// constraints are solved.
29+
/// This new assumptions are obtained when the given type is a partial applied
30+
/// type, i.e., the assumptions describes the free type variables.
31+
///
32+
/// ## The second `ConstraintListId`
33+
/// This is a list of constraints that should be solved to ensure the type is
34+
/// valid.
2035
#[salsa::tracked]
2136
pub(crate) fn ty_constraints(
2237
db: &dyn HirAnalysisDb,
@@ -102,6 +117,7 @@ pub(crate) fn trait_inst_constraints(
102117
)
103118
}
104119

120+
/// Collect super traits of the given trait.
105121
#[salsa::tracked(return_ref, recovery_fn = recover_collect_super_traits)]
106122
pub(crate) fn collect_super_traits(
107123
db: &dyn HirAnalysisDb,
@@ -141,6 +157,9 @@ pub(crate) fn super_trait_insts(
141157
.collect()
142158
}
143159

160+
/// Collect trait constraints that are specified by the given trait definition.
161+
/// This constraints describes 1. the constraints about self type(i.e.,
162+
/// implementor type), and 2. the generic parameter constraints.
144163
#[salsa::tracked]
145164
pub(crate) fn collect_trait_constraints(
146165
db: &dyn HirAnalysisDb,
@@ -152,6 +171,7 @@ pub(crate) fn collect_trait_constraints(
152171
collector.collect()
153172
}
154173

174+
/// Collect constraints that are specified by the given ADT definition.
155175
#[salsa::tracked]
156176
pub(crate) fn collect_adt_constraints(db: &dyn HirAnalysisDb, adt: AdtDef) -> ConstraintListId {
157177
let Some(owner) = adt.as_generic_param_owner(db) else {
@@ -162,6 +182,8 @@ pub(crate) fn collect_adt_constraints(db: &dyn HirAnalysisDb, adt: AdtDef) -> Co
162182
collector.collect()
163183
}
164184

185+
/// Collect constraints that are specified by the given implementor(i.e., impl
186+
/// trait).
165187
#[salsa::tracked]
166188
pub(crate) fn collect_implementor_constraints(
167189
db: &dyn HirAnalysisDb,
@@ -173,7 +195,7 @@ pub(crate) fn collect_implementor_constraints(
173195
collector.collect()
174196
}
175197

176-
/// Returns a list of assumptions obtained by the given assumptions by looking
198+
/// Returns a list of assumptions derived from the given assumptions by looking
177199
/// up super traits.
178200
#[salsa::tracked(return_ref)]
179201
pub(crate) fn compute_super_assumptions(
@@ -195,20 +217,23 @@ pub(crate) fn compute_super_assumptions(
195217
AssumptionListId::new(db, super_assumptions, ingot)
196218
}
197219

220+
/// Describes a predicate indicating `ty` implements `trait_`.
198221
#[salsa::interned]
199222
pub struct PredicateId {
200223
pub(super) ty: TyId,
201224
pub(super) trait_inst: TraitInstId,
202225
}
203226

204227
impl PredicateId {
228+
/// Applies the given substitution to the predicate.
205229
pub fn apply_subst<S: Subst>(self, db: &dyn HirAnalysisDb, subst: &mut S) -> Self {
206230
let ty = self.ty(db).apply_subst(db, subst);
207231
let trait_ = self.trait_inst(db).apply_subst(db, subst);
208232
Self::new(db, ty, trait_)
209233
}
210234
}
211235

236+
/// The list of predicates.
212237
#[salsa::interned]
213238
pub(crate) struct PredicateListId {
214239
#[return_ref]

crates/hir-analysis/src/ty/constraint_solver.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
1+
//! This module implements a constraint(trait bound) satisfiability solver.
2+
//! The algorithm is based on the paper [Typing Haskell in Haskell](https://web.cecs.pdx.edu/~mpj/thih/),
3+
//! but the algorithm here is slightly extended to support multi parametrized
4+
//! traits.
5+
16
use crate::{ty::constraint::ty_constraints, HirAnalysisDb};
27

38
use super::{
49
constraint::{compute_super_assumptions, AssumptionListId, PredicateId, PredicateListId},
5-
trait_::{TraitEnv, TraitInstId},
10+
trait_def::{TraitEnv, TraitInstId},
611
ty_def::{Subst, TyId},
712
unify::UnificationTable,
813
};
914

1015
type Goal = PredicateId;
1116

17+
/// Checks if the arguments of the given type applications satisfies the
18+
/// constraints under the given assumptions.
19+
///
20+
/// # Panics
21+
/// This function panics if the given type contains free inference keys.
1222
#[salsa::tracked]
13-
pub(crate) fn check_ty_sat(
23+
pub(crate) fn check_ty_app_sat(
1424
db: &dyn HirAnalysisDb,
1525
ty: TyId,
1626
assumptions: AssumptionListId,
@@ -20,7 +30,7 @@ pub(crate) fn check_ty_sat(
2030
let (_, args) = ty.decompose_ty_app(db);
2131

2232
for arg in args {
23-
match check_ty_sat(db, arg, assumptions) {
33+
match check_ty_app_sat(db, arg, assumptions) {
2434
GoalSatisfiability::Satisfied => {}
2535
err => return err,
2636
}
@@ -39,6 +49,8 @@ pub(crate) fn check_ty_sat(
3949
GoalSatisfiability::Satisfied
4050
}
4151

52+
/// Checks if the given argument of the given trait instantiation satisfies the
53+
/// constraints under the given assumptions.
4254
#[salsa::tracked]
4355
pub(crate) fn check_trait_inst_sat(
4456
db: &dyn HirAnalysisDb,
@@ -97,7 +109,7 @@ struct ConstraintSolver<'db> {
97109

98110
impl<'db> ConstraintSolver<'db> {
99111
fn new(db: &'db dyn HirAnalysisDb, goal: Goal, assumptions: AssumptionListId) -> Self {
100-
let ingot = goal.trait_inst(db).ingot(db);
112+
let ingot = assumptions.ingot(db);
101113
let env = TraitEnv::new(db, ingot);
102114

103115
Self {
@@ -108,6 +120,8 @@ impl<'db> ConstraintSolver<'db> {
108120
}
109121
}
110122

123+
/// The main entry point of the constraint solver, whici performs actual
124+
/// solving.
111125
fn solve(self) -> GoalSatisfiability {
112126
let goal_ty = self.goal.ty(self.db);
113127
let goal_trait = self.goal.trait_inst(self.db);
@@ -141,7 +155,7 @@ impl<'db> ConstraintSolver<'db> {
141155
if table.unify(gen_impl.ty(self.db), goal_ty)
142156
&& table.unify(gen_impl.trait_(self.db), goal_trait)
143157
{
144-
let mut subst = ChainedSubst::chain(&mut gen_param_map, &mut table);
158+
let mut subst = SubstComposition::compose(&mut gen_param_map, &mut table);
145159
let constraints = impl_.constraints(self.db);
146160
Some(constraints.apply_subst(self.db, &mut subst))
147161
} else {
@@ -152,6 +166,7 @@ impl<'db> ConstraintSolver<'db> {
152166
return GoalSatisfiability::NotSatisfied(self.goal);
153167
};
154168

169+
// Checks if the all subgoals are satisfied.
155170
for &sub_goal in sub_goals.predicates(self.db) {
156171
match is_goal_satisfiable(self.db, sub_goal, self.assumptions) {
157172
GoalSatisfiability::Satisfied => {}
@@ -175,18 +190,20 @@ impl PredicateListId {
175190
}
176191
}
177192

178-
struct ChainedSubst<'a, 'b, S1, S2> {
193+
/// A substitution that composes multiple substitutions.
194+
struct SubstComposition<'a, 'b, S1, S2> {
179195
first: &'a mut S1,
180196
second: &'b mut S2,
181197
}
182198

183-
impl<'a, 'b, S1, S2> ChainedSubst<'a, 'b, S1, S2> {
184-
fn chain(first: &'a mut S1, second: &'b mut S2) -> Self {
199+
impl<'a, 'b, S1, S2> SubstComposition<'a, 'b, S1, S2> {
200+
/// Creates a new `SubstComposition` from two substitutions.
201+
fn compose(first: &'a mut S1, second: &'b mut S2) -> Self {
185202
Self { first, second }
186203
}
187204
}
188205

189-
impl<'a, 'b, S1, S2> Subst for ChainedSubst<'a, 'b, S1, S2>
206+
impl<'a, 'b, S1, S2> Subst for SubstComposition<'a, 'b, S1, S2>
190207
where
191208
S1: Subst,
192209
S2: Subst,

crates/hir-analysis/src/ty/def_analysis.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//! This module contains analysis for the definition of the type/trait.
2+
//! This module is the only module in `ty` module which is allowed to emit
3+
//! diagnostics.
4+
15
use hir::{
26
hir_def::{
37
scope_graph::ScopeId, FieldDef, ImplTrait, Trait, TraitRefId, TypeAlias, TypeId as HirTyId,
@@ -25,13 +29,23 @@ use super::{
2529
constraint::{collect_super_traits, AssumptionListId, SuperTraitCycle},
2630
constraint_solver::{is_goal_satisfiable, GoalSatisfiability},
2731
diagnostics::{TraitConstraintDiag, TraitLowerDiag, TyDiagCollection, TyLowerDiag},
28-
trait_::{ingot_trait_env, Implementor, TraitDef},
32+
trait_def::{ingot_trait_env, Implementor, TraitDef},
2933
trait_lower::{lower_trait, lower_trait_ref, TraitRefLowerError},
3034
ty_def::{AdtDef, AdtRefId, TyId},
3135
ty_lower::{lower_adt, lower_hir_ty, lower_kind},
3236
visitor::{walk_ty, TyVisitor},
3337
};
3438

39+
/// This function implements analysis for the ADT definition.
40+
/// The analysis includes the following:
41+
/// - Check if the types in the ADT is well-formed.
42+
/// - Check if the trait instantiation appears in the ADT is well-formed.
43+
/// - Check if the field types are fully applied(i.e., these types should have
44+
/// `*` kind).
45+
/// - Check if the types in the ADT satisfies the constraints which is required
46+
/// in type application.
47+
/// - Check if the trait instantiations in the ADT satisfies the constraints.
48+
/// - Check if the recursive types has indirect type wrapper like pointer.
3549
#[salsa::tracked]
3650
pub fn analyze_adt(db: &dyn HirAnalysisDb, adt_ref: AdtRefId) {
3751
let analyzer = DefAnalyzer::for_adt(db, adt_ref);
@@ -46,6 +60,13 @@ pub fn analyze_adt(db: &dyn HirAnalysisDb, adt_ref: AdtRefId) {
4660
}
4761
}
4862

63+
/// This function implements analysis for the trait definition.
64+
/// The analysis includes the following:
65+
/// - Check if the types appear in the trait is well-formed.
66+
/// - Check if the trait instantiation appears in the trait is well-formed.
67+
/// - Check if the types in the trait satisfy the constraints which is required
68+
/// in type application.
69+
/// - Check if the trait instantiations in the trait satisfies the constraints.
4970
#[salsa::tracked]
5071
pub fn analyze_trait(db: &dyn HirAnalysisDb, trait_: Trait) {
5172
let analyzer = DefAnalyzer::for_trait(db, trait_);
@@ -56,6 +77,17 @@ pub fn analyze_trait(db: &dyn HirAnalysisDb, trait_: Trait) {
5677
}
5778
}
5879

80+
/// This function implements analysis for the trait implementation definition.
81+
/// The analysis include the following:
82+
/// - Check if the types appear in the trait impl is well-formed.
83+
/// - Check if the trait instantiation appears in the trait impl is well-formed.
84+
/// - Check if the types in the trait impl satisfy the constraints which is
85+
/// required in type application.
86+
/// - Check if the trait instantiations in the trait impl satisfies the
87+
/// constraints.
88+
/// - Check if the conflict doesn't occur.
89+
/// - Check if the trait or type is included in the ingot which contains the
90+
/// impl trait.
5991
#[salsa::tracked]
6092
pub fn analyze_impl_trait(db: &dyn HirAnalysisDb, impl_trait: ImplTrait) {
6193
let implementor = match analyze_trait_impl_specific_error(db, impl_trait) {
@@ -76,6 +108,15 @@ pub fn analyze_impl_trait(db: &dyn HirAnalysisDb, impl_trait: ImplTrait) {
76108
}
77109
}
78110

111+
/// This function implements analysis for the type alias definition.
112+
/// The analysis includes the following:
113+
/// - Check if the type alias is not recursive.
114+
/// - Check if the type in the type alias is well-formed.
115+
///
116+
/// NOTE: This function doesn't check the satisfiability of the type since our
117+
/// type system treats the alias as kind of macro, meaning type alias doesn't
118+
/// included in the type system. Satisfiability is checked where the type alias
119+
/// is used.
79120
#[salsa::tracked]
80121
pub fn analyze_type_alias(db: &dyn HirAnalysisDb, alias: TypeAlias) {
81122
let Some(hir_ty) = alias.ty(db.as_hir_db()).to_opt() else {
@@ -360,6 +401,10 @@ impl<'db> Visitor for DefAnalyzer<'db> {
360401
self.current_ty = Some((self.def.trait_self_param(self.db), name_span));
361402
walk_super_trait_list(self, ctxt, super_traits);
362403
}
404+
405+
fn visit_func(&mut self, _ctxt: &mut VisitorCtxt<'_, LazyFuncSpan>, _func: hir::hir_def::Func) {
406+
// TODO:
407+
}
363408
}
364409

365410
#[salsa::tracked(recovery_fn = check_recursive_adt_impl)]
@@ -502,7 +547,7 @@ impl DefKind {
502547
}
503548
}
504549

505-
/// This function analyzes
550+
/// This function analyzes the trait impl specific error.
506551
/// 1. If the trait ref is well-formed except for the satisfiability.
507552
/// 2. If implementor type is well-formed except for the satisfiability.
508553
/// 3. If the ingot contains impl trait is the same as the ingot which contains

crates/hir-analysis/src/ty/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use self::{
1313
pub mod constraint_solver;
1414
pub mod def_analysis;
1515
pub mod diagnostics;
16-
pub mod trait_;
16+
pub mod trait_def;
1717
pub mod trait_lower;
1818
pub mod ty_def;
1919
pub mod ty_lower;
@@ -23,6 +23,7 @@ pub(crate) mod constraint;
2323

2424
mod unify;
2525

26+
/// An analysis pass for type definitions.
2627
pub struct TypeDefAnalysisPass<'db> {
2728
db: &'db dyn HirAnalysisDb,
2829
}
@@ -64,6 +65,7 @@ impl<'db> ModuleAnalysisPass for TypeDefAnalysisPass<'db> {
6465
}
6566
}
6667

68+
/// An analysis pass for trait definitions.
6769
pub struct TraitAnalysisPass<'db> {
6870
db: &'db dyn HirAnalysisDb,
6971
}
@@ -89,6 +91,7 @@ impl<'db> ModuleAnalysisPass for TraitAnalysisPass<'db> {
8991
}
9092
}
9193

94+
/// An analysis pass for `ImplTrait'.
9295
pub struct ImplTraitAnalysisPass<'db> {
9396
db: &'db dyn HirAnalysisDb,
9497
}
@@ -115,6 +118,7 @@ impl<'db> ModuleAnalysisPass for ImplTraitAnalysisPass<'db> {
115118
}
116119
}
117120

121+
/// An analysis pass for type aliases.
118122
pub struct TypeAliasAnalysisPass<'db> {
119123
db: &'db dyn HirAnalysisDb,
120124
}

0 commit comments

Comments
 (0)