Unnamed repository; edit this file 'description' to name the repository.
Check if PatPtr resolves to ExprId
Ali Bektas 2025-02-09
parent 76b93c0 · commit 97251b3
-rw-r--r--crates/hir-def/src/expr_store/lower.rs22
-rw-r--r--crates/hir/src/diagnostics.rs30
-rw-r--r--crates/hir/src/lib.rs2
-rw-r--r--crates/hir/src/source_analyzer.rs43
4 files changed, 49 insertions, 48 deletions
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs
index 95dd1e53ae..6e505a6b11 100644
--- a/crates/hir-def/src/expr_store/lower.rs
+++ b/crates/hir-def/src/expr_store/lower.rs
@@ -1798,23 +1798,17 @@ impl ExprCollector<'_> {
Expr::Literal(pat_literal_to_hir(it)?.0),
ptr,
)),
- ast::Pat::IdentPat(ident) => {
- if ident.is_simple_ident() {
- return ident
- .name()
- .map(|name| name.as_name())
- .map(Path::from)
- .map(|path| {
- self.alloc_expr_from_pat(Expr::Path(path), ptr)
- });
- }
-
- None
- }
+ ast::Pat::IdentPat(ident) if ident.is_simple_ident() => ident
+ .name()
+ .map(|name| name.as_name())
+ .map(Path::from)
+ .map(|path| self.alloc_expr_from_pat(Expr::Path(path), ptr)),
ast::Pat::PathPat(p) => p
.path()
.and_then(|path| self.parse_path(path))
.map(|parsed| self.alloc_expr_from_pat(Expr::Path(parsed), ptr)),
+ // We only need to handle literal, ident (if bare) and path patterns here,
+ // as any other pattern as a range pattern operand is semantically invalid.
_ => None,
}
})
@@ -2545,7 +2539,7 @@ impl ExprCollector<'_> {
fn alloc_expr_from_pat(&mut self, expr: Expr, ptr: PatPtr) -> ExprId {
let src = self.expander.in_file(ptr);
- let id = self.body.exprs.alloc(expr);
+ let id = self.store.exprs.alloc(expr);
self.source_map.pat_map.insert(src, id.into());
self.source_map.expr_map_back.insert(id, src.map(AstPtr::wrap_right));
id
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 9a5e50af07..5876529df9 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -6,7 +6,7 @@
use cfg::{CfgExpr, CfgOptions};
use either::Either;
use hir_def::{
- body::ExprOrPatPtr,
+ expr_store::ExprOrPatPtr,
hir::ExprOrPatId,
path::{hir_segment_to_ast_segment, ModPath},
type_ref::TypesSourceMap,
@@ -116,14 +116,14 @@ diagnostics![
#[derive(Debug)]
pub struct BreakOutsideOfLoop {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub is_break: bool,
pub bad_value_break: bool,
}
#[derive(Debug)]
pub struct TypedHole {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub expected: Type,
}
@@ -222,26 +222,26 @@ pub struct NoSuchField {
#[derive(Debug)]
pub struct PrivateAssocItem {
- pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr_or_pat: InFile<ExprOrPatPtr>,
pub item: AssocItem,
}
#[derive(Debug)]
pub struct MismatchedTupleStructPatArgCount {
- pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr_or_pat: InFile<ExprOrPatPtr>,
pub expected: usize,
pub found: usize,
}
#[derive(Debug)]
pub struct ExpectedFunction {
- pub call: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub call: InFile<ExprOrPatPtr>,
pub found: Type,
}
#[derive(Debug)]
pub struct UnresolvedField {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub receiver: Type,
pub name: Name,
pub method_with_same_name_exists: bool,
@@ -249,7 +249,7 @@ pub struct UnresolvedField {
#[derive(Debug)]
pub struct UnresolvedMethodCall {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub receiver: Type,
pub name: Name,
pub field_with_same_name: Option<Type>,
@@ -258,17 +258,17 @@ pub struct UnresolvedMethodCall {
#[derive(Debug)]
pub struct UnresolvedAssocItem {
- pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr_or_pat: InFile<ExprOrPatPtr>,
}
#[derive(Debug)]
pub struct UnresolvedIdent {
- pub node: InFile<(AstPtr<Either<ast::Expr, ast::Pat>>, Option<TextRange>)>,
+ pub node: InFile<(ExprOrPatPtr, Option<TextRange>)>,
}
#[derive(Debug)]
pub struct PrivateField {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub field: Field,
}
@@ -281,7 +281,7 @@ pub enum UnsafeLint {
#[derive(Debug)]
pub struct MissingUnsafe {
- pub node: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub node: InFile<ExprOrPatPtr>,
pub lint: UnsafeLint,
pub reason: UnsafetyReason,
}
@@ -322,7 +322,7 @@ pub struct NonExhaustiveLet {
#[derive(Debug)]
pub struct TypeMismatch {
- pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr_or_pat: InFile<ExprOrPatPtr>,
pub expected: Type,
pub actual: Type,
}
@@ -396,13 +396,13 @@ pub struct RemoveUnnecessaryElse {
#[derive(Debug)]
pub struct CastToUnsized {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub cast_ty: Type,
}
#[derive(Debug)]
pub struct InvalidCast {
- pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
+ pub expr: InFile<ExprOrPatPtr>,
pub error: CastError,
pub expr_ty: Type,
pub cast_ty: Type,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 26b2819913..8b8203acb1 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2003,7 +2003,7 @@ impl DefWithBody {
match source_map.expr_syntax(node) {
Ok(node) => acc.push(
MissingUnsafe {
- node: node.map(|it| it.wrap_left()),
+ node,
lint: UnsafeLint::DeprecatedSafe2024,
reason: UnsafetyReason::UnsafeFnCall,
}
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 8a1e4fba6b..9e7f2c1948 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -210,13 +210,20 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
pat: &ast::Pat,
) -> Option<(Type, Option<Type>)> {
- let pat_id = self.pat_id(pat)?;
+ let expr_or_pat_id = self.pat_id(pat)?;
let infer = self.infer.as_ref()?;
- let coerced = infer
- .pat_adjustments
- .get(&pat_id.as_pat()?)
- .and_then(|adjusts| adjusts.last().cloned());
- let ty = infer[pat_id].clone();
+ let coerced = match expr_or_pat_id {
+ ExprOrPatId::ExprId(idx) => infer
+ .expr_adjustments
+ .get(&idx)
+ .and_then(|adjusts| adjusts.last().cloned())
+ .map(|adjust| adjust.target),
+ ExprOrPatId::PatId(idx) => {
+ infer.pat_adjustments.get(&idx).and_then(|adjusts| adjusts.last().cloned())
+ }
+ };
+
+ let ty = infer[expr_or_pat_id].clone();
let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
Some((mk_ty(ty), coerced.map(mk_ty)))
}
@@ -684,19 +691,18 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
pat: &ast::IdentPat,
) -> Option<ModuleDef> {
- let pat_id = self.pat_id(&pat.clone().into())?;
+ let expr_or_pat_id = self.pat_id(&pat.clone().into())?;
let body = self.body()?;
- let path = if pat_id.is_pat() {
- match &body[pat_id.as_pat()?] {
- Pat::Path(path) => path,
- _ => return None,
- }
- } else {
- match &body[pat_id.as_expr()?] {
+ let path = match expr_or_pat_id {
+ ExprOrPatId::ExprId(idx) => match &body[idx] {
Expr::Path(path) => path,
_ => return None,
- }
+ },
+ ExprOrPatId::PatId(idx) => match &body[idx] {
+ Pat::Path(path) => path,
+ _ => return None,
+ },
};
let res = resolve_hir_path(db, &self.resolver, path, HygieneId::ROOT, TypesMap::EMPTY)?;
@@ -793,8 +799,9 @@ impl SourceAnalyzer {
}
prefer_value_ns = true;
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
- let pat_id = self.pat_id(&path_pat.into())?;
- if let Some((assoc, subs)) = infer.assoc_resolutions_for_pat(pat_id.as_pat()?) {
+ let expr_or_pat_id = self.pat_id(&path_pat.into())?;
+ if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr_or_pat(expr_or_pat_id)
+ {
let (assoc, subst) = match assoc {
AssocItemId::ConstId(const_id) => {
let (konst, subst) =
@@ -818,7 +825,7 @@ impl SourceAnalyzer {
return Some((PathResolution::Def(AssocItem::from(assoc).into()), Some(subst)));
}
if let Some(VariantId::EnumVariantId(variant)) =
- infer.variant_resolution_for_pat(pat_id.as_pat()?)
+ infer.variant_resolution_for_expr_or_pat(expr_or_pat_id)
{
return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None));
}