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_syntax",
"rustc-hash",
"stdx",
]
[[package]]
@ -1333,6 +1334,7 @@ name = "ra_tt"
version = "0.1.0"
dependencies = [
"smol_str",
"stdx",
]
[[package]]

View file

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

View file

@ -38,6 +38,7 @@ use ra_syntax::{
AstNode,
};
use rustc_hash::FxHashSet;
use stdx::impl_from;
use crate::{
db::{DefDatabase, HirDatabase},
@ -142,8 +143,8 @@ pub enum ModuleDef {
TypeAlias(TypeAlias),
BuiltinType(BuiltinType),
}
impl_froms!(
ModuleDef: Module,
impl_from!(
Module,
Function,
Adt(Struct, Enum, Union),
EnumVariant,
@ -152,6 +153,7 @@ impl_froms!(
Trait,
TypeAlias,
BuiltinType
for ModuleDef
);
impl ModuleDef {
@ -541,7 +543,7 @@ pub enum Adt {
Union(Union),
Enum(Enum),
}
impl_froms!(Adt: Struct, Union, Enum);
impl_from!(Struct, Union, Enum for Adt);
impl Adt {
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
@ -584,7 +586,7 @@ pub enum VariantDef {
Union(Union),
EnumVariant(EnumVariant),
}
impl_froms!(VariantDef: Struct, Union, EnumVariant);
impl_from!(Struct, Union, EnumVariant for VariantDef);
impl VariantDef {
pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@ -627,8 +629,7 @@ pub enum DefWithBody {
Static(Static),
Const(Const),
}
impl_froms!(DefWithBody: Function, Const, Static);
impl_from!(Function, Const, Static for DefWithBody);
impl DefWithBody {
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)
Const(Const),
}
impl_froms!(
GenericDef: Function,
impl_from!(
Function,
Adt(Struct, Enum, Union),
Trait,
TypeAlias,
ImplDef,
EnumVariant,
Const
for GenericDef
);
impl GenericDef {
@ -1578,8 +1580,8 @@ pub enum AttrDef {
MacroDef(MacroDef),
}
impl_froms!(
AttrDef: Module,
impl_from!(
Module,
Field,
Adt(Struct, Enum, Union),
EnumVariant,
@ -1589,6 +1591,7 @@ impl_froms!(
Trait,
TypeAlias,
MacroDef
for AttrDef
);
pub trait HasAttrs {

View file

@ -19,25 +19,6 @@
#![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;
pub mod db;
mod source_analyzer;

View file

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

View file

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

View file

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

View file

@ -6,25 +6,6 @@ macro_rules! eprintln {
($($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;
pub mod primitive;
pub mod traits;

View file

@ -5,10 +5,7 @@
//! - Building the type for an item: This happens through the `type_for_def` query.
//!
//! This usually involves resolving names, collecting generic arguments etc.
use std::iter;
use std::sync::Arc;
use smallvec::SmallVec;
use std::{iter, sync::Arc};
use hir_def::{
adt::StructKind,
@ -24,6 +21,8 @@ use hir_def::{
use hir_expand::name::Name;
use ra_arena::map::ArenaMap;
use ra_db::CrateId;
use smallvec::SmallVec;
use stdx::impl_from;
use test_utils::mark;
use crate::{
@ -1110,7 +1109,7 @@ pub enum CallableDef {
StructId(StructId),
EnumVariantId(EnumVariantId),
}
impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId);
impl_from!(FunctionId, StructId, EnumVariantId for CallableDef);
impl CallableDef {
pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
@ -1140,7 +1139,7 @@ pub enum TyDefId {
AdtId(AdtId),
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)]
pub enum ValueTyDefId {
@ -1150,7 +1149,7 @@ pub enum ValueTyDefId {
ConstId(ConstId),
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
/// `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
[dependencies]
stdx = { path = "../stdx" }
# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here
# to reduce number of compilations
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
//! input and output) of macros. It closely mirrors `proc_macro` crate's
//! `TokenTree`.
macro_rules! impl_froms {
($e:ident: $($v:ident), *) => {
$(
impl From<$v> for $e {
fn from(it: $v) -> $e {
$e::$v(it)
}
}
)*
}
}
use std::{
fmt::{self, Debug},
panic::RefUnwindSafe,
};
use stdx::impl_from;
pub use smol_str::SmolStr;
/// Represents identity of the token.
@ -41,7 +30,7 @@ pub enum TokenTree {
Leaf(Leaf),
Subtree(Subtree),
}
impl_froms!(TokenTree: Leaf, Subtree);
impl_from!(Leaf, Subtree for TokenTree);
impl TokenTree {
pub fn empty() -> Self {
@ -55,7 +44,7 @@ pub enum Leaf {
Punct(Punct),
Ident(Ident),
}
impl_froms!(Leaf: Literal, Punct, Ident);
impl_from!(Literal, Punct, Ident for Leaf);
#[derive(Clone, PartialEq, Eq, Hash, Default)]
pub struct Subtree {

View file

@ -17,3 +17,24 @@ macro_rules! format_to {
{ 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))
}
}
)*)?
)*
}
}