mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Give TypeInfo fields and methods more appropriate names
This commit is contained in:
parent
8afa2722b2
commit
b96f1adf5c
30 changed files with 76 additions and 74 deletions
|
@ -90,22 +90,23 @@ impl PathResolution {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TypeInfo {
|
pub struct TypeInfo {
|
||||||
/// The original type of the expression or pattern.
|
/// The original type of the expression or pattern.
|
||||||
pub ty: Type,
|
pub original: Type,
|
||||||
/// The coerced type, if a coercion happened.
|
/// The adjusted type, if an adjustment happened.
|
||||||
pub coerced: Option<Type>,
|
pub adjusted: Option<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeInfo {
|
impl TypeInfo {
|
||||||
pub fn ty(self) -> Type {
|
pub fn original(self) -> Type {
|
||||||
self.ty
|
self.original
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_coercion(&self) -> bool {
|
pub fn has_adjustment(&self) -> bool {
|
||||||
self.coerced.is_some()
|
self.adjusted.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn coerced(self) -> Type {
|
/// The adjusted type, or the original in case no adjustments occurred.
|
||||||
self.coerced.unwrap_or(self.ty)
|
pub fn adjusted(self) -> Type {
|
||||||
|
self.adjusted.unwrap_or(self.original)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,13 +582,13 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
|
fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
|
||||||
self.analyze(expr.syntax())
|
self.analyze(expr.syntax())
|
||||||
.type_of_expr(self.db, expr)
|
.type_of_expr(self.db, expr)
|
||||||
.map(|(ty, coerced)| TypeInfo { ty, coerced })
|
.map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_of_pat(&self, pat: &ast::Pat) -> Option<TypeInfo> {
|
fn type_of_pat(&self, pat: &ast::Pat) -> Option<TypeInfo> {
|
||||||
self.analyze(pat.syntax())
|
self.analyze(pat.syntax())
|
||||||
.type_of_pat(self.db, pat)
|
.type_of_pat(self.db, pat)
|
||||||
.map(|(ty, coerced)| TypeInfo { ty, coerced })
|
.map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
|
fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
|
||||||
|
@ -766,7 +767,7 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
ast::Expr::FieldExpr(field_expr) => field_expr,
|
ast::Expr::FieldExpr(field_expr) => field_expr,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let ty = self.type_of_expr(&field_expr.expr()?)?.ty;
|
let ty = self.type_of_expr(&field_expr.expr()?)?.original;
|
||||||
if !ty.is_packed(self.db) {
|
if !ty.is_packed(self.db) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -793,7 +794,7 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
self.type_of_expr(&expr)
|
self.type_of_expr(&expr)
|
||||||
})
|
})
|
||||||
// Binding a reference to a packed type is possibly unsafe.
|
// Binding a reference to a packed type is possibly unsafe.
|
||||||
.map(|ty| ty.ty.is_packed(self.db))
|
.map(|ty| ty.original.is_packed(self.db))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
|
||||||
// FIXME This needs layout computation to be correct. It will highlight
|
// FIXME This needs layout computation to be correct. It will highlight
|
||||||
|
@ -839,7 +840,7 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Binding a reference to a packed type is possibly unsafe.
|
// Binding a reference to a packed type is possibly unsafe.
|
||||||
.map(|ty| ty.ty.is_packed(self.db))
|
.map(|ty| ty.original.is_packed(self.db))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
|
||||||
let name_ref = call_node.name_ref()?;
|
let name_ref = call_node.name_ref()?;
|
||||||
let func_target = match call_node {
|
let func_target = match call_node {
|
||||||
FnCallNode::CallExpr(expr) => {
|
FnCallNode::CallExpr(expr) => {
|
||||||
let callable = sema.type_of_expr(&expr.expr()?)?.ty.as_callable(db)?;
|
let callable = sema.type_of_expr(&expr.expr()?)?.original.as_callable(db)?;
|
||||||
match callable.kind() {
|
match callable.kind() {
|
||||||
hir::CallableKind::Function(it) => it.try_to_nav(db),
|
hir::CallableKind::Function(it) => it.try_to_nav(db),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -32,8 +32,8 @@ pub(crate) fn goto_type_definition(
|
||||||
let (ty, node) = sema.token_ancestors_with_macros(token).find_map(|node| {
|
let (ty, node) = sema.token_ancestors_with_macros(token).find_map(|node| {
|
||||||
let ty = match_ast! {
|
let ty = match_ast! {
|
||||||
match node {
|
match node {
|
||||||
ast::Expr(it) => sema.type_of_expr(&it)?.ty,
|
ast::Expr(it) => sema.type_of_expr(&it)?.original,
|
||||||
ast::Pat(it) => sema.type_of_pat(&it)?.ty,
|
ast::Pat(it) => sema.type_of_pat(&it)?.original,
|
||||||
ast::SelfParam(it) => sema.type_of_self(&it)?,
|
ast::SelfParam(it) => sema.type_of_self(&it)?,
|
||||||
ast::Type(it) => sema.resolve_type(&it)?,
|
ast::Type(it) => sema.resolve_type(&it)?,
|
||||||
ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?,
|
ast::RecordField(it) => sema.to_def(&it).map(|d| d.ty(db.upcast()))?,
|
||||||
|
|
|
@ -123,7 +123,7 @@ fn highlight_exit_points(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroCall(_) => {
|
ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroCall(_) => {
|
||||||
if sema.type_of_expr(&expr).map_or(false, |ty| ty.ty.is_never()) {
|
if sema.type_of_expr(&expr).map_or(false, |ty| ty.original.is_never()) {
|
||||||
highlights
|
highlights
|
||||||
.push(HighlightedRange { access: None, range: expr.syntax().text_range() });
|
.push(HighlightedRange { access: None, range: expr.syntax().text_range() });
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,29 +225,29 @@ fn hover_type_info(
|
||||||
config: &HoverConfig,
|
config: &HoverConfig,
|
||||||
expr_or_pat: &Either<ast::Expr, ast::Pat>,
|
expr_or_pat: &Either<ast::Expr, ast::Pat>,
|
||||||
) -> Option<HoverResult> {
|
) -> Option<HoverResult> {
|
||||||
let TypeInfo { ty, coerced } = match expr_or_pat {
|
let TypeInfo { original, adjusted } = match expr_or_pat {
|
||||||
Either::Left(expr) => sema.type_of_expr(expr)?,
|
Either::Left(expr) => sema.type_of_expr(expr)?,
|
||||||
Either::Right(pat) => sema.type_of_pat(pat)?,
|
Either::Right(pat) => sema.type_of_pat(pat)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = HoverResult::default();
|
let mut res = HoverResult::default();
|
||||||
res.markup = if let Some(coerced_ty) = coerced {
|
res.markup = if let Some(adjusted_ty) = adjusted {
|
||||||
let uncoerced = ty.display(sema.db).to_string();
|
let original = original.display(sema.db).to_string();
|
||||||
let coerced = coerced_ty.display(sema.db).to_string();
|
let adjusted = adjusted_ty.display(sema.db).to_string();
|
||||||
format!(
|
format!(
|
||||||
"```text\nType: {:>upad$}\nCoerced to: {:>cpad$}\n```\n",
|
"```text\nType: {:>apad$}\nCoerced to: {:>opad$}\n```\n",
|
||||||
uncoerced = uncoerced,
|
uncoerced = original,
|
||||||
coerced = coerced,
|
coerced = adjusted,
|
||||||
// 6 base padding for static text prefix of each line
|
// 6 base padding for static text prefix of each line
|
||||||
upad = 6 + coerced.len().max(uncoerced.len()),
|
apad = 6 + adjusted.len().max(original.len()),
|
||||||
cpad = uncoerced.len(),
|
opad = original.len(),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
if config.markdown() {
|
if config.markdown() {
|
||||||
Markup::fenced_block(&ty.display(sema.db))
|
Markup::fenced_block(&original.display(sema.db))
|
||||||
} else {
|
} else {
|
||||||
ty.display(sema.db).to_string().into()
|
original.display(sema.db).to_string().into()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(res)
|
Some(res)
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn get_chaining_hints(
|
||||||
next_next = tokens.next()?.kind();
|
next_next = tokens.next()?.kind();
|
||||||
}
|
}
|
||||||
if next_next == T![.] {
|
if next_next == T![.] {
|
||||||
let ty = sema.type_of_expr(&expr)?.ty;
|
let ty = sema.type_of_expr(&expr)?.original;
|
||||||
if ty.is_unknown() {
|
if ty.is_unknown() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ fn get_bind_pat_hints(
|
||||||
let krate = sema.scope(pat.syntax()).module().map(|it| it.krate());
|
let krate = sema.scope(pat.syntax()).module().map(|it| it.krate());
|
||||||
let famous_defs = FamousDefs(sema, krate);
|
let famous_defs = FamousDefs(sema, krate);
|
||||||
|
|
||||||
let ty = sema.type_of_pat(&pat.clone().into())?.ty;
|
let ty = sema.type_of_pat(&pat.clone().into())?.original;
|
||||||
|
|
||||||
if should_not_display_type_hint(sema, &pat, &ty) {
|
if should_not_display_type_hint(sema, &pat, &ty) {
|
||||||
return None;
|
return None;
|
||||||
|
@ -308,7 +308,7 @@ fn should_not_display_type_hint(
|
||||||
return it.in_token().is_none() ||
|
return it.in_token().is_none() ||
|
||||||
it.iterable()
|
it.iterable()
|
||||||
.and_then(|iterable_expr| sema.type_of_expr(&iterable_expr))
|
.and_then(|iterable_expr| sema.type_of_expr(&iterable_expr))
|
||||||
.map(TypeInfo::ty)
|
.map(TypeInfo::original)
|
||||||
.map_or(true, |iterable_ty| iterable_ty.is_unknown() || iterable_ty.is_unit())
|
.map_or(true, |iterable_ty| iterable_ty.is_unknown() || iterable_ty.is_unit())
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -394,7 +394,7 @@ fn is_enum_name_similar_to_param_name(
|
||||||
argument: &ast::Expr,
|
argument: &ast::Expr,
|
||||||
param_name: &str,
|
param_name: &str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match sema.type_of_expr(argument).and_then(|t| t.ty.as_adt()) {
|
match sema.type_of_expr(argument).and_then(|t| t.original.as_adt()) {
|
||||||
Some(hir::Adt::Enum(e)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name,
|
Some(hir::Adt::Enum(e)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ fn get_callable(
|
||||||
) -> Option<(hir::Callable, ast::ArgList)> {
|
) -> Option<(hir::Callable, ast::ArgList)> {
|
||||||
match expr {
|
match expr {
|
||||||
ast::Expr::CallExpr(expr) => {
|
ast::Expr::CallExpr(expr) => {
|
||||||
sema.type_of_expr(&expr.expr()?)?.ty.as_callable(sema.db).zip(expr.arg_list())
|
sema.type_of_expr(&expr.expr()?)?.original.as_callable(sema.db).zip(expr.arg_list())
|
||||||
}
|
}
|
||||||
ast::Expr::MethodCallExpr(expr) => {
|
ast::Expr::MethodCallExpr(expr) => {
|
||||||
sema.resolve_method_call_as_callable(expr).zip(expr.arg_list())
|
sema.resolve_method_call_as_callable(expr).zip(expr.arg_list())
|
||||||
|
|
|
@ -123,7 +123,7 @@ pub(super) fn element(
|
||||||
let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?;
|
let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?;
|
||||||
|
|
||||||
let expr = prefix_expr.expr()?;
|
let expr = prefix_expr.expr()?;
|
||||||
let ty = sema.type_of_expr(&expr)?.ty;
|
let ty = sema.type_of_expr(&expr)?.original;
|
||||||
if ty.is_raw_ptr() {
|
if ty.is_raw_ptr() {
|
||||||
HlTag::Operator(HlOperator::Other) | HlMod::Unsafe
|
HlTag::Operator(HlOperator::Other) | HlMod::Unsafe
|
||||||
} else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() {
|
} else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() {
|
||||||
|
@ -555,7 +555,7 @@ fn highlight_method_call(
|
||||||
if let Some(receiver_ty) =
|
if let Some(receiver_ty) =
|
||||||
method_call.receiver().and_then(|it| sema.type_of_expr(&it))
|
method_call.receiver().and_then(|it| sema.type_of_expr(&it))
|
||||||
{
|
{
|
||||||
if !receiver_ty.coerced().is_copy(sema.db) {
|
if !receiver_ty.adjusted().is_copy(sema.db) {
|
||||||
h |= HlMod::Consuming
|
h |= HlMod::Consuming
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?,
|
(ast::Pat::IdentPat(_), Some(expr)) => ctx.sema.type_of_expr(&expr)?,
|
||||||
(pat, _) => ctx.sema.type_of_pat(&pat)?,
|
(pat, _) => ctx.sema.type_of_pat(&pat)?,
|
||||||
}
|
}
|
||||||
.coerced();
|
.adjusted();
|
||||||
|
|
||||||
// Unresolved or unnameable types can't be annotated
|
// Unresolved or unnameable types can't be annotated
|
||||||
if ty.contains_unknown() || ty.is_closure() {
|
if ty.contains_unknown() || ty.is_closure() {
|
||||||
|
|
|
@ -86,7 +86,7 @@ fn validate_method_call_expr(
|
||||||
let receiver = expr.receiver()?;
|
let receiver = expr.receiver()?;
|
||||||
let expr = ast::Expr::MethodCallExpr(expr);
|
let expr = ast::Expr::MethodCallExpr(expr);
|
||||||
|
|
||||||
let it_type = sema.type_of_expr(&receiver)?.coerced();
|
let it_type = sema.type_of_expr(&receiver)?.adjusted();
|
||||||
let module = sema.scope(receiver.syntax()).module()?;
|
let module = sema.scope(receiver.syntax()).module()?;
|
||||||
let krate = module.krate();
|
let krate = module.krate();
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl FlowKind {
|
||||||
FlowKind::Return(Some(expr))
|
FlowKind::Return(Some(expr))
|
||||||
| FlowKind::Break(Some(expr))
|
| FlowKind::Break(Some(expr))
|
||||||
| FlowKind::TryReturn { expr, .. } => {
|
| FlowKind::TryReturn { expr, .. } => {
|
||||||
ctx.sema.type_of_expr(expr).map(TypeInfo::coerced)
|
ctx.sema.type_of_expr(expr).map(TypeInfo::adjusted)
|
||||||
}
|
}
|
||||||
FlowKind::Try { .. } => {
|
FlowKind::Try { .. } => {
|
||||||
stdx::never!("try does not have defined expr_ty");
|
stdx::never!("try does not have defined expr_ty");
|
||||||
|
@ -852,7 +852,7 @@ fn either_syntax(value: &Either<ast::IdentPat, ast::SelfParam>) -> &SyntaxNode {
|
||||||
|
|
||||||
fn body_return_ty(ctx: &AssistContext, body: &FunctionBody) -> Option<RetType> {
|
fn body_return_ty(ctx: &AssistContext, body: &FunctionBody) -> Option<RetType> {
|
||||||
match body.tail_expr() {
|
match body.tail_expr() {
|
||||||
Some(expr) => ctx.sema.type_of_expr(&expr).map(TypeInfo::ty).map(RetType::Expr),
|
Some(expr) => ctx.sema.type_of_expr(&expr).map(TypeInfo::original).map(RetType::Expr),
|
||||||
None => Some(RetType::Stmt),
|
None => Some(RetType::Stmt),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,7 +949,7 @@ fn expr_err_kind(expr: &ast::Expr, ctx: &AssistContext) -> Option<TryKind> {
|
||||||
let text = func_name.syntax().text();
|
let text = func_name.syntax().text();
|
||||||
|
|
||||||
if text == "Err" {
|
if text == "Err" {
|
||||||
Some(TryKind::Result { ty: ctx.sema.type_of_expr(expr).map(TypeInfo::ty)? })
|
Some(TryKind::Result { ty: ctx.sema.type_of_expr(expr).map(TypeInfo::original)? })
|
||||||
} else if text == "None" {
|
} else if text == "None" {
|
||||||
Some(TryKind::Option)
|
Some(TryKind::Option)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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))
|
.take_while(|it| it.text_range().contains_range(ctx.frange.range))
|
||||||
.find_map(valid_target_expr)?;
|
.find_map(valid_target_expr)?;
|
||||||
if let Some(ty_info) = ctx.sema.type_of_expr(&to_extract) {
|
if let Some(ty_info) = ctx.sema.type_of_expr(&to_extract) {
|
||||||
if ty_info.coerced().is_unit() {
|
if ty_info.adjusted().is_unit() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,7 @@ impl ExtendedEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<ExtendedEnum> {
|
fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<ExtendedEnum> {
|
||||||
sema.type_of_expr(expr)?.coerced().autoderef(sema.db).find_map(|ty| match ty.as_adt() {
|
sema.type_of_expr(expr)?.adjusted().autoderef(sema.db).find_map(|ty| match ty.as_adt() {
|
||||||
Some(Adt::Enum(e)) => Some(ExtendedEnum::Enum(e)),
|
Some(Adt::Enum(e)) => Some(ExtendedEnum::Enum(e)),
|
||||||
_ => ty.is_bool().then(|| ExtendedEnum::Bool),
|
_ => ty.is_bool().then(|| ExtendedEnum::Bool),
|
||||||
})
|
})
|
||||||
|
@ -234,7 +234,7 @@ fn resolve_tuple_of_enum_def(
|
||||||
expr: &ast::Expr,
|
expr: &ast::Expr,
|
||||||
) -> Option<Vec<ExtendedEnum>> {
|
) -> Option<Vec<ExtendedEnum>> {
|
||||||
sema.type_of_expr(expr)?
|
sema.type_of_expr(expr)?
|
||||||
.coerced()
|
.adjusted()
|
||||||
.tuple_fields(sema.db)
|
.tuple_fields(sema.db)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| {
|
.map(|ty| {
|
||||||
|
|
|
@ -153,7 +153,8 @@ impl FunctionBuilder {
|
||||||
// type, but that the current state of their code doesn't allow that return type
|
// type, but that the current state of their code doesn't allow that return type
|
||||||
// to be accurately inferred.
|
// to be accurately inferred.
|
||||||
let (ret_ty, should_render_snippet) = {
|
let (ret_ty, should_render_snippet) = {
|
||||||
match ctx.sema.type_of_expr(&ast::Expr::CallExpr(call.clone())).map(TypeInfo::ty) {
|
match ctx.sema.type_of_expr(&ast::Expr::CallExpr(call.clone())).map(TypeInfo::original)
|
||||||
|
{
|
||||||
Some(ty) if ty.is_unknown() || ty.is_unit() => (make::ty_unit(), true),
|
Some(ty) if ty.is_unknown() || ty.is_unit() => (make::ty_unit(), true),
|
||||||
Some(ty) => {
|
Some(ty) => {
|
||||||
let rendered = ty.display_source_code(ctx.db(), target_module.into());
|
let rendered = ty.display_source_code(ctx.db(), target_module.into());
|
||||||
|
@ -331,7 +332,7 @@ fn fn_arg_type(
|
||||||
target_module: hir::Module,
|
target_module: hir::Module,
|
||||||
fn_arg: &ast::Expr,
|
fn_arg: &ast::Expr,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let ty = ctx.sema.type_of_expr(fn_arg)?.coerced();
|
let ty = ctx.sema.type_of_expr(fn_arg)?.adjusted();
|
||||||
if ty.is_unknown() {
|
if ty.is_unknown() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||||
pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
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 (fn_type, tail_expr, builder_edit_pos) = extract_tail(ctx)?;
|
||||||
let module = ctx.sema.scope(tail_expr.syntax()).module()?;
|
let module = ctx.sema.scope(tail_expr.syntax()).module()?;
|
||||||
let ty = ctx.sema.type_of_expr(&tail_expr)?.coerced();
|
let ty = ctx.sema.type_of_expr(&tail_expr)?.adjusted();
|
||||||
if ty.is_unit() {
|
if ty.is_unit() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,7 +190,7 @@ pub(crate) fn inline_(
|
||||||
let ty = ctx
|
let ty = ctx
|
||||||
.sema
|
.sema
|
||||||
.type_of_expr(&expr)
|
.type_of_expr(&expr)
|
||||||
.filter(TypeInfo::has_coercion)
|
.filter(TypeInfo::has_adjustment)
|
||||||
.and_then(|_| param_ty);
|
.and_then(|_| param_ty);
|
||||||
body.push_front(
|
body.push_front(
|
||||||
make::let_stmt(pat, ty, Some(expr)).clone_for_update().into(),
|
make::let_stmt(pat, ty, Some(expr)).clone_for_update().into(),
|
||||||
|
|
|
@ -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 wanted_method = if ref_expr.mut_token().is_some() { known::iter_mut } else { known::iter };
|
||||||
let expr_behind_ref = ref_expr.expr()?;
|
let expr_behind_ref = ref_expr.expr()?;
|
||||||
let ty = sema.type_of_expr(&expr_behind_ref)?.coerced();
|
let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted();
|
||||||
let scope = sema.scope(iterable.syntax());
|
let scope = sema.scope(iterable.syntax());
|
||||||
let krate = scope.module()?.krate();
|
let krate = scope.module()?.krate();
|
||||||
let traits_in_scope = scope.traits_in_scope();
|
let traits_in_scope = scope.traits_in_scope();
|
||||||
|
@ -110,7 +110,7 @@ fn is_ref_and_impls_iter_method(
|
||||||
/// Whether iterable implements core::Iterator
|
/// Whether iterable implements core::Iterator
|
||||||
fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
|
fn impls_core_iter(sema: &hir::Semantics<ide_db::RootDatabase>, iterable: &ast::Expr) -> bool {
|
||||||
let it_typ = match sema.type_of_expr(iterable) {
|
let it_typ = match sema.type_of_expr(iterable) {
|
||||||
Some(it) => it.coerced(),
|
Some(it) => it.adjusted(),
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ fn make_else_arm(
|
||||||
let pattern = if let [(Either::Left(pat), _)] = conditionals {
|
let pattern = if let [(Either::Left(pat), _)] = conditionals {
|
||||||
ctx.sema
|
ctx.sema
|
||||||
.type_of_pat(&pat)
|
.type_of_pat(&pat)
|
||||||
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.coerced()))
|
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
|
||||||
.zip(Some(pat))
|
.zip(Some(pat))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -268,7 +268,7 @@ fn binds_name(pat: &ast::Pat) -> bool {
|
||||||
|
|
||||||
fn is_sad_pat(sema: &hir::Semantics<RootDatabase>, pat: &ast::Pat) -> bool {
|
fn is_sad_pat(sema: &hir::Semantics<RootDatabase>, pat: &ast::Pat) -> bool {
|
||||||
sema.type_of_pat(pat)
|
sema.type_of_pat(pat)
|
||||||
.and_then(|ty| TryEnum::from_ty(sema, &ty.coerced()))
|
.and_then(|ty| TryEnum::from_ty(sema, &ty.adjusted()))
|
||||||
.map_or(false, |it| does_pat_match_variant(pat, &it.sad_pattern()))
|
.map_or(false, |it| does_pat_match_variant(pat, &it.sad_pattern()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
|
||||||
|edit| {
|
|edit| {
|
||||||
let ty = ctx.sema.type_of_expr(&init);
|
let ty = ctx.sema.type_of_expr(&init);
|
||||||
let happy_variant = ty
|
let happy_variant = ty
|
||||||
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.coerced()))
|
.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
|
||||||
.map(|it| it.happy_case());
|
.map(|it| it.happy_case());
|
||||||
let pat = match happy_variant {
|
let pat = match happy_variant {
|
||||||
None => original_pat,
|
None => original_pat,
|
||||||
|
|
|
@ -270,8 +270,8 @@ fn invert_special_case(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Opti
|
||||||
|
|
||||||
fn bin_impls_ord(sema: &Semantics<RootDatabase>, bin: &ast::BinExpr) -> bool {
|
fn bin_impls_ord(sema: &Semantics<RootDatabase>, bin: &ast::BinExpr) -> bool {
|
||||||
match (
|
match (
|
||||||
bin.lhs().and_then(|lhs| sema.type_of_expr(&lhs)).map(hir::TypeInfo::coerced),
|
bin.lhs().and_then(|lhs| sema.type_of_expr(&lhs)).map(hir::TypeInfo::adjusted),
|
||||||
bin.rhs().and_then(|rhs| sema.type_of_expr(&rhs)).map(hir::TypeInfo::coerced),
|
bin.rhs().and_then(|rhs| sema.type_of_expr(&rhs)).map(hir::TypeInfo::adjusted),
|
||||||
) {
|
) {
|
||||||
(Some(lhs_ty), Some(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 krate = sema.scope(bin.syntax()).module().map(|it| it.krate());
|
||||||
|
|
|
@ -197,7 +197,7 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<St
|
||||||
match args_parent {
|
match args_parent {
|
||||||
ast::CallExpr(call) => {
|
ast::CallExpr(call) => {
|
||||||
let func = call.expr()?;
|
let func = call.expr()?;
|
||||||
let func_ty = sema.type_of_expr(&func)?.coerced();
|
let func_ty = sema.type_of_expr(&func)?.adjusted();
|
||||||
func_ty.as_callable(sema.db)?
|
func_ty.as_callable(sema.db)?
|
||||||
},
|
},
|
||||||
ast::MethodCallExpr(method) => sema.resolve_method_call_as_callable(&method)?,
|
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> {
|
fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<String> {
|
||||||
let ty = sema.type_of_expr(expr)?.coerced();
|
let ty = sema.type_of_expr(expr)?.adjusted();
|
||||||
let ty = ty.remove_ref().unwrap_or(ty);
|
let ty = ty.remove_ref().unwrap_or(ty);
|
||||||
|
|
||||||
name_of_type(&ty, sema.db)
|
name_of_type(&ty, sema.db)
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
|
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
|
||||||
Some(ty) => ty.ty,
|
Some(ty) => ty.original,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
|
||||||
if let Some(dot_receiver) = ctx.dot_receiver() {
|
if let Some(dot_receiver) = ctx.dot_receiver() {
|
||||||
ImportAssets::for_fuzzy_method_call(
|
ImportAssets::for_fuzzy_method_call(
|
||||||
current_module,
|
current_module,
|
||||||
ctx.sema.type_of_expr(dot_receiver)?.ty,
|
ctx.sema.type_of_expr(dot_receiver)?.original,
|
||||||
fuzzy_name,
|
fuzzy_name,
|
||||||
dot_receiver.syntax().clone(),
|
dot_receiver.syntax().clone(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
let receiver_text = get_receiver_text(dot_receiver, receiver_is_ambiguous_float_literal);
|
let receiver_text = get_receiver_text(dot_receiver, receiver_is_ambiguous_float_literal);
|
||||||
|
|
||||||
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
|
let receiver_ty = match ctx.sema.type_of_expr(dot_receiver) {
|
||||||
Some(it) => it.ty,
|
Some(it) => it.original,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
|
||||||
Some(ImmediateLocation::RecordExpr(record_expr)) => {
|
Some(ImmediateLocation::RecordExpr(record_expr)) => {
|
||||||
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
|
let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
|
||||||
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
|
let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default();
|
||||||
let impl_default_trait = default_trait
|
let impl_default_trait = default_trait.zip(ty).map_or(false, |(default_trait, ty)| {
|
||||||
.zip(ty)
|
ty.original.impls_trait(ctx.db, default_trait, &[])
|
||||||
.map_or(false, |(default_trait, ty)| ty.ty.impls_trait(ctx.db, default_trait, &[]));
|
});
|
||||||
|
|
||||||
let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
|
let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
|
||||||
if impl_default_trait && !missing_fields.is_empty() {
|
if impl_default_trait && !missing_fields.is_empty() {
|
||||||
|
|
|
@ -454,7 +454,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
let ty = it.pat()
|
let ty = it.pat()
|
||||||
.and_then(|pat| self.sema.type_of_pat(&pat))
|
.and_then(|pat| self.sema.type_of_pat(&pat))
|
||||||
.or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it)))
|
.or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it)))
|
||||||
.map(TypeInfo::ty);
|
.map(TypeInfo::original);
|
||||||
let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() {
|
let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() {
|
||||||
ident.name().map(NameOrNameRef::Name)
|
ident.name().map(NameOrNameRef::Name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -497,13 +497,13 @@ impl<'a> CompletionContext<'a> {
|
||||||
ast::RecordExprField(it) => {
|
ast::RecordExprField(it) => {
|
||||||
cov_mark::hit!(expected_type_struct_field_with_leading_char);
|
cov_mark::hit!(expected_type_struct_field_with_leading_char);
|
||||||
(
|
(
|
||||||
it.expr().as_ref().and_then(|e| self.sema.type_of_expr(e)).map(TypeInfo::ty),
|
it.expr().as_ref().and_then(|e| self.sema.type_of_expr(e)).map(TypeInfo::original),
|
||||||
it.field_name().map(NameOrNameRef::NameRef),
|
it.field_name().map(NameOrNameRef::NameRef),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
ast::MatchExpr(it) => {
|
ast::MatchExpr(it) => {
|
||||||
cov_mark::hit!(expected_type_match_arm_without_leading_char);
|
cov_mark::hit!(expected_type_match_arm_without_leading_char);
|
||||||
let ty = it.expr().and_then(|e| self.sema.type_of_expr(&e)).map(TypeInfo::ty);
|
let ty = it.expr().and_then(|e| self.sema.type_of_expr(&e)).map(TypeInfo::original);
|
||||||
(ty, None)
|
(ty, None)
|
||||||
},
|
},
|
||||||
ast::IfExpr(it) => {
|
ast::IfExpr(it) => {
|
||||||
|
@ -511,13 +511,13 @@ impl<'a> CompletionContext<'a> {
|
||||||
let ty = it.condition()
|
let ty = it.condition()
|
||||||
.and_then(|cond| cond.expr())
|
.and_then(|cond| cond.expr())
|
||||||
.and_then(|e| self.sema.type_of_expr(&e))
|
.and_then(|e| self.sema.type_of_expr(&e))
|
||||||
.map(TypeInfo::ty);
|
.map(TypeInfo::original);
|
||||||
(ty, None)
|
(ty, None)
|
||||||
},
|
},
|
||||||
ast::IdentPat(it) => {
|
ast::IdentPat(it) => {
|
||||||
cov_mark::hit!(expected_type_if_let_with_leading_char);
|
cov_mark::hit!(expected_type_if_let_with_leading_char);
|
||||||
cov_mark::hit!(expected_type_match_arm_with_leading_char);
|
cov_mark::hit!(expected_type_match_arm_with_leading_char);
|
||||||
let ty = self.sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::ty);
|
let ty = self.sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::original);
|
||||||
(ty, None)
|
(ty, None)
|
||||||
},
|
},
|
||||||
ast::Fn(it) => {
|
ast::Fn(it) => {
|
||||||
|
@ -528,7 +528,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
},
|
},
|
||||||
ast::ClosureExpr(it) => {
|
ast::ClosureExpr(it) => {
|
||||||
let ty = self.sema.type_of_expr(&it.into());
|
let ty = self.sema.type_of_expr(&it.into());
|
||||||
ty.and_then(|ty| ty.ty.as_callable(self.db))
|
ty.and_then(|ty| ty.original.as_callable(self.db))
|
||||||
.map(|c| (Some(c.return_type()), None))
|
.map(|c| (Some(c.return_type()), None))
|
||||||
.unwrap_or((None, None))
|
.unwrap_or((None, None))
|
||||||
},
|
},
|
||||||
|
|
|
@ -119,7 +119,7 @@ fn call_info_impl(
|
||||||
|
|
||||||
let callable = match &calling_node {
|
let callable = match &calling_node {
|
||||||
FnCallNode::CallExpr(call) => {
|
FnCallNode::CallExpr(call) => {
|
||||||
sema.type_of_expr(&call.expr()?)?.coerced().as_callable(sema.db)?
|
sema.type_of_expr(&call.expr()?)?.adjusted().as_callable(sema.db)?
|
||||||
}
|
}
|
||||||
FnCallNode::MethodCallExpr(call) => sema.resolve_method_call_as_callable(call)?,
|
FnCallNode::MethodCallExpr(call) => sema.resolve_method_call_as_callable(call)?,
|
||||||
};
|
};
|
||||||
|
|
|
@ -543,7 +543,7 @@ impl ImportCandidate {
|
||||||
match sema.resolve_method_call(method_call) {
|
match sema.resolve_method_call(method_call) {
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => Some(Self::TraitMethod(TraitImportCandidate {
|
None => Some(Self::TraitMethod(TraitImportCandidate {
|
||||||
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.coerced(),
|
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(),
|
||||||
assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()),
|
assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()),
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingOkOrSomeInTailExpr) -> Op
|
||||||
let tail_expr_range = tail_expr.syntax().text_range();
|
let tail_expr_range = tail_expr.syntax().text_range();
|
||||||
let mut builder = TextEdit::builder();
|
let mut builder = TextEdit::builder();
|
||||||
for_each_tail_expr(&tail_expr, &mut |expr| {
|
for_each_tail_expr(&tail_expr, &mut |expr| {
|
||||||
if ctx.sema.type_of_expr(expr).map(TypeInfo::ty).as_ref() != Some(&d.expected) {
|
if ctx.sema.type_of_expr(expr).map(TypeInfo::original).as_ref() != Some(&d.expected) {
|
||||||
builder.insert(expr.syntax().text_range().start(), format!("{}(", d.required));
|
builder.insert(expr.syntax().text_range().start(), format!("{}(", d.required));
|
||||||
builder.insert(expr.syntax().text_range().end(), ")".to_string());
|
builder.insert(expr.syntax().text_range().end(), ")".to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ fn missing_record_expr_field_fixes(
|
||||||
};
|
};
|
||||||
let def_file_id = def_file_id.original_file(sema.db);
|
let def_file_id = def_file_id.original_file(sema.db);
|
||||||
|
|
||||||
let new_field_type = sema.type_of_expr(&record_expr_field.expr()?)?.coerced();
|
let new_field_type = sema.type_of_expr(&record_expr_field.expr()?)?.adjusted();
|
||||||
if new_field_type.is_unknown() {
|
if new_field_type.is_unknown() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -615,7 +615,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
match_error!("Failed to get receiver type for `{}`", expr.syntax().text())
|
match_error!("Failed to get receiver type for `{}`", expr.syntax().text())
|
||||||
})?
|
})?
|
||||||
.ty;
|
.original;
|
||||||
// Temporary needed to make the borrow checker happy.
|
// Temporary needed to make the borrow checker happy.
|
||||||
let res = code_type
|
let res = code_type
|
||||||
.autoderef(self.sema.db)
|
.autoderef(self.sema.db)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue