Revise TypeInfo::ty usage

This commit is contained in:
Lukas Wirth 2021-08-03 17:24:43 +02:00
parent 25ff7171c4
commit 8afa2722b2
18 changed files with 30 additions and 29 deletions

View File

@ -100,11 +100,11 @@ impl TypeInfo {
self.ty
}
pub fn coerced(self) -> Option<Type> {
self.coerced
pub fn has_coercion(&self) -> bool {
self.coerced.is_some()
}
pub fn coerced_or_original(self) -> Type {
pub fn coerced(self) -> Type {
self.coerced.unwrap_or(self.ty)
}
}

View File

@ -555,7 +555,7 @@ fn highlight_method_call(
if let Some(receiver_ty) =
method_call.receiver().and_then(|it| sema.type_of_expr(&it))
{
if !receiver_ty.ty.is_copy(sema.db) {
if !receiver_ty.coerced().is_copy(sema.db) {
h |= HlMod::Consuming
}
}

View File

@ -57,7 +57,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
(ast::Pat::IdentPat(_), Some(expr)) => ctx.sema.type_of_expr(&expr)?,
(pat, _) => ctx.sema.type_of_pat(&pat)?,
}
.coerced_or_original();
.coerced();
// Unresolved or unnameable types can't be annotated
if ty.contains_unknown() || ty.is_closure() {

View File

@ -86,7 +86,7 @@ fn validate_method_call_expr(
let receiver = expr.receiver()?;
let expr = ast::Expr::MethodCallExpr(expr);
let it_type = sema.type_of_expr(&receiver)?.ty;
let it_type = sema.type_of_expr(&receiver)?.coerced();
let module = sema.scope(receiver.syntax()).module()?;
let krate = module.krate();

View File

@ -345,7 +345,7 @@ impl FlowKind {
FlowKind::Return(Some(expr))
| FlowKind::Break(Some(expr))
| FlowKind::TryReturn { expr, .. } => {
ctx.sema.type_of_expr(expr).map(TypeInfo::coerced_or_original)
ctx.sema.type_of_expr(expr).map(TypeInfo::coerced)
}
FlowKind::Try { .. } => {
stdx::never!("try does not have defined expr_ty");

View File

@ -40,7 +40,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
.take_while(|it| it.text_range().contains_range(ctx.frange.range))
.find_map(valid_target_expr)?;
if let Some(ty_info) = ctx.sema.type_of_expr(&to_extract) {
if ty_info.ty.is_unit() {
if ty_info.coerced().is_unit() {
return None;
}
}

View File

@ -223,7 +223,7 @@ impl ExtendedEnum {
}
fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<ExtendedEnum> {
sema.type_of_expr(expr)?.ty.autoderef(sema.db).find_map(|ty| match ty.as_adt() {
sema.type_of_expr(expr)?.coerced().autoderef(sema.db).find_map(|ty| match ty.as_adt() {
Some(Adt::Enum(e)) => Some(ExtendedEnum::Enum(e)),
_ => ty.is_bool().then(|| ExtendedEnum::Bool),
})
@ -234,7 +234,7 @@ fn resolve_tuple_of_enum_def(
expr: &ast::Expr,
) -> Option<Vec<ExtendedEnum>> {
sema.type_of_expr(expr)?
.ty
.coerced()
.tuple_fields(sema.db)
.iter()
.map(|ty| {

View File

@ -331,7 +331,7 @@ fn fn_arg_type(
target_module: hir::Module,
fn_arg: &ast::Expr,
) -> Option<String> {
let ty = ctx.sema.type_of_expr(fn_arg)?.ty;
let ty = ctx.sema.type_of_expr(fn_arg)?.coerced();
if ty.is_unknown() {
return None;
}

View File

@ -18,7 +18,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let (fn_type, tail_expr, builder_edit_pos) = extract_tail(ctx)?;
let module = ctx.sema.scope(tail_expr.syntax()).module()?;
let ty = ctx.sema.type_of_expr(&tail_expr)?.ty;
let ty = ctx.sema.type_of_expr(&tail_expr)?.coerced();
if ty.is_unit() {
return None;
}

View File

@ -190,7 +190,7 @@ pub(crate) fn inline_(
let ty = ctx
.sema
.type_of_expr(&expr)
.and_then(TypeInfo::coerced)
.filter(TypeInfo::has_coercion)
.and_then(|_| param_ty);
body.push_front(
make::let_stmt(pat, ty, Some(expr)).clone_for_update().into(),

View File

@ -80,7 +80,7 @@ fn is_ref_and_impls_iter_method(
};
let wanted_method = if ref_expr.mut_token().is_some() { known::iter_mut } else { known::iter };
let expr_behind_ref = ref_expr.expr()?;
let ty = sema.type_of_expr(&expr_behind_ref)?.ty;
let ty = sema.type_of_expr(&expr_behind_ref)?.coerced();
let scope = sema.scope(iterable.syntax());
let krate = scope.module()?.krate();
let traits_in_scope = scope.traits_in_scope();
@ -110,7 +110,7 @@ fn is_ref_and_impls_iter_method(
/// Whether iterable implements core::Iterator
fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
let it_typ = match sema.type_of_expr(iterable) {
Some(it) => it.ty,
Some(it) => it.coerced(),
None => return false,
};

View File

@ -127,7 +127,7 @@ fn make_else_arm(
let pattern = if let [(Either::Left(pat), _)] = conditionals {
ctx.sema
.type_of_pat(&pat)
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.ty))
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.coerced()))
.zip(Some(pat))
} else {
None
@ -268,7 +268,7 @@ fn binds_name(pat: &ast::Pat) -> bool {
fn is_sad_pat(sema: &hir::Semantics<RootDatabase>, pat: &ast::Pat) -> bool {
sema.type_of_pat(pat)
.and_then(|ty| TryEnum::from_ty(sema, &ty.ty))
.and_then(|ty| TryEnum::from_ty(sema, &ty.coerced()))
.map_or(false, |it| does_pat_match_variant(pat, &it.sad_pattern()))
}

View File

@ -49,8 +49,9 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
target,
|edit| {
let ty = ctx.sema.type_of_expr(&init);
let happy_variant =
ty.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.ty)).map(|it| it.happy_case());
let happy_variant = ty
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.coerced()))
.map(|it| it.happy_case());
let pat = match happy_variant {
None => original_pat,
Some(var_name) => {

View File

@ -270,12 +270,10 @@ fn invert_special_case(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Opti
fn bin_impls_ord(sema: &Semantics<RootDatabase>, bin: &ast::BinExpr) -> bool {
match (
bin.lhs().and_then(|lhs| sema.type_of_expr(&lhs)),
bin.rhs().and_then(|rhs| sema.type_of_expr(&rhs)),
bin.lhs().and_then(|lhs| sema.type_of_expr(&lhs)).map(hir::TypeInfo::coerced),
bin.rhs().and_then(|rhs| sema.type_of_expr(&rhs)).map(hir::TypeInfo::coerced),
) {
(Some(hir::TypeInfo { ty: lhs_ty, .. }), Some(hir::TypeInfo { ty: rhs_ty, .. }))
if lhs_ty == rhs_ty =>
{
(Some(lhs_ty), Some(rhs_ty)) if lhs_ty == rhs_ty => {
let krate = sema.scope(bin.syntax()).module().map(|it| it.krate());
let ord_trait = FamousDefs(sema, krate).core_cmp_Ord();
ord_trait.map_or(false, |ord_trait| {

View File

@ -197,7 +197,7 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<St
match args_parent {
ast::CallExpr(call) => {
let func = call.expr()?;
let func_ty = sema.type_of_expr(&func)?.ty;
let func_ty = sema.type_of_expr(&func)?.coerced();
func_ty.as_callable(sema.db)?
},
ast::MethodCallExpr(method) => sema.resolve_method_call_as_callable(&method)?,
@ -225,7 +225,7 @@ fn var_name_from_pat(pat: &ast::Pat) -> Option<ast::Name> {
}
fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<String> {
let ty = sema.type_of_expr(expr)?.ty;
let ty = sema.type_of_expr(expr)?.coerced();
let ty = ty.remove_ref().unwrap_or(ty);
name_of_type(&ty, sema.db)

View File

@ -118,7 +118,9 @@ fn call_info_impl(
let calling_node = FnCallNode::with_node(&token.parent()?)?;
let callable = match &calling_node {
FnCallNode::CallExpr(call) => sema.type_of_expr(&call.expr()?)?.ty.as_callable(sema.db)?,
FnCallNode::CallExpr(call) => {
sema.type_of_expr(&call.expr()?)?.coerced().as_callable(sema.db)?
}
FnCallNode::MethodCallExpr(call) => sema.resolve_method_call_as_callable(call)?,
};
let active_param = if let Some(arg_list) = calling_node.arg_list() {

View File

@ -543,7 +543,7 @@ impl ImportCandidate {
match sema.resolve_method_call(method_call) {
Some(_) => None,
None => Some(Self::TraitMethod(TraitImportCandidate {
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.ty,
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.coerced(),
assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()),
})),
}

View File

@ -62,7 +62,7 @@ fn missing_record_expr_field_fixes(
};
let def_file_id = def_file_id.original_file(sema.db);
let new_field_type = sema.type_of_expr(&record_expr_field.expr()?)?.ty;
let new_field_type = sema.type_of_expr(&record_expr_field.expr()?)?.coerced();
if new_field_type.is_unknown() {
return None;
}