aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs23
-rw-r--r--crates/ra_hir/src/lib.rs19
-rw-r--r--crates/ra_hir/src/semantics/source_to_def.rs5
-rw-r--r--crates/ra_hir_def/src/lib.rs45
-rw-r--r--crates/ra_hir_ty/src/infer.rs7
-rw-r--r--crates/ra_hir_ty/src/lib.rs19
-rw-r--r--crates/ra_hir_ty/src/lower.rs13
-rw-r--r--crates/ra_tt/Cargo.toml1
-rw-r--r--crates/ra_tt/src/lib.rs19
-rw-r--r--crates/stdx/src/macros.rs21
11 files changed, 67 insertions, 106 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index ba7b39a19..512676c99 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -15,6 +15,7 @@ arrayvec = "0.5.1"
15 15
16itertools = "0.9.0" 16itertools = "0.9.0"
17 17
18stdx = { path = "../stdx" }
18ra_syntax = { path = "../ra_syntax" } 19ra_syntax = { path = "../ra_syntax" }
19ra_db = { path = "../ra_db" } 20ra_db = { path = "../ra_db" }
20ra_prof = { path = "../ra_prof" } 21ra_prof = { path = "../ra_prof" }
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 04fd335fe..9222009fe 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -38,6 +38,7 @@ use ra_syntax::{
38 AstNode, 38 AstNode,
39}; 39};
40use rustc_hash::FxHashSet; 40use rustc_hash::FxHashSet;
41use stdx::impl_from;
41 42
42use crate::{ 43use crate::{
43 db::{DefDatabase, HirDatabase}, 44 db::{DefDatabase, HirDatabase},
@@ -142,8 +143,8 @@ pub enum ModuleDef {
142 TypeAlias(TypeAlias), 143 TypeAlias(TypeAlias),
143 BuiltinType(BuiltinType), 144 BuiltinType(BuiltinType),
144} 145}
145impl_froms!( 146impl_from!(
146 ModuleDef: Module, 147 Module,
147 Function, 148 Function,
148 Adt(Struct, Enum, Union), 149 Adt(Struct, Enum, Union),
149 EnumVariant, 150 EnumVariant,
@@ -152,6 +153,7 @@ impl_froms!(
152 Trait, 153 Trait,
153 TypeAlias, 154 TypeAlias,
154 BuiltinType 155 BuiltinType
156 for ModuleDef
155); 157);
156 158
157impl ModuleDef { 159impl ModuleDef {
@@ -541,7 +543,7 @@ pub enum Adt {
541 Union(Union), 543 Union(Union),
542 Enum(Enum), 544 Enum(Enum),
543} 545}
544impl_froms!(Adt: Struct, Union, Enum); 546impl_from!(Struct, Union, Enum for Adt);
545 547
546impl Adt { 548impl Adt {
547 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 549 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
@@ -584,7 +586,7 @@ pub enum VariantDef {
584 Union(Union), 586 Union(Union),
585 EnumVariant(EnumVariant), 587 EnumVariant(EnumVariant),
586} 588}
587impl_froms!(VariantDef: Struct, Union, EnumVariant); 589impl_from!(Struct, Union, EnumVariant for VariantDef);
588 590
589impl VariantDef { 591impl VariantDef {
590 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { 592 pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@@ -627,8 +629,7 @@ pub enum DefWithBody {
627 Static(Static), 629 Static(Static),
628 Const(Const), 630 Const(Const),
629} 631}
630 632impl_from!(Function, Const, Static for DefWithBody);
631impl_froms!(DefWithBody: Function, Const, Static);
632 633
633impl DefWithBody { 634impl DefWithBody {
634 pub fn module(self, db: &dyn HirDatabase) -> Module { 635 pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -930,14 +931,15 @@ pub enum GenericDef {
930 // consts can have type parameters from their parents (i.e. associated consts of traits) 931 // consts can have type parameters from their parents (i.e. associated consts of traits)
931 Const(Const), 932 Const(Const),
932} 933}
933impl_froms!( 934impl_from!(
934 GenericDef: Function, 935 Function,
935 Adt(Struct, Enum, Union), 936 Adt(Struct, Enum, Union),
936 Trait, 937 Trait,
937 TypeAlias, 938 TypeAlias,
938 ImplDef, 939 ImplDef,
939 EnumVariant, 940 EnumVariant,
940 Const 941 Const
942 for GenericDef
941); 943);
942 944
943impl GenericDef { 945impl GenericDef {
@@ -1578,8 +1580,8 @@ pub enum AttrDef {
1578 MacroDef(MacroDef), 1580 MacroDef(MacroDef),
1579} 1581}
1580 1582
1581impl_froms!( 1583impl_from!(
1582 AttrDef: Module, 1584 Module,
1583 Field, 1585 Field,
1584 Adt(Struct, Enum, Union), 1586 Adt(Struct, Enum, Union),
1585 EnumVariant, 1587 EnumVariant,
@@ -1589,6 +1591,7 @@ impl_froms!(
1589 Trait, 1591 Trait,
1590 TypeAlias, 1592 TypeAlias,
1591 MacroDef 1593 MacroDef
1594 for AttrDef
1592); 1595);
1593 1596
1594pub trait HasAttrs { 1597pub trait HasAttrs {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 3364a822f..7d9b174b4 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -19,25 +19,6 @@
19 19
20#![recursion_limit = "512"] 20#![recursion_limit = "512"]
21 21
22macro_rules! impl_froms {
23 ($e:ident: $($v:ident $(($($sv:ident),*))?),*$(,)?) => {
24 $(
25 impl From<$v> for $e {
26 fn from(it: $v) -> $e {
27 $e::$v(it)
28 }
29 }
30 $($(
31 impl From<$sv> for $e {
32 fn from(it: $sv) -> $e {
33 $e::$v($v::$sv(it))
34 }
35 }
36 )*)?
37 )*
38 }
39}
40
41mod semantics; 22mod semantics;
42pub mod db; 23pub mod db;
43mod source_analyzer; 24mod source_analyzer;
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs
index 0e1d92fb3..42e5a1bdb 100644
--- a/crates/ra_hir/src/semantics/source_to_def.rs
+++ b/crates/ra_hir/src/semantics/source_to_def.rs
@@ -16,6 +16,7 @@ use ra_syntax::{
16 match_ast, AstNode, SyntaxNode, 16 match_ast, AstNode, SyntaxNode,
17}; 17};
18use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19use stdx::impl_from;
19 20
20use crate::{db::HirDatabase, InFile, MacroDefId}; 21use crate::{db::HirDatabase, InFile, MacroDefId};
21 22
@@ -255,8 +256,7 @@ pub(crate) enum ChildContainer {
255 /// here the children generic parameters, and not, eg enum variants. 256 /// here the children generic parameters, and not, eg enum variants.
256 GenericDefId(GenericDefId), 257 GenericDefId(GenericDefId),
257} 258}
258impl_froms! { 259impl_from! {
259 ChildContainer:
260 DefWithBodyId, 260 DefWithBodyId,
261 ModuleId, 261 ModuleId,
262 TraitId, 262 TraitId,
@@ -265,6 +265,7 @@ impl_froms! {
265 VariantId, 265 VariantId,
266 TypeAliasId, 266 TypeAliasId,
267 GenericDefId 267 GenericDefId
268 for ChildContainer
268} 269}
269 270
270impl ChildContainer { 271impl ChildContainer {
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 564434ccc..b71d626c3 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -65,6 +65,7 @@ use item_tree::{
65 Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, 65 Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
66 TypeAlias, Union, 66 TypeAlias, Union,
67}; 67};
68use stdx::impl_from;
68 69
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70pub struct ModuleId { 71pub struct ModuleId {
@@ -223,25 +224,6 @@ pub struct TypeParamId {
223 224
224pub type LocalTypeParamId = Idx<generics::TypeParamData>; 225pub type LocalTypeParamId = Idx<generics::TypeParamData>;
225 226
226macro_rules! impl_froms {
227 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
228 $(
229 impl From<$v> for $e {
230 fn from(it: $v) -> $e {
231 $e::$v(it)
232 }
233 }
234 $($(
235 impl From<$sv> for $e {
236 fn from(it: $sv) -> $e {
237 $e::$v($v::$sv(it))
238 }
239 }
240 )*)?
241 )*
242 }
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 227#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
246pub enum ContainerId { 228pub enum ContainerId {
247 ModuleId(ModuleId), 229 ModuleId(ModuleId),
@@ -254,7 +236,7 @@ pub enum AssocContainerId {
254 ImplId(ImplId), 236 ImplId(ImplId),
255 TraitId(TraitId), 237 TraitId(TraitId),
256} 238}
257impl_froms!(AssocContainerId: ContainerId); 239impl_from!(ContainerId for AssocContainerId);
258 240
259/// A Data Type 241/// A Data Type
260#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 242#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -263,7 +245,7 @@ pub enum AdtId {
263 UnionId(UnionId), 245 UnionId(UnionId),
264 EnumId(EnumId), 246 EnumId(EnumId),
265} 247}
266impl_froms!(AdtId: StructId, UnionId, EnumId); 248impl_from!(StructId, UnionId, EnumId for AdtId);
267 249
268/// The defs which can be visible in the module. 250/// The defs which can be visible in the module.
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -279,8 +261,8 @@ pub enum ModuleDefId {
279 TypeAliasId(TypeAliasId), 261 TypeAliasId(TypeAliasId),
280 BuiltinType(BuiltinType), 262 BuiltinType(BuiltinType),
281} 263}
282impl_froms!( 264impl_from!(
283 ModuleDefId: ModuleId, 265 ModuleId,
284 FunctionId, 266 FunctionId,
285 AdtId(StructId, EnumId, UnionId), 267 AdtId(StructId, EnumId, UnionId),
286 EnumVariantId, 268 EnumVariantId,
@@ -289,6 +271,7 @@ impl_froms!(
289 TraitId, 271 TraitId,
290 TypeAliasId, 272 TypeAliasId,
291 BuiltinType 273 BuiltinType
274 for ModuleDefId
292); 275);
293 276
294/// The defs which have a body. 277/// The defs which have a body.
@@ -299,7 +282,7 @@ pub enum DefWithBodyId {
299 ConstId(ConstId), 282 ConstId(ConstId),
300} 283}
301 284
302impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId); 285impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
303 286
304#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 287#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
305pub enum AssocItemId { 288pub enum AssocItemId {
@@ -311,7 +294,7 @@ pub enum AssocItemId {
311// sure that you can only turn actual assoc items into AssocItemIds. This would 294// sure that you can only turn actual assoc items into AssocItemIds. This would
312// require not implementing From, and instead having some checked way of 295// require not implementing From, and instead having some checked way of
313// casting them, and somehow making the constructors private, which would be annoying. 296// casting them, and somehow making the constructors private, which would be annoying.
314impl_froms!(AssocItemId: FunctionId, ConstId, TypeAliasId); 297impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
315 298
316#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 299#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
317pub enum GenericDefId { 300pub enum GenericDefId {
@@ -326,14 +309,15 @@ pub enum GenericDefId {
326 // consts can have type parameters from their parents (i.e. associated consts of traits) 309 // consts can have type parameters from their parents (i.e. associated consts of traits)
327 ConstId(ConstId), 310 ConstId(ConstId),
328} 311}
329impl_froms!( 312impl_from!(
330 GenericDefId: FunctionId, 313 FunctionId,
331 AdtId(StructId, EnumId, UnionId), 314 AdtId(StructId, EnumId, UnionId),
332 TraitId, 315 TraitId,
333 TypeAliasId, 316 TypeAliasId,
334 ImplId, 317 ImplId,
335 EnumVariantId, 318 EnumVariantId,
336 ConstId 319 ConstId
320 for GenericDefId
337); 321);
338 322
339impl From<AssocItemId> for GenericDefId { 323impl From<AssocItemId> for GenericDefId {
@@ -361,8 +345,8 @@ pub enum AttrDefId {
361 ImplId(ImplId), 345 ImplId(ImplId),
362} 346}
363 347
364impl_froms!( 348impl_from!(
365 AttrDefId: ModuleId, 349 ModuleId,
366 FieldId, 350 FieldId,
367 AdtId(StructId, EnumId, UnionId), 351 AdtId(StructId, EnumId, UnionId),
368 EnumVariantId, 352 EnumVariantId,
@@ -373,6 +357,7 @@ impl_froms!(
373 TypeAliasId, 357 TypeAliasId,
374 MacroDefId, 358 MacroDefId,
375 ImplId 359 ImplId
360 for AttrDefId
376); 361);
377 362
378#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 363#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -381,7 +366,7 @@ pub enum VariantId {
381 StructId(StructId), 366 StructId(StructId),
382 UnionId(UnionId), 367 UnionId(UnionId),
383} 368}
384impl_froms!(VariantId: EnumVariantId, StructId, UnionId); 369impl_from!(EnumVariantId, StructId, UnionId for VariantId);
385 370
386trait Intern { 371trait Intern {
387 type ID; 372 type ID;
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 5c56c2eb0..2ce4f65cc 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -18,8 +18,6 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use rustc_hash::FxHashMap;
22
23use hir_def::{ 21use hir_def::{
24 body::Body, 22 body::Body,
25 data::{ConstData, FunctionData, StaticData}, 23 data::{ConstData, FunctionData, StaticData},
@@ -35,6 +33,8 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name};
35use ra_arena::map::ArenaMap; 33use ra_arena::map::ArenaMap;
36use ra_prof::profile; 34use ra_prof::profile;
37use ra_syntax::SmolStr; 35use ra_syntax::SmolStr;
36use rustc_hash::FxHashMap;
37use stdx::impl_from;
38 38
39use super::{ 39use super::{
40 primitive::{FloatTy, IntTy}, 40 primitive::{FloatTy, IntTy},
@@ -84,8 +84,7 @@ enum ExprOrPatId {
84 ExprId(ExprId), 84 ExprId(ExprId),
85 PatId(PatId), 85 PatId(PatId),
86} 86}
87 87impl_from!(ExprId, PatId for ExprOrPatId);
88impl_froms!(ExprOrPatId: ExprId, PatId);
89 88
90/// Binding modes inferred for patterns. 89/// Binding modes inferred for patterns.
91/// https://doc.rust-lang.org/reference/patterns.html#binding-modes 90/// https://doc.rust-lang.org/reference/patterns.html#binding-modes
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 34f0bd4ce..2652d200f 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -6,25 +6,6 @@ macro_rules! eprintln {
6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; 6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
7} 7}
8 8
9macro_rules! impl_froms {
10 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
11 $(
12 impl From<$v> for $e {
13 fn from(it: $v) -> $e {
14 $e::$v(it)
15 }
16 }
17 $($(
18 impl From<$sv> for $e {
19 fn from(it: $sv) -> $e {
20 $e::$v($v::$sv(it))
21 }
22 }
23 )*)?
24 )*
25 }
26}
27
28mod autoderef; 9mod autoderef;
29pub mod primitive; 10pub mod primitive;
30pub mod traits; 11pub mod traits;
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 3af8d55a1..101b8aebe 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -5,10 +5,7 @@
5//! - Building the type for an item: This happens through the `type_for_def` query. 5//! - Building the type for an item: This happens through the `type_for_def` query.
6//! 6//!
7//! This usually involves resolving names, collecting generic arguments etc. 7//! This usually involves resolving names, collecting generic arguments etc.
8use std::iter; 8use std::{iter, sync::Arc};
9use std::sync::Arc;
10
11use smallvec::SmallVec;
12 9
13use hir_def::{ 10use hir_def::{
14 adt::StructKind, 11 adt::StructKind,
@@ -24,6 +21,8 @@ use hir_def::{
24use hir_expand::name::Name; 21use hir_expand::name::Name;
25use ra_arena::map::ArenaMap; 22use ra_arena::map::ArenaMap;
26use ra_db::CrateId; 23use ra_db::CrateId;
24use smallvec::SmallVec;
25use stdx::impl_from;
27use test_utils::mark; 26use test_utils::mark;
28 27
29use crate::{ 28use crate::{
@@ -1110,7 +1109,7 @@ pub enum CallableDef {
1110 StructId(StructId), 1109 StructId(StructId),
1111 EnumVariantId(EnumVariantId), 1110 EnumVariantId(EnumVariantId),
1112} 1111}
1113impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); 1112impl_from!(FunctionId, StructId, EnumVariantId for CallableDef);
1114 1113
1115impl CallableDef { 1114impl CallableDef {
1116 pub fn krate(self, db: &dyn HirDatabase) -> CrateId { 1115 pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
@@ -1140,7 +1139,7 @@ pub enum TyDefId {
1140 AdtId(AdtId), 1139 AdtId(AdtId),
1141 TypeAliasId(TypeAliasId), 1140 TypeAliasId(TypeAliasId),
1142} 1141}
1143impl_froms!(TyDefId: BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId); 1142impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1144 1143
1145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1146pub enum ValueTyDefId { 1145pub enum ValueTyDefId {
@@ -1150,7 +1149,7 @@ pub enum ValueTyDefId {
1150 ConstId(ConstId), 1149 ConstId(ConstId),
1151 StaticId(StaticId), 1150 StaticId(StaticId),
1152} 1151}
1153impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId); 1152impl_from!(FunctionId, StructId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1154 1153
1155/// Build the declared type of an item. This depends on the namespace; e.g. for 1154/// Build the declared type of an item. This depends on the namespace; e.g. for
1156/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 1155/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
diff --git a/crates/ra_tt/Cargo.toml b/crates/ra_tt/Cargo.toml
index f7230a9ca..b5b12e3af 100644
--- a/crates/ra_tt/Cargo.toml
+++ b/crates/ra_tt/Cargo.toml
@@ -8,6 +8,7 @@ authors = ["rust-analyzer developers"]
8doctest = false 8doctest = false
9 9
10[dependencies] 10[dependencies]
11stdx = { path = "../stdx" }
11# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here 12# ideally, `serde` should be enabled by `rust-analyzer`, but we enable it here
12# to reduce number of compilations 13# to reduce number of compilations
13smol_str = { version = "0.1.15", features = ["serde"] } 14smol_str = { version = "0.1.15", features = ["serde"] }
diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
index 342ddbe32..8faf1cc67 100644
--- a/crates/ra_tt/src/lib.rs
+++ b/crates/ra_tt/src/lib.rs
@@ -1,24 +1,13 @@
1//! `tt` crate defines a `TokenTree` data structure: this is the interface (both 1//! `tt` crate defines a `TokenTree` data structure: this is the interface (both
2//! input and output) of macros. It closely mirrors `proc_macro` crate's 2//! input and output) of macros. It closely mirrors `proc_macro` crate's
3//! `TokenTree`. 3//! `TokenTree`.
4
5macro_rules! impl_froms {
6 ($e:ident: $($v:ident), *) => {
7 $(
8 impl From<$v> for $e {
9 fn from(it: $v) -> $e {
10 $e::$v(it)
11 }
12 }
13 )*
14 }
15}
16
17use std::{ 4use std::{
18 fmt::{self, Debug}, 5 fmt::{self, Debug},
19 panic::RefUnwindSafe, 6 panic::RefUnwindSafe,
20}; 7};
21 8
9use stdx::impl_from;
10
22pub use smol_str::SmolStr; 11pub use smol_str::SmolStr;
23 12
24/// Represents identity of the token. 13/// Represents identity of the token.
@@ -41,7 +30,7 @@ pub enum TokenTree {
41 Leaf(Leaf), 30 Leaf(Leaf),
42 Subtree(Subtree), 31 Subtree(Subtree),
43} 32}
44impl_froms!(TokenTree: Leaf, Subtree); 33impl_from!(Leaf, Subtree for TokenTree);
45 34
46impl TokenTree { 35impl TokenTree {
47 pub fn empty() -> Self { 36 pub fn empty() -> Self {
@@ -55,7 +44,7 @@ pub enum Leaf {
55 Punct(Punct), 44 Punct(Punct),
56 Ident(Ident), 45 Ident(Ident),
57} 46}
58impl_froms!(Leaf: Literal, Punct, Ident); 47impl_from!(Literal, Punct, Ident for Leaf);
59 48
60#[derive(Clone, PartialEq, Eq, Hash, Default)] 49#[derive(Clone, PartialEq, Eq, Hash, Default)]
61pub struct Subtree { 50pub struct Subtree {
diff --git a/crates/stdx/src/macros.rs b/crates/stdx/src/macros.rs
index 0f7690a67..bf298460f 100644
--- a/crates/stdx/src/macros.rs
+++ b/crates/stdx/src/macros.rs
@@ -17,3 +17,24 @@ macro_rules! format_to {
17 { use ::std::fmt::Write as _; let _ = ::std::write!($buf, $lit $($arg)*); } 17 { use ::std::fmt::Write as _; let _ = ::std::write!($buf, $lit $($arg)*); }
18 }; 18 };
19} 19}
20
21// Generates `From` impls for `Enum E { Foo(Foo), Bar(Bar) }` enums
22#[macro_export]
23macro_rules! impl_from {
24 ($($variant:ident $(($($sub_variant:ident),*))?),* for $enum:ident) => {
25 $(
26 impl From<$variant> for $enum {
27 fn from(it: $variant) -> $enum {
28 $enum::$variant(it)
29 }
30 }
31 $($(
32 impl From<$sub_variant> for $enum {
33 fn from(it: $sub_variant) -> $enum {
34 $enum::$variant($variant::$sub_variant(it))
35 }
36 }
37 )*)?
38 )*
39 }
40}