Don't copy-paste impl_froms into every crate

This commit is contained in:
Aleksey Kladov 2020-07-13 16:16:53 +02:00
parent 6b4cf5b7d8
commit 693ac892f2
12 changed files with 69 additions and 106 deletions

2
Cargo.lock generated
View file

@ -1081,6 +1081,7 @@ dependencies = [
"ra_prof", "ra_prof",
"ra_syntax", "ra_syntax",
"rustc-hash", "rustc-hash",
"stdx",
] ]
[[package]] [[package]]
@ -1333,6 +1334,7 @@ name = "ra_tt"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"smol_str", "smol_str",
"stdx",
] ]
[[package]] [[package]]

View file

@ -15,6 +15,7 @@ arrayvec = "0.5.1"
itertools = "0.9.0" itertools = "0.9.0"
stdx = { path = "../stdx" }
ra_syntax = { path = "../ra_syntax" } ra_syntax = { path = "../ra_syntax" }
ra_db = { path = "../ra_db" } ra_db = { path = "../ra_db" }
ra_prof = { path = "../ra_prof" } ra_prof = { path = "../ra_prof" }

View file

@ -38,6 +38,7 @@ use ra_syntax::{
AstNode, AstNode,
}; };
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use stdx::impl_from;
use crate::{ use crate::{
db::{DefDatabase, HirDatabase}, db::{DefDatabase, HirDatabase},
@ -142,8 +143,8 @@ pub enum ModuleDef {
TypeAlias(TypeAlias), TypeAlias(TypeAlias),
BuiltinType(BuiltinType), BuiltinType(BuiltinType),
} }
impl_froms!( impl_from!(
ModuleDef: Module, Module,
Function, Function,
Adt(Struct, Enum, Union), Adt(Struct, Enum, Union),
EnumVariant, EnumVariant,
@ -152,6 +153,7 @@ impl_froms!(
Trait, Trait,
TypeAlias, TypeAlias,
BuiltinType BuiltinType
for ModuleDef
); );
impl ModuleDef { impl ModuleDef {
@ -541,7 +543,7 @@ pub enum Adt {
Union(Union), Union(Union),
Enum(Enum), Enum(Enum),
} }
impl_froms!(Adt: Struct, Union, Enum); impl_from!(Struct, Union, Enum for Adt);
impl Adt { impl Adt {
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
@ -584,7 +586,7 @@ pub enum VariantDef {
Union(Union), Union(Union),
EnumVariant(EnumVariant), EnumVariant(EnumVariant),
} }
impl_froms!(VariantDef: Struct, Union, EnumVariant); impl_from!(Struct, Union, EnumVariant for VariantDef);
impl VariantDef { impl VariantDef {
pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@ -627,8 +629,7 @@ pub enum DefWithBody {
Static(Static), Static(Static),
Const(Const), Const(Const),
} }
impl_from!(Function, Const, Static for DefWithBody);
impl_froms!(DefWithBody: Function, Const, Static);
impl DefWithBody { impl DefWithBody {
pub fn module(self, db: &dyn HirDatabase) -> Module { pub fn module(self, db: &dyn HirDatabase) -> Module {
@ -930,14 +931,15 @@ pub enum GenericDef {
// consts can have type parameters from their parents (i.e. associated consts of traits) // consts can have type parameters from their parents (i.e. associated consts of traits)
Const(Const), Const(Const),
} }
impl_froms!( impl_from!(
GenericDef: Function, Function,
Adt(Struct, Enum, Union), Adt(Struct, Enum, Union),
Trait, Trait,
TypeAlias, TypeAlias,
ImplDef, ImplDef,
EnumVariant, EnumVariant,
Const Const
for GenericDef
); );
impl GenericDef { impl GenericDef {
@ -1578,8 +1580,8 @@ pub enum AttrDef {
MacroDef(MacroDef), MacroDef(MacroDef),
} }
impl_froms!( impl_from!(
AttrDef: Module, Module,
Field, Field,
Adt(Struct, Enum, Union), Adt(Struct, Enum, Union),
EnumVariant, EnumVariant,
@ -1589,6 +1591,7 @@ impl_froms!(
Trait, Trait,
TypeAlias, TypeAlias,
MacroDef MacroDef
for AttrDef
); );
pub trait HasAttrs { pub trait HasAttrs {

View file

@ -19,25 +19,6 @@
#![recursion_limit = "512"] #![recursion_limit = "512"]
macro_rules! impl_froms {
($e:ident: $($v:ident $(($($sv:ident),*))?),*$(,)?) => {
$(
impl From<$v> for $e {
fn from(it: $v) -> $e {
$e::$v(it)
}
}
$($(
impl From<$sv> for $e {
fn from(it: $sv) -> $e {
$e::$v($v::$sv(it))
}
}
)*)?
)*
}
}
mod semantics; mod semantics;
pub mod db; pub mod db;
mod source_analyzer; mod source_analyzer;

View file

@ -16,6 +16,7 @@ use ra_syntax::{
match_ast, AstNode, SyntaxNode, match_ast, AstNode, SyntaxNode,
}; };
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use stdx::impl_from;
use crate::{db::HirDatabase, InFile, MacroDefId}; use crate::{db::HirDatabase, InFile, MacroDefId};
@ -255,8 +256,7 @@ pub(crate) enum ChildContainer {
/// here the children generic parameters, and not, eg enum variants. /// here the children generic parameters, and not, eg enum variants.
GenericDefId(GenericDefId), GenericDefId(GenericDefId),
} }
impl_froms! { impl_from! {
ChildContainer:
DefWithBodyId, DefWithBodyId,
ModuleId, ModuleId,
TraitId, TraitId,
@ -265,6 +265,7 @@ impl_froms! {
VariantId, VariantId,
TypeAliasId, TypeAliasId,
GenericDefId GenericDefId
for ChildContainer
} }
impl ChildContainer { impl ChildContainer {

View file

@ -65,6 +65,7 @@ use item_tree::{
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
TypeAlias, Union, TypeAlias, Union,
}; };
use stdx::impl_from;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ModuleId { pub struct ModuleId {
@ -223,25 +224,6 @@ pub struct TypeParamId {
pub type LocalTypeParamId = Idx<generics::TypeParamData>; pub type LocalTypeParamId = Idx<generics::TypeParamData>;
macro_rules! impl_froms {
($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
$(
impl From<$v> for $e {
fn from(it: $v) -> $e {
$e::$v(it)
}
}
$($(
impl From<$sv> for $e {
fn from(it: $sv) -> $e {
$e::$v($v::$sv(it))
}
}
)*)?
)*
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ContainerId { pub enum ContainerId {
ModuleId(ModuleId), ModuleId(ModuleId),
@ -254,7 +236,7 @@ pub enum AssocContainerId {
ImplId(ImplId), ImplId(ImplId),
TraitId(TraitId), TraitId(TraitId),
} }
impl_froms!(AssocContainerId: ContainerId); impl_from!(ContainerId for AssocContainerId);
/// A Data Type /// A Data Type
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@ -263,7 +245,7 @@ pub enum AdtId {
UnionId(UnionId), UnionId(UnionId),
EnumId(EnumId), EnumId(EnumId),
} }
impl_froms!(AdtId: StructId, UnionId, EnumId); impl_from!(StructId, UnionId, EnumId for AdtId);
/// The defs which can be visible in the module. /// The defs which can be visible in the module.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -279,8 +261,8 @@ pub enum ModuleDefId {
TypeAliasId(TypeAliasId), TypeAliasId(TypeAliasId),
BuiltinType(BuiltinType), BuiltinType(BuiltinType),
} }
impl_froms!( impl_from!(
ModuleDefId: ModuleId, ModuleId,
FunctionId, FunctionId,
AdtId(StructId, EnumId, UnionId), AdtId(StructId, EnumId, UnionId),
EnumVariantId, EnumVariantId,
@ -289,6 +271,7 @@ impl_froms!(
TraitId, TraitId,
TypeAliasId, TypeAliasId,
BuiltinType BuiltinType
for ModuleDefId
); );
/// The defs which have a body. /// The defs which have a body.
@ -299,7 +282,7 @@ pub enum DefWithBodyId {
ConstId(ConstId), ConstId(ConstId),
} }
impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum AssocItemId { pub enum AssocItemId {
@ -311,7 +294,7 @@ pub enum AssocItemId {
// sure that you can only turn actual assoc items into AssocItemIds. This would // sure that you can only turn actual assoc items into AssocItemIds. This would
// require not implementing From, and instead having some checked way of // require not implementing From, and instead having some checked way of
// casting them, and somehow making the constructors private, which would be annoying. // casting them, and somehow making the constructors private, which would be annoying.
impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum GenericDefId { pub enum GenericDefId {
@ -326,14 +309,15 @@ pub enum GenericDefId {
// consts can have type parameters from their parents (i.e. associated consts of traits) // consts can have type parameters from their parents (i.e. associated consts of traits)
ConstId(ConstId), ConstId(ConstId),
} }
impl_froms!( impl_from!(
GenericDefId: FunctionId, FunctionId,
AdtId(StructId, EnumId, UnionId), AdtId(StructId, EnumId, UnionId),
TraitId, TraitId,
TypeAliasId, TypeAliasId,
ImplId, ImplId,
EnumVariantId, EnumVariantId,
ConstId ConstId
for GenericDefId
); );
impl From<AssocItemId> for GenericDefId { impl From<AssocItemId> for GenericDefId {
@ -361,8 +345,8 @@ pub enum AttrDefId {
ImplId(ImplId), ImplId(ImplId),
} }
impl_froms!( impl_from!(
AttrDefId: ModuleId, ModuleId,
FieldId, FieldId,
AdtId(StructId, EnumId, UnionId), AdtId(StructId, EnumId, UnionId),
EnumVariantId, EnumVariantId,
@ -373,6 +357,7 @@ impl_froms!(
TypeAliasId, TypeAliasId,
MacroDefId, MacroDefId,
ImplId ImplId
for AttrDefId
); );
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -381,7 +366,7 @@ pub enum VariantId {
StructId(StructId), StructId(StructId),
UnionId(UnionId), UnionId(UnionId),
} }
impl_froms!(VariantId: EnumVariantId, StructId, UnionId); impl_from!(EnumVariantId, StructId, UnionId for VariantId);
trait Intern { trait Intern {
type ID; type ID;

View file

@ -18,8 +18,6 @@ use std::mem;
use std::ops::Index; use std::ops::Index;
use std::sync::Arc; use std::sync::Arc;
use rustc_hash::FxHashMap;
use hir_def::{ use hir_def::{
body::Body, body::Body,
data::{ConstData, FunctionData, StaticData}, data::{ConstData, FunctionData, StaticData},
@ -35,6 +33,8 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name};
use ra_arena::map::ArenaMap; use ra_arena::map::ArenaMap;
use ra_prof::profile; use ra_prof::profile;
use ra_syntax::SmolStr; use ra_syntax::SmolStr;
use rustc_hash::FxHashMap;
use stdx::impl_from;
use super::{ use super::{
primitive::{FloatTy, IntTy}, primitive::{FloatTy, IntTy},
@ -84,8 +84,7 @@ enum ExprOrPatId {
ExprId(ExprId), ExprId(ExprId),
PatId(PatId), PatId(PatId),
} }
impl_from!(ExprId, PatId for ExprOrPatId);
impl_froms!(ExprOrPatId: ExprId, PatId);
/// Binding modes inferred for patterns. /// Binding modes inferred for patterns.
/// https://doc.rust-lang.org/reference/patterns.html#binding-modes /// https://doc.rust-lang.org/reference/patterns.html#binding-modes

View file

@ -6,25 +6,6 @@ macro_rules! eprintln {
($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
} }
macro_rules! impl_froms {
($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
$(
impl From<$v> for $e {
fn from(it: $v) -> $e {
$e::$v(it)
}
}
$($(
impl From<$sv> for $e {
fn from(it: $sv) -> $e {
$e::$v($v::$sv(it))
}
}
)*)?
)*
}
}
mod autoderef; mod autoderef;
pub mod primitive; pub mod primitive;
pub mod traits; pub mod traits;

View file

@ -5,10 +5,7 @@
//! - Building the type for an item: This happens through the `type_for_def` query. //! - Building the type for an item: This happens through the `type_for_def` query.
//! //!
//! This usually involves resolving names, collecting generic arguments etc. //! This usually involves resolving names, collecting generic arguments etc.
use std::iter; use std::{iter, sync::Arc};
use std::sync::Arc;
use smallvec::SmallVec;
use hir_def::{ use hir_def::{
adt::StructKind, adt::StructKind,
@ -24,6 +21,8 @@ use hir_def::{
use hir_expand::name::Name; use hir_expand::name::Name;
use ra_arena::map::ArenaMap; use ra_arena::map::ArenaMap;
use ra_db::CrateId; use ra_db::CrateId;
use smallvec::SmallVec;
use stdx::impl_from;
use test_utils::mark; use test_utils::mark;
use crate::{ use crate::{
@ -1110,7 +1109,7 @@ pub enum CallableDef {
StructId(StructId), StructId(StructId),
EnumVariantId(EnumVariantId), EnumVariantId(EnumVariantId),
} }
impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); impl_from!(FunctionId, StructId, EnumVariantId for CallableDef);
impl CallableDef { impl CallableDef {
pub fn krate(self, db: &dyn HirDatabase) -> CrateId { pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
@ -1140,7 +1139,7 @@ pub enum TyDefId {
AdtId(AdtId), AdtId(AdtId),
TypeAliasId(TypeAliasId), TypeAliasId(TypeAliasId),
} }
impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ValueTyDefId { pub enum ValueTyDefId {
@ -1150,7 +1149,7 @@ pub enum ValueTyDefId {
ConstId(ConstId), ConstId(ConstId),
StaticId(StaticId), StaticId(StaticId),
} }
impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); impl_from!(FunctionId, StructId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
/// Build the declared type of an item. This depends on the namespace; e.g. for /// Build the declared type of an item. This depends on the namespace; e.g. for
/// `struct Foo(usize)`, we have two types: The type of the struct itself, and /// `struct Foo(usize)`, we have two types: The type of the struct itself, and

View file

@ -8,6 +8,7 @@ authors = ["rust-analyzer developers"]
doctest = false doctest = false
[dependencies] [dependencies]
stdx = { path = "../stdx" }
# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here # ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here
# to reduce number of compilations # to reduce number of compilations
smol_str = { version = "0.1.15", features = ["serde"] } smol_str = { version = "0.1.15", features = ["serde"] }

View file

@ -1,24 +1,13 @@
//! `tt` crate defines a `TokenTree` data structure: this is the interface (both //! `tt` crate defines a `TokenTree` data structure: this is the interface (both
//! input and output) of macros. It closely mirrors `proc_macro` crate's //! input and output) of macros. It closely mirrors `proc_macro` crate's
//! `TokenTree`. //! `TokenTree`.
macro_rules! impl_froms {
($e:ident: $($v:ident), *) => {
$(
impl From<$v> for $e {
fn from(it: $v) -> $e {
$e::$v(it)
}
}
)*
}
}
use std::{ use std::{
fmt::{self, Debug}, fmt::{self, Debug},
panic::RefUnwindSafe, panic::RefUnwindSafe,
}; };
use stdx::impl_from;
pub use smol_str::SmolStr; pub use smol_str::SmolStr;
/// Represents identity of the token. /// Represents identity of the token.
@ -41,7 +30,7 @@ pub enum TokenTree {
Leaf(Leaf), Leaf(Leaf),
Subtree(Subtree), Subtree(Subtree),
} }
impl_froms!(TokenTree: Leaf, Subtree); impl_from!(Leaf, Subtree for TokenTree);
impl TokenTree { impl TokenTree {
pub fn empty() -> Self { pub fn empty() -> Self {
@ -55,7 +44,7 @@ pub enum Leaf {
Punct(Punct), Punct(Punct),
Ident(Ident), Ident(Ident),
} }
impl_froms!(Leaf: Literal, Punct, Ident); impl_from!(Literal, Punct, Ident for Leaf);
#[derive(Clone, PartialEq, Eq, Hash, Default)] #[derive(Clone, PartialEq, Eq, Hash, Default)]
pub struct Subtree { pub struct Subtree {

View file

@ -17,3 +17,24 @@ macro_rules! format_to {
{ use ::std::fmt::Write as _; let _ = ::std::write!($buf, $lit $($arg)*); } { use ::std::fmt::Write as _; let _ = ::std::write!($buf, $lit $($arg)*); }
}; };
} }
// Generates `From` impls for `Enum E { Foo(Foo), Bar(Bar) }` enums
#[macro_export]
macro_rules! impl_from {
($($variant:ident $(($($sub_variant:ident),*))?),* for $enum:ident) => {
$(
impl From<$variant> for $enum {
fn from(it: $variant) -> $enum {
$enum::$variant(it)
}
}
$($(
impl From<$sub_variant> for $enum {
fn from(it: $sub_variant) -> $enum {
$enum::$variant($variant::$sub_variant(it))
}
}
)*)?
)*
}
}