internal: Handle fields called as method calls as the fields they resolve to
This commit is contained in:
parent
b85e2af898
commit
5a91f015b4
@ -12,7 +12,7 @@ use hir_def::{
|
|||||||
macro_id_to_def_id,
|
macro_id_to_def_id,
|
||||||
resolver::{self, HasResolver, Resolver, TypeNs},
|
resolver::{self, HasResolver, Resolver, TypeNs},
|
||||||
type_ref::Mutability,
|
type_ref::Mutability,
|
||||||
AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
|
AsMacroCall, DefWithBodyId, FieldId, FunctionId, MacroId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
db::AstDatabase,
|
db::AstDatabase,
|
||||||
@ -366,6 +366,16 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
|||||||
self.imp.resolve_method_call(call).map(Function::from)
|
self.imp.resolve_method_call(call).map(Function::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to resolve this call expression as a method call falling back to resolving it as a field.
|
||||||
|
pub fn resolve_method_call_field_fallback(
|
||||||
|
&self,
|
||||||
|
call: &ast::MethodCallExpr,
|
||||||
|
) -> Option<Either<Function, Field>> {
|
||||||
|
self.imp
|
||||||
|
.resolve_method_call_fallback(call)
|
||||||
|
.map(|it| it.map_left(Function::from).map_right(Field::from))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<Function> {
|
pub fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<Function> {
|
||||||
self.imp.resolve_await_to_poll(await_expr).map(Function::from)
|
self.imp.resolve_await_to_poll(await_expr).map(Function::from)
|
||||||
}
|
}
|
||||||
@ -1146,6 +1156,13 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
self.analyze(call.syntax())?.resolve_method_call(self.db, call)
|
self.analyze(call.syntax())?.resolve_method_call(self.db, call)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_method_call_fallback(
|
||||||
|
&self,
|
||||||
|
call: &ast::MethodCallExpr,
|
||||||
|
) -> Option<Either<FunctionId, FieldId>> {
|
||||||
|
self.analyze(call.syntax())?.resolve_method_call_fallback(self.db, call)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<FunctionId> {
|
fn resolve_await_to_poll(&self, await_expr: &ast::AwaitExpr) -> Option<FunctionId> {
|
||||||
self.analyze(await_expr.syntax())?.resolve_await_to_poll(self.db, await_expr)
|
self.analyze(await_expr.syntax())?.resolve_await_to_poll(self.db, await_expr)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
body::{
|
body::{
|
||||||
self,
|
self,
|
||||||
@ -266,6 +267,21 @@ impl SourceAnalyzer {
|
|||||||
Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
|
Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resolve_method_call_fallback(
|
||||||
|
&self,
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
call: &ast::MethodCallExpr,
|
||||||
|
) -> Option<Either<FunctionId, FieldId>> {
|
||||||
|
let expr_id = self.expr_id(db, &call.clone().into())?;
|
||||||
|
let inference_result = self.infer.as_ref()?;
|
||||||
|
match inference_result.method_resolution(expr_id) {
|
||||||
|
Some((f_in_trait, substs)) => {
|
||||||
|
Some(Either::Left(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs)))
|
||||||
|
}
|
||||||
|
None => inference_result.field_resolution(expr_id).map(Either::Right),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_await_to_poll(
|
pub(crate) fn resolve_await_to_poll(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
|
@ -469,9 +469,12 @@ impl NameRefClass {
|
|||||||
match_ast! {
|
match_ast! {
|
||||||
match parent {
|
match parent {
|
||||||
ast::MethodCallExpr(method_call) => {
|
ast::MethodCallExpr(method_call) => {
|
||||||
sema.resolve_method_call(&method_call)
|
sema.resolve_method_call_field_fallback(&method_call)
|
||||||
.map(Definition::Function)
|
.map(|it| {
|
||||||
.map(NameRefClass::Definition)
|
it.map_left(Definition::Function)
|
||||||
|
.map_right(Definition::Field)
|
||||||
|
.either(NameRefClass::Definition, NameRefClass::Definition)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
ast::FieldExpr(field_expr) => {
|
ast::FieldExpr(field_expr) => {
|
||||||
sema.resolve_field(&field_expr)
|
sema.resolve_field(&field_expr)
|
||||||
|
@ -5797,3 +5797,26 @@ mod m {
|
|||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn field_as_method_call_fallback() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct S { f: u32 }
|
||||||
|
fn test() {
|
||||||
|
S { f: 0 }.f$0();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*f*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test::S
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
f: u32 // size = 4, align = 4, offset = 0
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user