]> git.lizzy.rs Git - rust.git/commitdiff
Resolve the self parameter during type inference
authorFlorian Diebold <flodiebold@gmail.com>
Sat, 29 Dec 2018 21:59:18 +0000 (22:59 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 4 Jan 2019 18:12:29 +0000 (19:12 +0100)
crates/ra_hir/src/path.rs
crates/ra_hir/src/ty.rs
crates/ra_hir/src/ty/tests/data/0007_self.txt

index 93f7203fe26587388c8392689da2d9464f62f57f..9fdfa0d131238b5f46661babe8c626176892229e 100644 (file)
@@ -70,6 +70,11 @@ pub fn is_ident(&self) -> bool {
         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.
     pub fn as_ident(&self) -> Option<&Name> {
         if self.kind != PathKind::Plain || self.segments.len() > 1 {
index c762ec6068eac2a765333c1dd0baf7b55a3e124e..5ea62a14cfa398c97910baef3801dc3ccb23fcea 100644 (file)
@@ -496,6 +496,8 @@ pub fn type_of_node(&self, node: SyntaxNodeRef) -> Option<Ty> {
 struct InferenceContext<'a, D: HirDatabase> {
     db: &'a D,
     scopes: Arc<FnScopes>,
+    /// The self param for the current method, if it exists.
+    self_param: Option<LocalSyntaxPtr>,
     module: Module,
     var_unification_table: InPlaceUnificationTable<TypeVarId>,
     type_of: FxHashMap<LocalSyntaxPtr, Ty>,
@@ -506,6 +508,7 @@ fn new(db: &'a D, scopes: Arc<FnScopes>, module: Module) -> Self {
         InferenceContext {
             type_of: FxHashMap::default(),
             var_unification_table: InPlaceUnificationTable::new(),
+            self_param: None, // set during parameter typing
             db,
             scopes,
             module,
@@ -628,6 +631,12 @@ fn infer_path_expr(&mut self, expr: ast::PathExpr) -> Cancelable<Option<Ty>> {
                 let ty = self.resolve_ty_as_possible(ty.clone());
                 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
@@ -940,8 +949,9 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceRe
                 ctx.new_type_var()
             };
             if let Some(self_kw) = self_param.self_kw() {
-                ctx.type_of
-                    .insert(LocalSyntaxPtr::new(self_kw.syntax()), self_type);
+                let self_param = LocalSyntaxPtr::new(self_kw.syntax());
+                ctx.self_param = Some(self_param);
+                ctx.type_of.insert(self_param, self_type);
             }
         }
         for param in param_list.params() {
index 3d3c8b260994bcc9e1d08ba218a8b9aba087160a..0dd61da559f509dc022cd8c9a025b2b544a8f5d7 100644 (file)
@@ -1,6 +1,6 @@
-[50; 54) 'self': [unknown]
+[50; 54) 'self': &S
 [34; 38) 'self': &S
 [40; 61) '{     ...     }': ()
 [88; 109) '{     ...     }': ()
-[98; 102) 'self': [unknown]
+[98; 102) 'self': &[unknown]
 [75; 79) 'self': &[unknown]