mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 09:48:10 +00:00
Merge #1291
1291: add is_union to structs AST r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
4369c1c4a1
3 changed files with 33 additions and 21 deletions
|
@ -197,13 +197,13 @@ impl From<crate::adt::AdtDef> for GenericDef {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait HasGenericParams {
|
||||
pub trait HasGenericParams: Copy {
|
||||
fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>;
|
||||
}
|
||||
|
||||
impl<T> HasGenericParams for T
|
||||
where
|
||||
T: Into<GenericDef>,
|
||||
T: Into<GenericDef> + Copy,
|
||||
{
|
||||
fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> {
|
||||
db.generic_params(self.into())
|
||||
|
|
|
@ -9,9 +9,7 @@ use std::sync::Arc;
|
|||
use std::iter;
|
||||
|
||||
use crate::{
|
||||
Function, Struct, StructField, Enum, EnumVariant, Path,
|
||||
ModuleDef, TypeAlias,
|
||||
Const, Static,
|
||||
Function, Struct, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static,
|
||||
HirDatabase,
|
||||
type_ref::TypeRef,
|
||||
name::KnownName,
|
||||
|
@ -19,7 +17,10 @@ use crate::{
|
|||
resolve::{Resolver, Resolution},
|
||||
path::{PathSegment, GenericArg},
|
||||
generics::{HasGenericParams},
|
||||
adt::VariantDef, Trait, generics::{ WherePredicate, GenericDef}
|
||||
adt::VariantDef,
|
||||
Trait,
|
||||
generics::{WherePredicate, GenericDef},
|
||||
ty::AdtDef,
|
||||
};
|
||||
use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate};
|
||||
|
||||
|
@ -288,9 +289,9 @@ impl TraitRef {
|
|||
pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty {
|
||||
match (def, ns) {
|
||||
(TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f),
|
||||
(TypableDef::Struct(s), Namespace::Types) => type_for_struct(db, s),
|
||||
(TypableDef::Struct(s), Namespace::Types) => type_for_adt(db, s),
|
||||
(TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s),
|
||||
(TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e),
|
||||
(TypableDef::Enum(e), Namespace::Types) => type_for_adt(db, e),
|
||||
(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),
|
||||
|
@ -405,7 +406,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
|
|||
.iter()
|
||||
.map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
|
||||
.collect::<Vec<_>>();
|
||||
let ret = type_for_struct(db, def);
|
||||
let ret = type_for_adt(db, def);
|
||||
FnSig::from_params_and_return(params, ret)
|
||||
}
|
||||
|
||||
|
@ -413,7 +414,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
|
|||
fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
|
||||
let var_data = def.variant_data(db);
|
||||
if var_data.fields().is_none() {
|
||||
return type_for_struct(db, def); // Unit struct
|
||||
return type_for_adt(db, def); // Unit struct
|
||||
}
|
||||
let generics = def.generic_params(db);
|
||||
let substs = Substs::identity(&generics);
|
||||
|
@ -433,7 +434,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
|
|||
.collect::<Vec<_>>();
|
||||
let generics = def.parent_enum(db).generic_params(db);
|
||||
let substs = Substs::identity(&generics);
|
||||
let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs);
|
||||
let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs);
|
||||
FnSig::from_params_and_return(params, ret)
|
||||
}
|
||||
|
||||
|
@ -441,21 +442,16 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
|
|||
fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
|
||||
let var_data = def.variant_data(db);
|
||||
if var_data.fields().is_none() {
|
||||
return type_for_enum(db, def.parent_enum(db)); // Unit variant
|
||||
return type_for_adt(db, def.parent_enum(db)); // Unit variant
|
||||
}
|
||||
let generics = def.parent_enum(db).generic_params(db);
|
||||
let substs = Substs::identity(&generics);
|
||||
Ty::apply(TypeCtor::FnDef(def.into()), substs)
|
||||
}
|
||||
|
||||
fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
|
||||
let generics = s.generic_params(db);
|
||||
Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics))
|
||||
}
|
||||
|
||||
fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
|
||||
let generics = s.generic_params(db);
|
||||
Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics))
|
||||
fn type_for_adt(db: &impl HirDatabase, adt: impl Into<AdtDef> + HasGenericParams) -> Ty {
|
||||
let generics = adt.generic_params(db);
|
||||
Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics))
|
||||
}
|
||||
|
||||
fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{SmolStr, SyntaxToken, ast::{self, AstNode, children, child_opt}, SyntaxKind::*, SyntaxElement, T};
|
||||
use crate::{
|
||||
SmolStr, SyntaxToken,
|
||||
ast::{self, AstNode, children, child_opt},
|
||||
SyntaxKind::*,
|
||||
SyntaxElement, T,
|
||||
};
|
||||
use ra_parser::SyntaxKind;
|
||||
|
||||
impl ast::Name {
|
||||
|
@ -196,6 +201,17 @@ impl StructKind<'_> {
|
|||
}
|
||||
|
||||
impl ast::StructDef {
|
||||
pub fn is_union(&self) -> bool {
|
||||
for child in self.syntax().children_with_tokens() {
|
||||
match child.kind() {
|
||||
T![struct] => return false,
|
||||
T![union] => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> StructKind {
|
||||
StructKind::from_node(self)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue