Resolve the self parameter during type inference

This commit is contained in:
Florian Diebold 2018-12-29 22:59:18 +01:00
parent 111126ed3c
commit d4db61b9a1
3 changed files with 19 additions and 4 deletions

View file

@ -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 {

View file

@ -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() {

View file

@ -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]