mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 15:15:24 +00:00
Diagnose unresolved method calls
This commit is contained in:
parent
78b2dd813a
commit
e7485a0416
8 changed files with 320 additions and 48 deletions
|
@ -164,14 +164,45 @@ pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum InferenceDiagnostic {
|
||||
NoSuchField { expr: ExprId },
|
||||
PrivateField { expr: ExprId, field: FieldId },
|
||||
PrivateAssocItem { id: ExprOrPatId, item: AssocItemId },
|
||||
UnresolvedField { expr: ExprId, receiver: Ty, name: Name, method_with_same_name_exists: bool },
|
||||
NoSuchField {
|
||||
expr: ExprId,
|
||||
},
|
||||
PrivateField {
|
||||
expr: ExprId,
|
||||
field: FieldId,
|
||||
},
|
||||
PrivateAssocItem {
|
||||
id: ExprOrPatId,
|
||||
item: AssocItemId,
|
||||
},
|
||||
UnresolvedField {
|
||||
expr: ExprId,
|
||||
receiver: Ty,
|
||||
name: Name,
|
||||
method_with_same_name_exists: bool,
|
||||
},
|
||||
UnresolvedMethodCall {
|
||||
expr: ExprId,
|
||||
receiver: Ty,
|
||||
name: Name,
|
||||
/// Contains the type the field resolves to
|
||||
field_with_same_name: Option<Ty>,
|
||||
},
|
||||
// FIXME: Make this proper
|
||||
BreakOutsideOfLoop { expr: ExprId, is_break: bool, bad_value_break: bool },
|
||||
MismatchedArgCount { call_expr: ExprId, expected: usize, found: usize },
|
||||
ExpectedFunction { call_expr: ExprId, found: Ty },
|
||||
BreakOutsideOfLoop {
|
||||
expr: ExprId,
|
||||
is_break: bool,
|
||||
bad_value_break: bool,
|
||||
},
|
||||
MismatchedArgCount {
|
||||
call_expr: ExprId,
|
||||
expected: usize,
|
||||
found: usize,
|
||||
},
|
||||
ExpectedFunction {
|
||||
call_expr: ExprId,
|
||||
found: Ty,
|
||||
},
|
||||
}
|
||||
|
||||
/// A mismatch between an expected and an inferred type.
|
||||
|
@ -509,12 +540,28 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
result.diagnostics.retain_mut(|diagnostic| {
|
||||
if let InferenceDiagnostic::ExpectedFunction { found: ty, .. }
|
||||
| InferenceDiagnostic::UnresolvedField { receiver: ty, .. } = diagnostic
|
||||
| InferenceDiagnostic::UnresolvedField { receiver: ty, .. }
|
||||
| InferenceDiagnostic::UnresolvedMethodCall { receiver: ty, .. } = diagnostic
|
||||
{
|
||||
*ty = table.resolve_completely(ty.clone());
|
||||
// FIXME: Remove this when we are on par with rustc in terms of inference
|
||||
if ty.is_unknown() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if let InferenceDiagnostic::UnresolvedMethodCall { field_with_same_name, .. } =
|
||||
diagnostic
|
||||
{
|
||||
let clear = if let Some(ty) = field_with_same_name {
|
||||
*ty = table.resolve_completely(ty.clone());
|
||||
ty.is_unknown()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if clear {
|
||||
*field_with_same_name = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue