mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-09 18:02:48 +00:00
Resolve the self parameter during type inference
This commit is contained in:
parent
111126ed3c
commit
d4db61b9a1
3 changed files with 19 additions and 4 deletions
|
@ -70,6 +70,11 @@ impl Path {
|
||||||
self.kind == PathKind::Plain && self.segments.len() == 1
|
self.kind == PathKind::Plain && self.segments.len() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `true` if this path is just a standalone `self`
|
||||||
|
pub fn is_self(&self) -> bool {
|
||||||
|
self.kind == PathKind::Self_ && self.segments.len() == 0
|
||||||
|
}
|
||||||
|
|
||||||
/// If this path is a single identifier, like `foo`, return its name.
|
/// If this path is a single identifier, like `foo`, return its name.
|
||||||
pub fn as_ident(&self) -> Option<&Name> {
|
pub fn as_ident(&self) -> Option<&Name> {
|
||||||
if self.kind != PathKind::Plain || self.segments.len() > 1 {
|
if self.kind != PathKind::Plain || self.segments.len() > 1 {
|
||||||
|
|
|
@ -496,6 +496,8 @@ impl InferenceResult {
|
||||||
struct InferenceContext<'a, D: HirDatabase> {
|
struct InferenceContext<'a, D: HirDatabase> {
|
||||||
db: &'a D,
|
db: &'a D,
|
||||||
scopes: Arc<FnScopes>,
|
scopes: Arc<FnScopes>,
|
||||||
|
/// The self param for the current method, if it exists.
|
||||||
|
self_param: Option<LocalSyntaxPtr>,
|
||||||
module: Module,
|
module: Module,
|
||||||
var_unification_table: InPlaceUnificationTable<TypeVarId>,
|
var_unification_table: InPlaceUnificationTable<TypeVarId>,
|
||||||
type_of: FxHashMap<LocalSyntaxPtr, Ty>,
|
type_of: FxHashMap<LocalSyntaxPtr, Ty>,
|
||||||
|
@ -506,6 +508,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
InferenceContext {
|
InferenceContext {
|
||||||
type_of: FxHashMap::default(),
|
type_of: FxHashMap::default(),
|
||||||
var_unification_table: InPlaceUnificationTable::new(),
|
var_unification_table: InPlaceUnificationTable::new(),
|
||||||
|
self_param: None, // set during parameter typing
|
||||||
db,
|
db,
|
||||||
scopes,
|
scopes,
|
||||||
module,
|
module,
|
||||||
|
@ -628,6 +631,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
let ty = self.resolve_ty_as_possible(ty.clone());
|
let ty = self.resolve_ty_as_possible(ty.clone());
|
||||||
return Ok(Some(ty));
|
return Ok(Some(ty));
|
||||||
};
|
};
|
||||||
|
} else if path.is_self() {
|
||||||
|
// resolve `self` param
|
||||||
|
let self_param = ctry!(self.self_param);
|
||||||
|
let ty = ctry!(self.type_of.get(&self_param));
|
||||||
|
let ty = self.resolve_ty_as_possible(ty.clone());
|
||||||
|
return Ok(Some(ty));
|
||||||
};
|
};
|
||||||
|
|
||||||
// resolve in module
|
// resolve in module
|
||||||
|
@ -940,8 +949,9 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceRe
|
||||||
ctx.new_type_var()
|
ctx.new_type_var()
|
||||||
};
|
};
|
||||||
if let Some(self_kw) = self_param.self_kw() {
|
if let Some(self_kw) = self_param.self_kw() {
|
||||||
ctx.type_of
|
let self_param = LocalSyntaxPtr::new(self_kw.syntax());
|
||||||
.insert(LocalSyntaxPtr::new(self_kw.syntax()), self_type);
|
ctx.self_param = Some(self_param);
|
||||||
|
ctx.type_of.insert(self_param, self_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for param in param_list.params() {
|
for param in param_list.params() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[50; 54) 'self': [unknown]
|
[50; 54) 'self': &S
|
||||||
[34; 38) 'self': &S
|
[34; 38) 'self': &S
|
||||||
[40; 61) '{ ... }': ()
|
[40; 61) '{ ... }': ()
|
||||||
[88; 109) '{ ... }': ()
|
[88; 109) '{ ... }': ()
|
||||||
[98; 102) 'self': [unknown]
|
[98; 102) 'self': &[unknown]
|
||||||
[75; 79) 'self': &[unknown]
|
[75; 79) 'self': &[unknown]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue