mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
add union to code_model
This commit is contained in:
parent
eef24bddc9
commit
5d54aa6781
@ -10,7 +10,7 @@ use ra_syntax::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
Name, AsName, Struct, Enum, EnumVariant, Crate,
|
||||
Name, AsName, Struct, Union, Enum, EnumVariant, Crate,
|
||||
HirDatabase, HirFileId, StructField, FieldSource,
|
||||
type_ref::TypeRef, DefDatabase,
|
||||
};
|
||||
@ -18,14 +18,16 @@ use crate::{
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum AdtDef {
|
||||
Struct(Struct),
|
||||
Union(Union),
|
||||
Enum(Enum),
|
||||
}
|
||||
impl_froms!(AdtDef: Struct, Enum);
|
||||
impl_froms!(AdtDef: Struct, Union, Enum);
|
||||
|
||||
impl AdtDef {
|
||||
pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
|
||||
match self {
|
||||
AdtDef::Struct(s) => s.module(db),
|
||||
AdtDef::Union(s) => s.module(db),
|
||||
AdtDef::Enum(e) => e.module(db),
|
||||
}
|
||||
.krate(db)
|
||||
@ -38,6 +40,7 @@ impl Struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// Note that we use `StructData` for unions as well!
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct StructData {
|
||||
pub(crate) name: Option<Name>,
|
||||
|
@ -71,6 +71,7 @@ pub enum ModuleDef {
|
||||
Module(Module),
|
||||
Function(Function),
|
||||
Struct(Struct),
|
||||
Union(Union),
|
||||
Enum(Enum),
|
||||
// Can't be directly declared, but can be imported.
|
||||
EnumVariant(EnumVariant),
|
||||
@ -83,6 +84,7 @@ impl_froms!(
|
||||
ModuleDef: Module,
|
||||
Function,
|
||||
Struct,
|
||||
Union,
|
||||
Enum,
|
||||
EnumVariant,
|
||||
Const,
|
||||
@ -325,6 +327,42 @@ impl Docs for Struct {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Union {
|
||||
pub(crate) id: StructId,
|
||||
}
|
||||
|
||||
impl Union {
|
||||
pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
|
||||
self.id.source(db)
|
||||
}
|
||||
|
||||
pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
|
||||
db.struct_data(Struct { id: self.id }).name.clone()
|
||||
}
|
||||
|
||||
pub fn module(&self, db: &impl HirDatabase) -> Module {
|
||||
self.id.module(db)
|
||||
}
|
||||
|
||||
// FIXME move to a more general type
|
||||
/// Builds a resolver for type references inside this union.
|
||||
pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||
// take the outer scope...
|
||||
let r = self.module(db).resolver(db);
|
||||
// ...and add generic params, if present
|
||||
let p = self.generic_params(db);
|
||||
let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl Docs for Union {
|
||||
fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
|
||||
docs_from_ast(&*self.source(db).1)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Enum {
|
||||
pub(crate) id: EnumId,
|
||||
|
@ -9,7 +9,7 @@ use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner, DefaultT
|
||||
|
||||
use crate::{
|
||||
db::{ HirDatabase, DefDatabase},
|
||||
Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
|
||||
Name, AsName, Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock, Container, path::Path, type_ref::TypeRef, AdtDef
|
||||
};
|
||||
|
||||
/// Data about a generic parameter (to a function, struct, impl, ...).
|
||||
@ -42,12 +42,13 @@ pub struct WherePredicate {
|
||||
pub enum GenericDef {
|
||||
Function(Function),
|
||||
Struct(Struct),
|
||||
Union(Union),
|
||||
Enum(Enum),
|
||||
Trait(Trait),
|
||||
TypeAlias(TypeAlias),
|
||||
ImplBlock(ImplBlock),
|
||||
}
|
||||
impl_froms!(GenericDef: Function, Struct, Enum, Trait, TypeAlias, ImplBlock);
|
||||
impl_froms!(GenericDef: Function, Struct, Union, Enum, Trait, TypeAlias, ImplBlock);
|
||||
|
||||
impl GenericParams {
|
||||
pub(crate) fn generic_params_query(
|
||||
@ -58,7 +59,10 @@ impl GenericParams {
|
||||
let parent = match def {
|
||||
GenericDef::Function(it) => it.container(db).map(GenericDef::from),
|
||||
GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
|
||||
GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None,
|
||||
GenericDef::Struct(_)
|
||||
| GenericDef::Union(_)
|
||||
| GenericDef::Enum(_)
|
||||
| GenericDef::Trait(_) => None,
|
||||
GenericDef::ImplBlock(_) => None,
|
||||
};
|
||||
generics.parent_params = parent.map(|p| db.generic_params(p));
|
||||
@ -66,6 +70,7 @@ impl GenericParams {
|
||||
match def {
|
||||
GenericDef::Function(it) => generics.fill(&*it.source(db).1, start),
|
||||
GenericDef::Struct(it) => generics.fill(&*it.source(db).1, start),
|
||||
GenericDef::Union(it) => generics.fill(&*it.source(db).1, start),
|
||||
GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start),
|
||||
GenericDef::Trait(it) => {
|
||||
// traits get the Self type as an implicit first type parameter
|
||||
@ -171,6 +176,7 @@ impl GenericDef {
|
||||
match self {
|
||||
GenericDef::Function(inner) => inner.resolver(db),
|
||||
GenericDef::Struct(inner) => inner.resolver(db),
|
||||
GenericDef::Union(inner) => inner.resolver(db),
|
||||
GenericDef::Enum(inner) => inner.resolver(db),
|
||||
GenericDef::Trait(inner) => inner.resolver(db),
|
||||
GenericDef::TypeAlias(inner) => inner.resolver(db),
|
||||
@ -192,6 +198,7 @@ impl From<crate::adt::AdtDef> for GenericDef {
|
||||
fn from(adt: crate::adt::AdtDef) -> Self {
|
||||
match adt {
|
||||
AdtDef::Struct(s) => s.into(),
|
||||
AdtDef::Union(u) => u.into(),
|
||||
AdtDef::Enum(e) => e.into(),
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ pub use self::code_model_api::{
|
||||
Crate, CrateDependency,
|
||||
DefWithBody,
|
||||
Module, ModuleDef, ModuleSource,
|
||||
Struct, Enum, EnumVariant,
|
||||
Struct, Union, Enum, EnumVariant,
|
||||
Function, FnSignature,
|
||||
StructField, FieldSource,
|
||||
Static, Const, ConstSignature,
|
||||
|
@ -6,7 +6,7 @@ use ra_db::FileId;
|
||||
use ra_syntax::ast;
|
||||
|
||||
use crate::{
|
||||
Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
|
||||
Function, Module, Struct, Union, Enum, Const, Static, Trait, TypeAlias,
|
||||
DefDatabase, HirFileId, Name, Path,
|
||||
KnownName,
|
||||
nameres::{
|
||||
@ -495,6 +495,10 @@ where
|
||||
let s = def!(Struct, ast_id);
|
||||
PerNs::both(s, s)
|
||||
}
|
||||
raw::DefKind::Union(ast_id) => {
|
||||
let s = def!(Union, ast_id);
|
||||
PerNs::both(s, s)
|
||||
}
|
||||
raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)),
|
||||
raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)),
|
||||
raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)),
|
||||
|
@ -1,7 +1,4 @@
|
||||
use std::{
|
||||
sync::Arc,
|
||||
ops::Index,
|
||||
};
|
||||
use std::{sync::Arc, ops::Index};
|
||||
|
||||
use test_utils::tested_by;
|
||||
use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap};
|
||||
@ -10,10 +7,7 @@ use ra_syntax::{
|
||||
ast::{self, NameOwner, AttrsOwner},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
DefDatabase, Name, AsName, Path, HirFileId, ModuleSource,
|
||||
AstIdMap, FileAstId, Either,
|
||||
};
|
||||
use crate::{DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, AstIdMap, FileAstId, Either};
|
||||
|
||||
/// `RawItems` is a set of top-level items in a file (except for impls).
|
||||
///
|
||||
@ -161,6 +155,7 @@ pub(super) struct DefData {
|
||||
pub(super) enum DefKind {
|
||||
Function(FileAstId<ast::FnDef>),
|
||||
Struct(FileAstId<ast::StructDef>),
|
||||
Union(FileAstId<ast::StructDef>),
|
||||
Enum(FileAstId<ast::EnumDef>),
|
||||
Const(FileAstId<ast::ConstDef>),
|
||||
Static(FileAstId<ast::StaticDef>),
|
||||
@ -215,7 +210,13 @@ impl RawItemsCollector {
|
||||
return;
|
||||
}
|
||||
ast::ModuleItemKind::StructDef(it) => {
|
||||
(DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name())
|
||||
let id = self.source_ast_id_map.ast_id(it);
|
||||
let name = it.name();
|
||||
if it.is_union() {
|
||||
(DefKind::Union(id), name)
|
||||
} else {
|
||||
(DefKind::Struct(id), name)
|
||||
}
|
||||
}
|
||||
ast::ModuleItemKind::EnumDef(it) => {
|
||||
(DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name())
|
||||
|
@ -536,6 +536,7 @@ impl HirDisplay for ApplicationTy {
|
||||
TypeCtor::Adt(def_id) => {
|
||||
let name = match def_id {
|
||||
AdtDef::Struct(s) => s.name(f.db),
|
||||
AdtDef::Union(u) => u.name(f.db),
|
||||
AdtDef::Enum(e) => e.name(f.db),
|
||||
}
|
||||
.unwrap_or_else(Name::missing);
|
||||
|
@ -27,13 +27,13 @@ use ra_prof::profile;
|
||||
use test_utils::tested_by;
|
||||
|
||||
use crate::{
|
||||
Function, StructField, Path, Name,
|
||||
FnSignature, AdtDef,ConstSignature,
|
||||
HirDatabase,
|
||||
DefWithBody,
|
||||
ImplItem,
|
||||
Function, StructField, Path, Name, FnSignature, AdtDef, ConstSignature, HirDatabase,
|
||||
DefWithBody, ImplItem,
|
||||
type_ref::{TypeRef, Mutability},
|
||||
expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self},
|
||||
expr::{
|
||||
Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement,
|
||||
FieldPat, Array, self,
|
||||
},
|
||||
generics::{GenericParams, HasGenericParams},
|
||||
path::{GenericArgs, GenericArg},
|
||||
ModuleDef,
|
||||
@ -644,7 +644,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
let ty = self.insert_type_vars(ty.apply_substs(substs));
|
||||
(ty, Some(var.into()))
|
||||
}
|
||||
TypableDef::TypeAlias(_)
|
||||
TypableDef::Union(_)
|
||||
| TypableDef::TypeAlias(_)
|
||||
| TypableDef::Function(_)
|
||||
| TypableDef::Enum(_)
|
||||
| TypableDef::Const(_)
|
||||
@ -1407,7 +1408,11 @@ impl Expectation {
|
||||
}
|
||||
|
||||
mod diagnostics {
|
||||
use crate::{expr::ExprId, diagnostics::{DiagnosticSink, NoSuchField}, HirDatabase, Function};
|
||||
use crate::{
|
||||
expr::ExprId,
|
||||
diagnostics::{DiagnosticSink, NoSuchField},
|
||||
HirDatabase, Function,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub(super) enum InferenceDiagnostic {
|
||||
|
@ -9,7 +9,7 @@ use std::sync::Arc;
|
||||
use std::iter;
|
||||
|
||||
use crate::{
|
||||
Function, Struct, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
|
||||
Function, Struct, Union, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
|
||||
HirDatabase,
|
||||
type_ref::TypeRef,
|
||||
name::KnownName,
|
||||
@ -124,6 +124,7 @@ impl Ty {
|
||||
let def_generic: Option<GenericDef> = match resolved {
|
||||
TypableDef::Function(func) => Some(func.into()),
|
||||
TypableDef::Struct(s) => Some(s.into()),
|
||||
TypableDef::Union(u) => Some(u.into()),
|
||||
TypableDef::Enum(e) => Some(e.into()),
|
||||
TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()),
|
||||
TypableDef::TypeAlias(t) => Some(t.into()),
|
||||
@ -144,6 +145,7 @@ impl Ty {
|
||||
let segment = match resolved {
|
||||
TypableDef::Function(_)
|
||||
| TypableDef::Struct(_)
|
||||
| TypableDef::Union(_)
|
||||
| TypableDef::Enum(_)
|
||||
| TypableDef::Const(_)
|
||||
| TypableDef::Static(_)
|
||||
@ -293,12 +295,14 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
|
||||
(TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
|
||||
(TypableDef::Enum(e), Namespace::Types) => type_for_adt(db, e),
|
||||
(TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v),
|
||||
(TypableDef::Union(u), Namespace::Types) => type_for_adt(db, u),
|
||||
(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,
|
||||
(TypableDef::Union(_), Namespace::Values) => Ty::Unknown,
|
||||
(TypableDef::Enum(_), Namespace::Values) => Ty::Unknown,
|
||||
(TypableDef::EnumVariant(_), Namespace::Types) => Ty::Unknown,
|
||||
(TypableDef::TypeAlias(_), Namespace::Values) => Ty::Unknown,
|
||||
@ -467,19 +471,21 @@ fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
|
||||
pub enum TypableDef {
|
||||
Function(Function),
|
||||
Struct(Struct),
|
||||
Union(Union),
|
||||
Enum(Enum),
|
||||
EnumVariant(EnumVariant),
|
||||
TypeAlias(TypeAlias),
|
||||
Const(Const),
|
||||
Static(Static),
|
||||
}
|
||||
impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant, TypeAlias, Const, Static);
|
||||
impl_froms!(TypableDef: Function, Struct, Union, Enum, EnumVariant, TypeAlias, Const, Static);
|
||||
|
||||
impl From<ModuleDef> for Option<TypableDef> {
|
||||
fn from(def: ModuleDef) -> Option<TypableDef> {
|
||||
let res = match def {
|
||||
ModuleDef::Function(f) => f.into(),
|
||||
ModuleDef::Struct(s) => s.into(),
|
||||
ModuleDef::Union(u) => u.into(),
|
||||
ModuleDef::Enum(e) => e.into(),
|
||||
ModuleDef::EnumVariant(v) => v.into(),
|
||||
ModuleDef::TypeAlias(t) => t.into(),
|
||||
|
@ -20,6 +20,7 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon
|
||||
}
|
||||
|
||||
// FIXME unions
|
||||
AdtDef::Union(_) => (),
|
||||
AdtDef::Enum(_) => (),
|
||||
};
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ impl Completions {
|
||||
return self.add_function_with_name(ctx, Some(local_name), *func);
|
||||
}
|
||||
Resolution::Def(Struct(it)) => (CompletionItemKind::Struct, it.docs(ctx.db)),
|
||||
Resolution::Def(Union(it)) => (CompletionItemKind::Struct, it.docs(ctx.db)),
|
||||
Resolution::Def(Enum(it)) => (CompletionItemKind::Enum, it.docs(ctx.db)),
|
||||
Resolution::Def(EnumVariant(it)) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
|
||||
Resolution::Def(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)),
|
||||
|
@ -154,6 +154,10 @@ impl NavigationTarget {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
}
|
||||
hir::AdtDef::Union(s) => {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
}
|
||||
hir::AdtDef::Enum(s) => {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
@ -169,6 +173,10 @@ impl NavigationTarget {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
}
|
||||
hir::ModuleDef::Union(s) => {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
}
|
||||
hir::ModuleDef::Const(s) => {
|
||||
let (file_id, node) = s.source(db);
|
||||
NavigationTarget::from_named(file_id.original_file(db), &*node)
|
||||
|
@ -57,6 +57,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
|
||||
Some(Def(ModuleDef::Module(_))) => "module",
|
||||
Some(Def(ModuleDef::Function(_))) => "function",
|
||||
Some(Def(ModuleDef::Struct(_))) => "type",
|
||||
Some(Def(ModuleDef::Union(_))) => "type",
|
||||
Some(Def(ModuleDef::Enum(_))) => "type",
|
||||
Some(Def(ModuleDef::EnumVariant(_))) => "constant",
|
||||
Some(Def(ModuleDef::Const(_))) => "constant",
|
||||
|
Loading…
Reference in New Issue
Block a user