Skip to content

Commit

Permalink
Record diverging match arms in InferenceResult
Browse files Browse the repository at this point in the history
  • Loading branch information
unexge committed Oct 29, 2022
1 parent ba28e19 commit 319611b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ pub struct InferenceResult {
assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
pub diagnostics: Vec<InferenceDiagnostic>,
pub type_of_expr: ArenaMap<ExprId, Ty>,
/// For each match expr, record diverging arm's expr.
pub diverging_arms: FxHashMap<ExprId, Vec<ExprId>>,
/// For each pattern record the type it resolves to.
///
/// **Note**: When a pattern type is resolved it may still contain
Expand Down
5 changes: 5 additions & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ impl<'a> InferenceContext<'a> {

let matchee_diverges = self.diverges;
let mut all_arms_diverge = Diverges::Always;
let mut diverging_arms = Vec::new();

for arm in arms.iter() {
self.diverges = Diverges::Maybe;
Expand All @@ -387,11 +388,15 @@ impl<'a> InferenceContext<'a> {
}

let arm_ty = self.infer_expr_inner(arm.expr, &expected);
if self.diverges.is_always() {
diverging_arms.push(arm.expr);
}
all_arms_diverge &= self.diverges;
coerce.coerce(self, Some(arm.expr), &arm_ty);
}

self.diverges = matchee_diverges | all_arms_diverge;
self.result.diverging_arms.insert(tgt_expr, diverging_arms);

coerce.complete()
}
Expand Down
8 changes: 8 additions & 0 deletions crates/hir/src/semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
self.imp.is_unsafe_ident_pat(ident_pat)
}

pub fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option<bool> {
self.imp.is_diverging_match_arm(match_arm)
}
}

impl<'db> SemanticsImpl<'db> {
Expand Down Expand Up @@ -1421,6 +1425,10 @@ impl<'db> SemanticsImpl<'db> {
.map(|ty| ty.original.is_packed(self.db))
.unwrap_or(false)
}

fn is_diverging_match_arm(&self, match_arm: &ast::MatchArm) -> Option<bool> {
self.analyze(match_arm.syntax())?.is_diverging_match_arm(self.db, match_arm)
}
}

fn macro_call_to_macro_id(
Expand Down
15 changes: 15 additions & 0 deletions crates/hir/src/source_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,21 @@ impl SourceAnalyzer {
false
}

pub(crate) fn is_diverging_match_arm(
&self,
db: &dyn HirDatabase,
match_arm: &ast::MatchArm,
) -> Option<bool> {
let infer = self.infer.as_ref()?;
let match_expr = match_arm.syntax().ancestors().find_map(ast::MatchExpr::cast)?;
let match_id = self.expr_id(db, &match_expr.into())?;
let diverging_arms = infer.diverging_arms.get(&match_id)?;
let match_arm_expr = match_arm.expr()?;
let match_arm_expr_id = self.expr_id(db, &match_arm_expr)?;

Some(diverging_arms.contains(&match_arm_expr_id))
}

fn resolve_impl_method_or_trait_def(
&self,
db: &dyn HirDatabase,
Expand Down

0 comments on commit 319611b

Please sign in to comment.