From 29f93a79069cf929fbc6d4efa194a0ab18bb1f45 Mon Sep 17 00:00:00 2001 From: Ville Penttinen Date: Mon, 25 Feb 2019 10:21:01 +0200 Subject: Add static type inference --- crates/ra_hir/src/code_model_api.rs | 10 ++++++++++ crates/ra_hir/src/code_model_impl/konst.rs | 17 ++++++++++++++++- crates/ra_hir/src/db.rs | 5 ++++- crates/ra_hir/src/ty/infer.rs | 3 ++- crates/ra_hir/src/ty/lower.rs | 21 +++++++++++++++++---- .../src/ty/snapshots/tests__infer_static.snap | 10 +++++----- 6 files changed, 54 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 9efd902fa..d668b883c 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -612,6 +612,16 @@ impl Static { pub fn module(&self, db: &impl PersistentHirDatabase) -> Module { self.id.module(db) } + + pub fn signature(&self, db: &impl HirDatabase) -> Arc { + db.static_signature(*self) + } + + /// Builds a resolver for code inside this item. + pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { + // take the outer scope... + self.module(db).resolver(db) + } } impl Docs for Static { diff --git a/crates/ra_hir/src/code_model_impl/konst.rs b/crates/ra_hir/src/code_model_impl/konst.rs index ee03e3374..d7722ccc2 100644 --- a/crates/ra_hir/src/code_model_impl/konst.rs +++ b/crates/ra_hir/src/code_model_impl/konst.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use ra_syntax::ast::{NameOwner}; use crate::{ - Name, AsName, Const, ConstSignature, + Name, AsName, Const, ConstSignature, Static, type_ref::{TypeRef}, PersistentHirDatabase, }; @@ -23,4 +23,19 @@ impl ConstSignature { Arc::new(sig) } + + pub(crate) fn static_signature_query( + db: &impl PersistentHirDatabase, + konst: Static, + ) -> Arc { + let (_, node) = konst.source(db); + + let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); + + let type_ref = TypeRef::from_ast_opt(node.type_ref()); + + let sig = ConstSignature { name, type_ref }; + + Arc::new(sig) + } } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 2be47c160..ec848f1b2 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -8,7 +8,7 @@ use crate::{ SourceFileItems, SourceItemId, Crate, Module, HirInterner, Function, FnSignature, ExprScopes, TypeAlias, Struct, Enum, StructField, - Const, ConstSignature, + Const, ConstSignature, Static, macros::MacroExpansion, module_tree::ModuleTree, nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, @@ -86,6 +86,9 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef { #[salsa::invoke(crate::ConstSignature::const_signature_query)] fn const_signature(&self, konst: Const) -> Arc; + + #[salsa::invoke(crate::ConstSignature::static_signature_query)] + fn static_signature(&self, konst: Static) -> Arc; } #[salsa::query_group(HirDatabaseStorage)] diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index f5f85308c..5e4d49ffb 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -485,7 +485,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { TypableDef::TypeAlias(_) | TypableDef::Function(_) | TypableDef::Enum(_) - | TypableDef::Const(_) => (Ty::Unknown, None), + | TypableDef::Const(_) + | TypableDef::Static(_) => (Ty::Unknown, None), } } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 4a9b725d1..f4e055feb 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use crate::{ Function, Struct, StructField, Enum, EnumVariant, Path, Name, ModuleDef, TypeAlias, - Const, + Const, Static, HirDatabase, type_ref::TypeRef, name::KnownName, @@ -126,7 +126,7 @@ impl Ty { TypableDef::Enum(e) => e.generic_params(db), TypableDef::EnumVariant(var) => var.parent_enum(db).generic_params(db), TypableDef::TypeAlias(t) => t.generic_params(db), - TypableDef::Const(_) => GenericParams::default().into(), + TypableDef::Const(_) | TypableDef::Static(_) => GenericParams::default().into(), }; let parent_param_count = def_generics.count_parent_params(); substs.extend((0..parent_param_count).map(|_| Ty::Unknown)); @@ -166,6 +166,7 @@ impl Ty { | TypableDef::Struct(_) | TypableDef::Enum(_) | TypableDef::Const(_) + | TypableDef::Static(_) | TypableDef::TypeAlias(_) => last, TypableDef::EnumVariant(_) => { // the generic args for an enum variant may be either specified @@ -201,6 +202,7 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), + (TypableDef::Static(c), Namespace::Values) => type_for_static(db, c), // 'error' cases: (TypableDef::Function(_), Namespace::Types) => Ty::Unknown, @@ -208,6 +210,7 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace (TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown, (TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown, (TypableDef::Const(_), Namespace::Types) => Ty::Unknown, + (TypableDef::Static(_), Namespace::Types) => Ty::Unknown, } } @@ -246,6 +249,14 @@ fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { Ty::from_hir(db, &resolver, signature.type_ref()) } +/// Build the declared type of a static. +fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { + let signature = def.signature(db); + let resolver = def.resolver(db); + + Ty::from_hir(db, &resolver, signature.type_ref()) +} + /// Build the type of a tuple struct constructor. fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { let var_data = def.variant_data(db); @@ -332,8 +343,9 @@ pub enum TypableDef { EnumVariant(EnumVariant), TypeAlias(TypeAlias), Const(Const), + Static(Static), } -impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, TypeAlias, Const); +impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, TypeAlias, Const, Static); impl From for Option { fn from(def: ModuleDef) -> Option { @@ -344,7 +356,8 @@ impl From for Option { ModuleDef::EnumVariant(v) => v.into(), ModuleDef::TypeAlias(t) => t.into(), ModuleDef::Const(v) => v.into(), - ModuleDef::Static(_) | ModuleDef::Module(_) | ModuleDef::Trait(_) => return None, + ModuleDef::Static(v) => v.into(), + ModuleDef::Module(_) | ModuleDef::Trait(_) => return None, }; Some(res) } diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_static.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_static.snap index ffe9ca66d..5d90f56ed 100644 --- a/crates/ra_hir/src/ty/snapshots/tests__infer_static.snap +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_static.snap @@ -1,5 +1,5 @@ --- -created: "2019-02-25T07:26:41.480764900Z" +created: "2019-02-25T08:20:17.807316Z" creator: insta@0.6.3 source: crates/ra_hir/src/ty/tests.rs expression: "&result" @@ -9,8 +9,8 @@ expression: "&result" [177; 189) 'LOCAL_STATIC': [unknown] [199; 200) 'y': [unknown] [203; 219) 'LOCAL_...IC_MUT': [unknown] -[229; 230) 'z': [unknown] -[233; 246) 'GLOBAL_STATIC': [unknown] -[256; 257) 'w': [unknown] -[260; 277) 'GLOBAL...IC_MUT': [unknown] +[229; 230) 'z': u32 +[233; 246) 'GLOBAL_STATIC': u32 +[256; 257) 'w': u32 +[260; 277) 'GLOBAL...IC_MUT': u32 -- cgit v1.2.3