mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Expose coercions for patterns and expressions in semantics
This commit is contained in:
parent
576e3a4e12
commit
7e6f40b6f1
3 changed files with 31 additions and 7 deletions
|
@ -216,7 +216,7 @@ 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> {
|
||||
pub fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, Option<Type>)> {
|
||||
self.imp.type_of_expr_with_coercion(expr)
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,10 @@ 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<Type>)> {
|
||||
self.imp.type_of_pat_with_coercion(expr)
|
||||
}
|
||||
|
||||
pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
|
||||
self.imp.type_of_self(param)
|
||||
}
|
||||
|
@ -564,7 +568,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> {
|
||||
fn type_of_expr_with_coercion(&self, expr: &ast::Expr) -> Option<(Type, Option<Type>)> {
|
||||
self.analyze(expr.syntax()).type_of_expr_with_coercion(self.db, expr)
|
||||
}
|
||||
|
||||
|
@ -572,6 +576,10 @@ 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<Type>)> {
|
||||
self.analyze(pat.syntax()).type_of_pat_with_coercion(self.db, pat)
|
||||
}
|
||||
|
||||
fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
|
||||
self.analyze(param.syntax()).type_of_self(self.db, param)
|
||||
}
|
||||
|
|
|
@ -126,15 +126,15 @@ impl SourceAnalyzer {
|
|||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
expr: &ast::Expr,
|
||||
) -> Option<Type> {
|
||||
) -> Option<(Type, Option<Type>)> {
|
||||
let expr_id = self.expr_id(db, expr)?;
|
||||
let infer = self.infer.as_ref()?;
|
||||
let ty = infer
|
||||
.expr_adjustments
|
||||
.get(&expr_id)
|
||||
.and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target))
|
||||
.unwrap_or_else(|| &infer[expr_id]);
|
||||
Type::new_with_resolver(db, &self.resolver, ty.clone())
|
||||
.and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target));
|
||||
let mk_ty = |ty: &hir_ty::Ty| Type::new_with_resolver(db, &self.resolver, ty.clone());
|
||||
mk_ty(&infer[expr_id]).map(|it| (it, ty.and_then(mk_ty)))
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_pat(&self, db: &dyn HirDatabase, pat: &ast::Pat) -> Option<Type> {
|
||||
|
@ -143,6 +143,21 @@ impl SourceAnalyzer {
|
|||
Type::new_with_resolver(db, &self.resolver, ty)
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_pat_with_coercion(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
pat: &ast::Pat,
|
||||
) -> Option<(Type, Option<Type>)> {
|
||||
let pat_id = self.pat_id(pat)?;
|
||||
let infer = self.infer.as_ref()?;
|
||||
let ty = infer
|
||||
.pat_adjustments
|
||||
.get(&pat_id)
|
||||
.and_then(|adjusts| adjusts.last().map(|adjust| &adjust.target));
|
||||
let mk_ty = |ty: &hir_ty::Ty| Type::new_with_resolver(db, &self.resolver, ty.clone());
|
||||
mk_ty(&infer[pat_id]).map(|it| (it, ty.and_then(mk_ty)))
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_self(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
|
|
|
@ -55,7 +55,8 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
|
|||
}
|
||||
|
||||
// Infer type
|
||||
let ty = ctx.sema.type_of_expr_with_coercion(&expr)?;
|
||||
let (ty, coerced) = ctx.sema.type_of_expr_with_coercion(&expr)?;
|
||||
let ty = coerced.unwrap_or(ty);
|
||||
if ty.contains_unknown() || ty.is_closure() {
|
||||
cov_mark::hit!(add_explicit_type_not_applicable_if_ty_not_inferred);
|
||||
return None;
|
||||
|
|
Loading…
Reference in a new issue