Merge branch 'master' into feature/themes

This commit is contained in:
Seivan Heidari 2019-10-31 17:40:39 +01:00
commit 1b6c68e51f
9 changed files with 240 additions and 217 deletions

42
Cargo.lock generated
View file

@ -272,7 +272,7 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -455,7 +455,15 @@ name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -664,7 +672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memoffset"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -761,9 +769,10 @@ dependencies = [
[[package]]
name = "num_cpus"
version = "1.10.1"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -802,7 +811,7 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1111,7 +1120,7 @@ dependencies = [
"ra_syntax 0.1.0",
"ra_tt 0.1.0",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"test_utils 0.1.0",
]
@ -1364,7 +1373,7 @@ dependencies = [
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1476,7 +1485,7 @@ dependencies = [
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"salsa-macros 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1573,7 +1582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.6.11"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1659,7 +1668,7 @@ name = "threadpool"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1693,12 +1702,12 @@ name = "unicode-normalization"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-segmentation"
version = "1.4.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1879,6 +1888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
"checksum indicatif 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d596a9576eaa1446996092642d72bfef35cf47243129b7ab883baf5faec31e"
@ -1905,7 +1915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lsp-types 0.61.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa3268fbe8beb2795c2fb327bf44f4f3d24f5fe9ebc18d7e2980afd444d72bcf"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a85c1a8c329f11437034d7313dca647c79096523533a1c79e86f1d0f657c7cc"
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
@ -1914,7 +1924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum num_cpus 1.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155394f924cdddf08149da25bfb932d226b4a593ca7468b08191ff6335941af5"
"checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
@ -1975,7 +1985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cefaa50e76a6f10b86f36e640eb1739eafbd4084865067778463913e43a77ff3"
"checksum smallvec 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "533e29e15d0748f28afbaf4ff7cab44d73e483a8e50b38c40bd13b7f3d48f542"
"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
"checksum stacker 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d96fc4f13a0ac088e9a3cd9af1cc8c5cc1ab5deb2145cef661267dfc9c542f8a"
"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
@ -1989,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
"checksum unicode-segmentation 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc5415c074426c7c65db13bd647c23d78c0fb2e10dca0b8fb0f40058a59bccdf"
"checksum unicode-segmentation 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49f5526225fd8b77342d5986ab5f6055552e9c0776193b5b63fd53b46debfad7"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"

View file

@ -3,152 +3,16 @@
use std::sync::Arc;
use hir_def::{type_ref::TypeRef, LocalEnumVariantId};
use hir_expand::name::AsName;
use ra_arena::{impl_arena_id, Arena, RawId};
use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner};
use hir_def::adt::VariantData;
use crate::{
db::{AstDatabase, DefDatabase, HirDatabase},
Enum, EnumVariant, FieldSource, HasSource, Module, Name, Source, Struct, StructField,
db::{DefDatabase, HirDatabase},
EnumVariant, Module, Name, Struct, StructField,
};
impl Struct {
pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
db.struct_data(self).variant_data.clone()
}
}
/// Note that we use `StructData` for unions as well!
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructData {
pub(crate) name: Option<Name>,
pub(crate) variant_data: Arc<VariantData>,
}
impl StructData {
fn new(struct_def: &ast::StructDef) -> StructData {
let name = struct_def.name().map(|n| n.as_name());
let variant_data = VariantData::new(struct_def.kind());
let variant_data = Arc::new(variant_data);
StructData { name, variant_data }
}
pub(crate) fn struct_data_query(
db: &(impl DefDatabase + AstDatabase),
struct_: Struct,
) -> Arc<StructData> {
let src = struct_.source(db);
Arc::new(StructData::new(&src.ast))
}
}
fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = ast::EnumVariant> {
enum_def.variant_list().into_iter().flat_map(|it| it.variants())
}
impl EnumVariant {
pub(crate) fn source_impl(
self,
db: &(impl DefDatabase + AstDatabase),
) -> Source<ast::EnumVariant> {
let src = self.parent.source(db);
let ast = variants(&src.ast)
.zip(db.enum_data(self.parent).variants.iter())
.find(|(_syntax, (id, _))| *id == self.id)
.unwrap()
.0;
Source { file_id: src.file_id, ast }
}
pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
db.enum_data(self.parent).variants[self.id].variant_data.clone()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumData {
pub(crate) name: Option<Name>,
pub(crate) variants: Arena<LocalEnumVariantId, EnumVariantData>,
}
impl EnumData {
pub(crate) fn enum_data_query(db: &(impl DefDatabase + AstDatabase), e: Enum) -> Arc<EnumData> {
let src = e.source(db);
let name = src.ast.name().map(|n| n.as_name());
let variants = variants(&src.ast)
.map(|var| EnumVariantData {
name: var.name().map(|it| it.as_name()),
variant_data: Arc::new(VariantData::new(var.kind())),
})
.collect();
Arc::new(EnumData { name, variants })
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct EnumVariantData {
pub(crate) name: Option<Name>,
variant_data: Arc<VariantData>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct StructFieldId(RawId);
impl_arena_id!(StructFieldId);
/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructFieldData {
pub(crate) name: Name,
pub(crate) type_ref: TypeRef,
}
/// Fields of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct VariantData(VariantDataInner);
#[derive(Debug, Clone, PartialEq, Eq)]
enum VariantDataInner {
Struct(Arena<StructFieldId, StructFieldData>),
Tuple(Arena<StructFieldId, StructFieldData>),
Unit,
}
impl VariantData {
pub(crate) fn fields(&self) -> Option<&Arena<StructFieldId, StructFieldData>> {
match &self.0 {
VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields),
_ => None,
}
}
}
impl VariantData {
fn new(flavor: StructKind) -> Self {
let inner = match flavor {
ast::StructKind::Tuple(fl) => {
let fields = fl
.fields()
.enumerate()
.map(|(i, fd)| StructFieldData {
name: Name::new_tuple_field(i),
type_ref: TypeRef::from_ast_opt(fd.type_ref()),
})
.collect();
VariantDataInner::Tuple(fields)
}
ast::StructKind::Named(fl) => {
let fields = fl
.fields()
.map(|fd| StructFieldData {
name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
})
.collect();
VariantDataInner::Struct(fields)
}
ast::StructKind::Unit => VariantDataInner::Unit,
};
VariantData(inner)
db.struct_data(self.id).variant_data.clone()
}
}
@ -188,35 +52,3 @@ impl VariantDef {
}
}
}
impl StructField {
pub(crate) fn source_impl(&self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> {
let var_data = self.parent.variant_data(db);
let fields = var_data.fields().unwrap();
let ss;
let es;
let (file_id, struct_kind) = match self.parent {
VariantDef::Struct(s) => {
ss = s.source(db);
(ss.file_id, ss.ast.kind())
}
VariantDef::EnumVariant(e) => {
es = e.source(db);
(es.file_id, es.ast.kind())
}
};
let field_sources = match struct_kind {
ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(),
ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(),
ast::StructKind::Unit => Vec::new(),
};
let ast = field_sources
.into_iter()
.zip(fields.iter())
.find(|(_syntax, (id, _))| *id == self.id)
.unwrap()
.0;
Source { file_id, ast }
}
}

View file

@ -6,16 +6,17 @@ pub(crate) mod docs;
use std::sync::Arc;
use hir_def::{
adt::VariantData,
builtin_type::BuiltinType,
type_ref::{Mutability, TypeRef},
CrateModuleId, LocalEnumVariantId, ModuleId,
CrateModuleId, LocalEnumVariantId, LocalStructFieldId, ModuleId,
};
use hir_expand::name::{self, AsName};
use ra_db::{CrateId, Edition};
use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
use crate::{
adt::{StructFieldId, VariantDef},
adt::VariantDef,
db::{AstDatabase, DefDatabase, HirDatabase},
diagnostics::DiagnosticSink,
expr::{validation::ExprValidator, Body, BodySourceMap},
@ -250,7 +251,7 @@ impl Module {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StructField {
pub(crate) parent: VariantDef,
pub(crate) id: StructFieldId,
pub(crate) id: LocalStructFieldId,
}
#[derive(Debug, PartialEq, Eq)]
@ -288,11 +289,11 @@ impl Struct {
}
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.struct_data(self).name.clone()
db.struct_data(self.id).name.clone()
}
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
db.struct_data(self)
db.struct_data(self.id)
.variant_data
.fields()
.into_iter()
@ -302,7 +303,7 @@ impl Struct {
}
pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
db.struct_data(self)
db.struct_data(self.id)
.variant_data
.fields()
.into_iter()
@ -338,7 +339,7 @@ pub struct Union {
impl Union {
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.struct_data(Struct { id: self.id }).name.clone()
db.struct_data(self.id).name.clone()
}
pub fn module(self, db: &impl HirDatabase) -> Module {
@ -376,15 +377,19 @@ impl Enum {
}
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.enum_data(self).name.clone()
db.enum_data(self.id).name.clone()
}
pub fn variants(self, db: &impl DefDatabase) -> Vec<EnumVariant> {
db.enum_data(self).variants.iter().map(|(id, _)| EnumVariant { parent: self, id }).collect()
db.enum_data(self.id)
.variants
.iter()
.map(|(id, _)| EnumVariant { parent: self, id })
.collect()
}
pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
db.enum_data(self)
db.enum_data(self.id)
.variants
.iter()
.find(|(_id, data)| data.name.as_ref() == Some(name))
@ -422,7 +427,7 @@ impl EnumVariant {
}
pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.enum_data(self.parent).variants[self.id].name.clone()
db.enum_data(self.parent.id).variants[self.id].name.clone()
}
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
@ -442,6 +447,10 @@ impl EnumVariant {
.find(|(_id, data)| data.name == *name)
.map(|(id, _)| StructField { parent: self.into(), id })
}
pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
}
}
/// A Data Type

View file

@ -3,6 +3,7 @@
use ra_syntax::ast::{self, AstNode};
use crate::{
adt::VariantDef,
db::{AstDatabase, DefDatabase, HirDatabase},
ids::AstItemDef,
Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module,
@ -45,7 +46,33 @@ impl Module {
impl HasSource for StructField {
type Ast = FieldSource;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> {
self.source_impl(db)
let var_data = self.parent.variant_data(db);
let fields = var_data.fields().unwrap();
let ss;
let es;
let (file_id, struct_kind) = match self.parent {
VariantDef::Struct(s) => {
ss = s.source(db);
(ss.file_id, ss.ast.kind())
}
VariantDef::EnumVariant(e) => {
es = e.source(db);
(es.file_id, es.ast.kind())
}
};
let field_sources = match struct_kind {
ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(),
ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(),
ast::StructKind::Unit => Vec::new(),
};
let ast = field_sources
.into_iter()
.zip(fields.iter())
.find(|(_syntax, (id, _))| *id == self.id)
.unwrap()
.0;
Source { file_id, ast }
}
}
impl HasSource for Struct {
@ -69,7 +96,18 @@ impl HasSource for Enum {
impl HasSource for EnumVariant {
type Ast = ast::EnumVariant;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> {
self.source_impl(db)
let enum_data = db.enum_data(self.parent.id);
let src = self.parent.id.source(db);
let ast = src
.ast
.variant_list()
.into_iter()
.flat_map(|it| it.variants())
.zip(enum_data.variants.iter())
.find(|(_syntax, (id, _))| *id == self.id)
.unwrap()
.0;
Source { file_id: src.file_id, ast }
}
}
impl HasSource for Function {

View file

@ -6,7 +6,6 @@ use ra_db::salsa;
use ra_syntax::SmolStr;
use crate::{
adt::{EnumData, StructData},
debug::HirDebugDatabase,
generics::{GenericDef, GenericParams},
ids,
@ -19,13 +18,13 @@ use crate::{
InferenceResult, Substs, Ty, TypableDef, TypeCtor,
},
type_alias::TypeAliasData,
Const, ConstData, Crate, DefWithBody, Enum, ExprScopes, FnData, Function, Module, Static,
Struct, StructField, Trait, TypeAlias,
Const, ConstData, Crate, DefWithBody, ExprScopes, FnData, Function, Module, Static,
StructField, Trait, TypeAlias,
};
pub use hir_def::db::{
DefDatabase2, DefDatabase2Storage, InternDatabase, InternDatabaseStorage, RawItemsQuery,
RawItemsWithSourceMapQuery,
DefDatabase2, DefDatabase2Storage, EnumDataQuery, InternDatabase, InternDatabaseStorage,
RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery,
};
pub use hir_expand::db::{
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
@ -36,12 +35,6 @@ pub use hir_expand::db::{
#[salsa::query_group(DefDatabaseStorage)]
#[salsa::requires(AstDatabase)]
pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
#[salsa::invoke(crate::adt::StructData::struct_data_query)]
fn struct_data(&self, s: Struct) -> Arc<StructData>;
#[salsa::invoke(crate::adt::EnumData::enum_data_query)]
fn enum_data(&self, e: Enum) -> Arc<EnumData>;
#[salsa::invoke(crate::traits::TraitData::trait_data_query)]
fn trait_data(&self, t: Trait) -> Arc<TraitData>;

View file

@ -655,8 +655,8 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
}
fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
let var_data = def.variant_data(db);
let fields = match var_data.fields() {
let struct_data = db.struct_data(def.id);
let fields = match struct_data.variant_data.fields() {
Some(fields) => fields,
None => panic!("fn_sig_for_struct_constructor called on unit struct"),
};
@ -671,8 +671,8 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
/// 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);
if var_data.fields().is_none() {
let struct_data = db.struct_data(def.id);
if struct_data.variant_data.fields().is_none() {
return type_for_adt(db, def); // Unit struct
}
let generics = def.generic_params(db);

View file

@ -0,0 +1,114 @@
//! Defines hir-level representation of structs, enums and unions
use std::sync::Arc;
use hir_expand::name::{AsName, Name};
use ra_arena::Arena;
use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
use crate::{
db::DefDatabase2, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId,
LocalStructFieldId, StructId,
};
/// Note that we use `StructData` for unions as well!
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructData {
pub name: Option<Name>,
pub variant_data: Arc<VariantData>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumData {
pub name: Option<Name>,
pub variants: Arena<LocalEnumVariantId, EnumVariantData>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumVariantData {
pub name: Option<Name>,
pub variant_data: Arc<VariantData>,
}
/// Fields of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantData(VariantDataInner);
#[derive(Debug, Clone, PartialEq, Eq)]
enum VariantDataInner {
Struct(Arena<LocalStructFieldId, StructFieldData>),
Tuple(Arena<LocalStructFieldId, StructFieldData>),
Unit,
}
/// A single field of an enum variant or struct
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructFieldData {
pub name: Name,
pub type_ref: TypeRef,
}
impl StructData {
pub(crate) fn struct_data_query(db: &impl DefDatabase2, struct_: StructId) -> Arc<StructData> {
let src = struct_.source(db);
let name = src.ast.name().map(|n| n.as_name());
let variant_data = VariantData::new(src.ast.kind());
let variant_data = Arc::new(variant_data);
Arc::new(StructData { name, variant_data })
}
}
impl EnumData {
pub(crate) fn enum_data_query(db: &impl DefDatabase2, e: EnumId) -> Arc<EnumData> {
let src = e.source(db);
let name = src.ast.name().map(|n| n.as_name());
let variants = src
.ast
.variant_list()
.into_iter()
.flat_map(|it| it.variants())
.map(|var| EnumVariantData {
name: var.name().map(|it| it.as_name()),
variant_data: Arc::new(VariantData::new(var.kind())),
})
.collect();
Arc::new(EnumData { name, variants })
}
}
impl VariantData {
fn new(flavor: ast::StructKind) -> Self {
let inner = match flavor {
ast::StructKind::Tuple(fl) => {
let fields = fl
.fields()
.enumerate()
.map(|(i, fd)| StructFieldData {
name: Name::new_tuple_field(i),
type_ref: TypeRef::from_ast_opt(fd.type_ref()),
})
.collect();
VariantDataInner::Tuple(fields)
}
ast::StructKind::Named(fl) => {
let fields = fl
.fields()
.map(|fd| StructFieldData {
name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
})
.collect();
VariantDataInner::Struct(fields)
}
ast::StructKind::Unit => VariantDataInner::Unit,
};
VariantData(inner)
}
pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> {
match &self.0 {
VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields),
_ => None,
}
}
}

View file

@ -5,7 +5,11 @@ use hir_expand::{db::AstDatabase, HirFileId};
use ra_db::{salsa, SourceDatabase};
use ra_syntax::ast;
use crate::nameres::raw::{ImportSourceMap, RawItems};
use crate::{
adt::{EnumData, StructData},
nameres::raw::{ImportSourceMap, RawItems},
EnumId, StructId,
};
#[salsa::query_group(InternDatabaseStorage)]
pub trait InternDatabase: SourceDatabase {
@ -37,4 +41,10 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
#[salsa::invoke(RawItems::raw_items_query)]
fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
#[salsa::invoke(StructData::struct_data_query)]
fn struct_data(&self, s: StructId) -> Arc<StructData>;
#[salsa::invoke(EnumData::enum_data_query)]
fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
}

View file

@ -12,6 +12,7 @@ pub mod attr;
pub mod path;
pub mod type_ref;
pub mod builtin_type;
pub mod adt;
// FIXME: this should be private
pub mod nameres;
@ -259,6 +260,22 @@ pub struct EnumVariantId {
pub struct LocalEnumVariantId(RawId);
impl_arena_id!(LocalEnumVariantId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VariantId {
EnumVariantId(EnumVariantId),
StructId(StructId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StructFieldId {
parent: VariantId,
local_id: LocalStructFieldId,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LocalStructFieldId(RawId);
impl_arena_id!(LocalStructFieldId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConstId(salsa::InternId);
impl_intern_key!(ConstId);