Add static type inference

This commit is contained in:
Ville Penttinen 2019-02-25 10:21:01 +02:00
parent 18b0bd9bff
commit 29f93a7906
6 changed files with 54 additions and 12 deletions

View File

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

View File

@ -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<ConstSignature> {
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)
}
}

View File

@ -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<HirInterner> {
#[salsa::invoke(crate::ConstSignature::const_signature_query)]
fn const_signature(&self, konst: Const) -> Arc<ConstSignature>;
#[salsa::invoke(crate::ConstSignature::static_signature_query)]
fn static_signature(&self, konst: Static) -> Arc<ConstSignature>;
}
#[salsa::query_group(HirDatabaseStorage)]

View File

@ -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),
}
}

View File

@ -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<ModuleDef> for Option<TypableDef> {
fn from(def: ModuleDef) -> Option<TypableDef> {
@ -344,7 +356,8 @@ impl From<ModuleDef> for Option<TypableDef> {
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)
}

View File

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