diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index cac4bce3f906..cc320227f803 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -216,7 +216,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.type_of_expr(expr) } - pub fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, Option)> { + /// Returns true in case a coercion happened. + pub fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, bool)> { self.imp.type_of_expr_with_coercion(expr) } @@ -224,7 +225,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.type_of_pat(pat) } - pub fn type_of_pat_with_coercion(&self, expr: &ast::Pat) -> Option<(Type, Option)> { + pub fn type_of_pat_with_coercion(&self, expr: &ast::Pat) -> Option { self.imp.type_of_pat_with_coercion(expr) } @@ -568,7 +569,7 @@ impl<'db> SemanticsImpl<'db> { self.analyze(expr.syntax()).type_of_expr(self.db, expr) } - fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, Option)> { + fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, bool)> { self.analyze(expr.syntax()).type_of_expr_with_coercion(self.db, expr) } @@ -576,7 +577,7 @@ impl<'db> SemanticsImpl<'db> { self.analyze(pat.syntax()).type_of_pat(self.db, pat) } - fn type_of_pat_with_coercion(&self, pat: &ast::Pat) -> Option<(Type, Option)> { + fn type_of_pat_with_coercion(&self, pat: &ast::Pat) -> Option { self.analyze(pat.syntax()).type_of_pat_with_coercion(self.db, pat) } diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 2ba8284fcbfc..b1792f2ab0d1 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -21,7 +21,7 @@ use hir_def::{ use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; use hir_ty::{ diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, - InferenceResult, Interner, Substitution, Ty, TyExt, TyLoweringContext, + InferenceResult, Interner, Substitution, TyExt, TyLoweringContext, }; use syntax::{ ast::{self, AstNode}, @@ -126,15 +126,15 @@ impl SourceAnalyzer { &self, db: &dyn HirDatabase, expr: &ast::Expr, - ) -> Option<(Type, Option)> { + ) -> Option<(Type, bool)> { let expr_id = self.expr_id(db, expr)?; let infer = self.infer.as_ref()?; - let coerced = infer + let (ty, coerced) = infer .expr_adjustments .get(&expr_id) - .and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target)); - let mk_ty = |ty: &Ty| Type::new_with_resolver(db, &self.resolver, ty.clone()); - mk_ty(&infer[expr_id]).map(|ty| (ty, coerced.and_then(mk_ty))) + .and_then(|adjusts| adjusts.last().map(|adjust| (&adjust.target, true))) + .unwrap_or_else(|| (&infer[expr_id], false)); + Type::new_with_resolver(db, &self.resolver, ty.clone()).zip(Some(coerced)) } pub(crate) fn type_of_pat(&self, db: &dyn HirDatabase, pat: &ast::Pat) -> Option { @@ -147,15 +147,15 @@ impl SourceAnalyzer { &self, db: &dyn HirDatabase, pat: &ast::Pat, - ) -> Option<(Type, Option)> { + ) -> Option { let pat_id = self.pat_id(pat)?; let infer = self.infer.as_ref()?; - let coerced = infer + let ty = infer .pat_adjustments .get(&pat_id) - .and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target)); - let mk_ty = |ty: &Ty| Type::new_with_resolver(db, &self.resolver, ty.clone()); - mk_ty(&infer[pat_id]).map(|ty| (ty, coerced.and_then(mk_ty))) + .and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target)) + .unwrap_or_else(|| &infer[pat_id]); + Type::new_with_resolver(db, &self.resolver, ty.clone()) } pub(crate) fn type_of_self( diff --git a/crates/ide_assists/src/handlers/add_explicit_type.rs b/crates/ide_assists/src/handlers/add_explicit_type.rs index e545454159bf..b1fec65ac06e 100644 --- a/crates/ide_assists/src/handlers/add_explicit_type.rs +++ b/crates/ide_assists/src/handlers/add_explicit_type.rs @@ -55,8 +55,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio } // Infer type - let (ty, coerced) = ctx.sema.type_of_expr_with_coercion(&expr)?; - let ty = coerced.unwrap_or(ty); + let (ty, _) = ctx.sema.type_of_expr_with_coercion(&expr)?; if ty.contains_unknown() || ty.is_closure() { cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred); return None; diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs index 0dcc12d8cb99..0ecf930cb929 100644 --- a/crates/ide_assists/src/handlers/inline_call.rs +++ b/crates/ide_assists/src/handlers/inline_call.rs @@ -190,7 +190,7 @@ pub(crate) fn inline_( let ty = ctx .sema .type_of_expr_with_coercion(&expr) - .map_or(false, |(_, coerced)| coerced.is_some()) + .map_or(false, |(_, coerced)| coerced) .then(|| param_ty) .flatten(); body.push_front(