Skip to content

Commit

Permalink
[WIP] ty_check: path pat
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Nak committed Feb 2, 2024
1 parent 070ab4c commit 800b1fb
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 177 deletions.
41 changes: 38 additions & 3 deletions crates/hir-analysis/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,26 @@ pub struct FuncDefDiagAccumulator(pub(super) TyDiagCollection);
#[salsa::accumulator]
pub struct TypeAliasDefDiagAccumulator(pub(super) TyDiagCollection);
#[salsa::accumulator]
pub struct FuncBodyDiagAccumulator(pub(super) TyDiagCollection);
pub struct FuncBodyDiagAccumulator(pub(super) FuncBodyDiag);

#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::From)]
pub enum FuncBodyDiag {
Ty(TyDiagCollection),
Body(BodyDiag),
}

impl FuncBodyDiag {
pub(super) fn to_voucher(&self) -> Box<dyn hir::diagnostics::DiagnosticVoucher> {
match self {
Self::Ty(diag) => diag.to_voucher(),
Self::Body(diag) => Box::new(diag.clone()) as _,
}
}
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::From)]
pub enum TyDiagCollection {
Ty(TyLowerDiag),
BodyDiag(BodyDiag),
Satisfaction(TraitConstraintDiag),
TraitLower(TraitLowerDiag),
Impl(ImplDiag),
Expand All @@ -45,7 +59,6 @@ impl TyDiagCollection {
pub(super) fn to_voucher(&self) -> Box<dyn hir::diagnostics::DiagnosticVoucher> {
match self.clone() {
TyDiagCollection::Ty(diag) => Box::new(diag) as _,
TyDiagCollection::BodyDiag(diag) => Box::new(diag) as _,
TyDiagCollection::Satisfaction(diag) => Box::new(diag) as _,
TyDiagCollection::TraitLower(diag) => Box::new(diag) as _,
TyDiagCollection::Impl(diag) => Box::new(diag) as _,
Expand Down Expand Up @@ -527,6 +540,10 @@ pub enum BodyDiag {
TypeMismatch(DynLazySpan, String, String),
InfiniteOccurrence(DynLazySpan),
DuplicatedRestPat(DynLazySpan),
InvalidPathDomainInPat {
primary: DynLazySpan,
resolved: Option<DynLazySpan>,
},
}

impl BodyDiag {
Expand All @@ -546,6 +563,7 @@ impl BodyDiag {
Self::TypeMismatch(_, _, _) => 0,
Self::InfiniteOccurrence(_) => 1,
Self::DuplicatedRestPat(_) => 2,
Self::InvalidPathDomainInPat { .. } => 3,
}
}

Expand All @@ -554,6 +572,7 @@ impl BodyDiag {
Self::TypeMismatch(_, _, _) => "type mismatch".to_string(),
Self::InfiniteOccurrence(_) => "infinite sized type found".to_string(),
Self::DuplicatedRestPat(_) => "duplicated `..` found".to_string(),
Self::InvalidPathDomainInPat { .. } => "invalid item is given here".to_string(),
}
}

Expand All @@ -576,6 +595,22 @@ impl BodyDiag {
"`..` can be used only once".to_string(),
span.resolve(db),
)],

Self::InvalidPathDomainInPat { primary, resolved } => {
let mut diag = vec![SubDiagnostic::new(
LabelStyle::Primary,
"expected type or enum variant here".to_string(),
primary.resolve(db),
)];
if let Some(resolved) = resolved {
diag.push(SubDiagnostic::new(
LabelStyle::Secondary,
"this item given".to_string(),
resolved.resolve(db),
))
}
diag
}
}
}

Expand Down
53 changes: 43 additions & 10 deletions crates/hir-analysis/src/ty/ty_check/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ use crate::{
ty::{
ty_def::{InvalidCause, TyId},
ty_lower::lower_hir_ty,
unify::UnificationTable,
},
HirAnalysisDb,
};

pub(super) struct ThCheckEnv<'db> {
pub(super) struct TyCheckEnv<'db> {
db: &'db dyn HirAnalysisDb,
body: Body,

Expand All @@ -24,7 +25,7 @@ pub(super) struct ThCheckEnv<'db> {
var_env: Vec<BlockEnv>,
}

impl<'db> ThCheckEnv<'db> {
impl<'db> TyCheckEnv<'db> {
pub(super) fn new_with_func(db: &'db dyn HirAnalysisDb, func: Func) -> Result<Self, ()> {
let hir_db = db.as_hir_db();
let Some(body) = func.body(hir_db) else {
Expand All @@ -45,7 +46,7 @@ impl<'db> ThCheckEnv<'db> {
return Err(());
};

for param in params.data(hir_db) {
for (i, param) in params.data(hir_db).iter().enumerate() {
let Some(name) = param.name() else {
continue;
};
Expand All @@ -58,8 +59,9 @@ impl<'db> ThCheckEnv<'db> {
if ty.is_star_kind(db) {
ty = TyId::invalid(db, InvalidCause::Other);
}
let var = VarKind::Param(i, ty);

env.register_var(name, ty);
env.var_env.last_mut().unwrap().register_var(name, var);
}

Ok(env)
Expand Down Expand Up @@ -94,12 +96,21 @@ impl<'db> ThCheckEnv<'db> {
self.pat_ty.insert(pat, ty);
}

pub(super) fn register_var(&mut self, name: IdentId, ty: TyId) {
pub(super) fn register_var(&mut self, name: IdentId, pat: PatId) {
let var_env = self.var_env.last_mut().unwrap();
var_env.vars.insert(name, ty);
let var = VarKind::Local(pat);
var_env.register_var(name, var);
}

pub(super) fn finish(self) -> TypedBody {
pub(super) fn finish(mut self, table: &mut UnificationTable) -> TypedBody {
self.expr_ty
.values_mut()
.for_each(|ty| *ty = ty.apply_subst(self.db, table));

self.pat_ty
.values_mut()
.for_each(|ty| *ty = ty.apply_subst(self.db, table));

TypedBody {
body: Some(self.body),
pat_ty: self.pat_ty,
Expand All @@ -114,11 +125,19 @@ impl<'db> ThCheckEnv<'db> {
pub(super) fn stmt_data(&self, stmt: StmtId) -> &'db Partial<Stmt> {
stmt.data(self.db.as_hir_db(), self.body)
}

pub(super) fn scope(&self) -> ScopeId {
self.var_env.last().unwrap().scope
}

pub(super) fn iter_block_env(&self) -> impl Iterator<Item = &BlockEnv> {
self.var_env.iter().rev()
}
}

struct BlockEnv {
scope: ScopeId,
vars: FxHashMap<IdentId, TyId>,
pub(super) struct BlockEnv {
pub(super) scope: ScopeId,
pub(super) vars: FxHashMap<IdentId, VarKind>,
}

impl BlockEnv {
Expand All @@ -128,4 +147,18 @@ impl BlockEnv {
vars: FxHashMap::default(),
}
}

fn register_var(&mut self, name: IdentId, var: VarKind) {
self.vars.insert(name, var);
}

pub(super) fn lookup_var(&self, name: IdentId) -> Option<VarKind> {
self.vars.get(&name).copied()
}
}

#[derive(Clone, Copy)]
pub(super) enum VarKind {
Local(PatId),
Param(usize, TyId),
}
Loading

0 comments on commit 800b1fb

Please sign in to comment.