From 97251b3e28676d051fbed7d7916fb7999fea7c37 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Mon, 3 Feb 2025 12:07:52 +0100 Subject: [PATCH] Check if PatPtr resolves to ExprId --- crates/hir-def/src/expr_store/lower.rs | 22 +++++-------- crates/hir/src/diagnostics.rs | 30 +++++++++--------- crates/hir/src/lib.rs | 2 +- crates/hir/src/source_analyzer.rs | 43 +++++++++++++++----------- 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>>, + pub expr: InFile, pub is_break: bool, pub bad_value_break: bool, } #[derive(Debug)] pub struct TypedHole { - pub expr: InFile>>, + pub expr: InFile, pub expected: Type, } @@ -222,26 +222,26 @@ pub struct NoSuchField { #[derive(Debug)] pub struct PrivateAssocItem { - pub expr_or_pat: InFile>>, + pub expr_or_pat: InFile, pub item: AssocItem, } #[derive(Debug)] pub struct MismatchedTupleStructPatArgCount { - pub expr_or_pat: InFile>>, + pub expr_or_pat: InFile, pub expected: usize, pub found: usize, } #[derive(Debug)] pub struct ExpectedFunction { - pub call: InFile>>, + pub call: InFile, pub found: Type, } #[derive(Debug)] pub struct UnresolvedField { - pub expr: InFile>>, + pub expr: InFile, 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>>, + pub expr: InFile, pub receiver: Type, pub name: Name, pub field_with_same_name: Option, @@ -258,17 +258,17 @@ pub struct UnresolvedMethodCall { #[derive(Debug)] pub struct UnresolvedAssocItem { - pub expr_or_pat: InFile>>, + pub expr_or_pat: InFile, } #[derive(Debug)] pub struct UnresolvedIdent { - pub node: InFile<(AstPtr>, Option)>, + pub node: InFile<(ExprOrPatPtr, Option)>, } #[derive(Debug)] pub struct PrivateField { - pub expr: InFile>>, + pub expr: InFile, pub field: Field, } @@ -281,7 +281,7 @@ pub enum UnsafeLint { #[derive(Debug)] pub struct MissingUnsafe { - pub node: InFile>>, + pub node: InFile, pub lint: UnsafeLint, pub reason: UnsafetyReason, } @@ -322,7 +322,7 @@ pub struct NonExhaustiveLet { #[derive(Debug)] pub struct TypeMismatch { - pub expr_or_pat: InFile>>, + pub expr_or_pat: InFile, pub expected: Type, pub actual: Type, } @@ -396,13 +396,13 @@ pub struct RemoveUnnecessaryElse { #[derive(Debug)] pub struct CastToUnsized { - pub expr: InFile>>, + pub expr: InFile, pub cast_ty: Type, } #[derive(Debug)] pub struct InvalidCast { - pub expr: InFile>>, + pub expr: InFile, 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)> { - 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 { - 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)); }