Skip to content

Commit

Permalink
ty_check: path tuple pat
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Nak committed Feb 13, 2024
1 parent 2c555bc commit 8c6f57e
Show file tree
Hide file tree
Showing 17 changed files with 724 additions and 123 deletions.
5 changes: 4 additions & 1 deletion crates/hir-analysis/src/name_resolution/path_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use super::{
},
NameDomain, NameQuery,
};
use crate::{name_resolution::QueryDirective, HirAnalysisDb};
use crate::{
name_resolution::{resolve_segments_early, QueryDirective},
HirAnalysisDb,
};

/// The result of early path resolution.
/// There are two kinds of early resolution results:
Expand Down
94 changes: 85 additions & 9 deletions crates/hir-analysis/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::{
ty_check::ResolvedPathData,
ty_def::{Kind, TyId},
};
use crate::HirAnalysisDb;
use crate::{name_resolution::diagnostics::NameResDiag, HirAnalysisDb};

#[salsa::accumulator]
pub struct AdtDefDiagAccumulator(pub(super) TyDiagCollection);
Expand All @@ -37,13 +37,15 @@ pub struct FuncBodyDiagAccumulator(pub(super) FuncBodyDiag);
pub enum FuncBodyDiag {
Ty(TyDiagCollection),
Body(BodyDiag),
NameRes(NameResDiag),
}

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 _,
Self::NameRes(diag) => Box::new(diag.clone()) as _,
}
}
}
Expand Down Expand Up @@ -547,9 +549,19 @@ pub enum BodyDiag {
},
UnitVariantExpectedInPat {
primary: DynLazySpan,
kind: &'static str,
pat_kind: &'static str,
hint: Option<String>,
},
TupleVariantExpectedInPat {
primary: DynLazySpan,
pat_kind: Option<&'static str>,
hint: Option<String>,
},
MismatchedFieldCount {
primary: DynLazySpan,
expected: usize,
given: usize,
},
}

impl BodyDiag {
Expand All @@ -569,11 +581,29 @@ impl BodyDiag {
primary: DynLazySpan,
data: ResolvedPathData,
) -> Self {
let kind = data.data_kind(db);
let pat_kind = data.data_kind(db);
let hint = data.initializer_hint(db);
Self::UnitVariantExpectedInPat {
primary,
kind,
pat_kind,
hint,
}
}

pub(super) fn tuple_variant_expected_in_pat(
db: &dyn HirAnalysisDb,
primary: DynLazySpan,
data: Option<ResolvedPathData>,
) -> Self {
let (pat_kind, hint) = if let Some(data) = data {
(Some(data.data_kind(db)), data.initializer_hint(db))
} else {
(None, None)
};

Self::TupleVariantExpectedInPat {
primary,
pat_kind,
hint,
}
}
Expand All @@ -585,6 +615,8 @@ impl BodyDiag {
Self::DuplicatedRestPat(_) => 2,
Self::InvalidPathDomainInPat { .. } => 3,
Self::UnitVariantExpectedInPat { .. } => 4,
Self::TupleVariantExpectedInPat { .. } => 5,
Self::MismatchedFieldCount { .. } => 6,
}
}

Expand All @@ -595,6 +627,8 @@ impl BodyDiag {
Self::DuplicatedRestPat(_) => "duplicated `..` found".to_string(),
Self::InvalidPathDomainInPat { .. } => "invalid item is given here".to_string(),
Self::UnitVariantExpectedInPat { .. } => "unit variant is expected here".to_string(),
Self::TupleVariantExpectedInPat { .. } => "tuple variant is expected here".to_string(),
Self::MismatchedFieldCount { .. } => "field count mismatch".to_string(),
}
}

Expand Down Expand Up @@ -636,22 +670,64 @@ impl BodyDiag {

Self::UnitVariantExpectedInPat {
primary,
kind,
pat_kind,
hint,
} => {
let mut diags = vec![SubDiagnostic::new(
let mut diag = vec![SubDiagnostic::new(
LabelStyle::Primary,
format!("expected unit variant here, but found {}", kind,),
format!("expected unit variant here, but found {}", pat_kind,),
primary.resolve(db),
)];
if let Some(hint) = hint {
diags.push(SubDiagnostic::new(
diag.push(SubDiagnostic::new(
LabelStyle::Secondary,
format!("Use {} instead", hint),
primary.resolve(db),
))
}
diags
diag
}

Self::TupleVariantExpectedInPat {
primary,
pat_kind,
hint,
} => {
let mut diag = if let Some(pat_kind) = pat_kind {
vec![SubDiagnostic::new(
LabelStyle::Primary,
format!("expected tuple variant here, but found {}", pat_kind,),
primary.resolve(db),
)]
} else {
vec![SubDiagnostic::new(
LabelStyle::Primary,
"expected tuple variant here".to_string(),
primary.resolve(db),
)]
};

if let Some(hint) = hint {
diag.push(SubDiagnostic::new(
LabelStyle::Secondary,
format!("Use {} instead", hint),
primary.resolve(db),
))
}

diag
}

Self::MismatchedFieldCount {
primary,
expected,
given,
} => {
vec![SubDiagnostic::new(
LabelStyle::Primary,
format!("expected {} fields here, but {} given", expected, given,),
primary.resolve(db),
)]
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions crates/hir-analysis/src/ty/ty_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ impl<'db> TyChecker<'db> {
}
}

fn body(&self) -> Body {
self.env.body()
}

fn lit_ty(&mut self, lit: &LitKind) -> TyId {
match lit {
LitKind::Bool(_) => TyId::bool(self.db),
Expand Down Expand Up @@ -103,6 +107,10 @@ impl<'db> TyChecker<'db> {
self.table.new_var(TyVarUniverse::General, &Kind::Star)
}

fn fresh_tys_n(&mut self, n: usize) -> Vec<TyId> {
(0..n).map(|_| self.fresh_ty()).collect()
}

fn unify_ty<T>(&mut self, t: T, actual: TyId, expected: TyId) -> TyId
where
T: Into<Typeable>,
Expand Down Expand Up @@ -274,4 +282,38 @@ impl ResolvedPathData {
}
}
}

fn is_tuple_variant(&self, db: &dyn HirAnalysisDb) -> bool {
match self {
Self::Adt(_, _) => false,
Self::Variant(enum_, idx, _) => {
let hir_db = db.as_hir_db();
matches!(
enum_.variants(hir_db).data(hir_db)[*idx].kind,
HirVariantKind::Tuple(_)
)
}
}
}

fn field_tys(&self, db: &dyn HirAnalysisDb) -> Vec<TyId> {
let (adt, idx) = match self {
Self::Adt(adt, _) => {
if matches!(
adt.adt_ref(db).data(db),
AdtRef::Struct(_) | AdtRef::Contract(_)
) {
(*adt, 0)
} else {
return vec![];
}
}
Self::Variant(enum_, idx, _) => {
let adt = lower_adt(db, AdtRefId::from_enum(db, *enum_));
(adt, *idx)
}
};

adt.fields(db)[idx].iter_types(db).collect()
}
}
Loading

0 comments on commit 8c6f57e

Please sign in to comment.