From 6a5014329aecf73da81943216729ab64fa255368 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 28 Apr 2020 01:48:55 +0800 Subject: Use core instead of std for builtin derive macros --- crates/ra_hir_expand/src/builtin_derive.rs | 93 ++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 32 deletions(-) (limited to 'crates/ra_hir_expand') diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index bb45b0f1d..dae623dd0 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -9,7 +9,7 @@ use ra_syntax::{ }; use crate::db::AstDatabase; -use crate::{name, quote, LazyMacroId, MacroDefId, MacroDefKind}; +use crate::{name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind}; macro_rules! register_builtin { ( $($trait:ident => $expand:ident),* ) => { @@ -153,76 +153,105 @@ fn expand_simple_derive( Ok(expanded) } +fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { + // FIXME: make hygiene works for builtin derive macro + // such that $crate can be used here. + + let m: MacroCallId = id.into(); + let file_id = m.as_file().original_file(db); + let cg = db.crate_graph(); + let crates = db.relevant_crates(file_id); + let mut crate_names = + crates.iter().filter_map(|krate| cg[*krate].display_name.clone()).map(|it| it.to_string()); + + let tt = if crate_names.any(|name| name == "std" || name == "core") { + quote! { krate } + } else { + quote! { core } + }; + + tt.token_trees[0].clone() +} + fn copy_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::marker::Copy }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::marker::Copy }) } fn clone_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::clone::Clone }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::clone::Clone }) } fn default_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::default::Default }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::default::Default }) } fn debug_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::fmt::Debug }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::fmt::Debug }) } fn hash_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::hash::Hash }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::hash::Hash }) } fn eq_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::cmp::Eq }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::cmp::Eq }) } fn partial_eq_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::cmp::PartialEq }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::cmp::PartialEq }) } fn ord_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::cmp::Ord }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::cmp::Ord }) } fn partial_ord_expand( - _db: &dyn AstDatabase, - _id: LazyMacroId, + db: &dyn AstDatabase, + id: LazyMacroId, tt: &tt::Subtree, ) -> Result { - expand_simple_derive(tt, quote! { std::cmp::PartialOrd }) + let krate = find_builtin_crate(db, id); + expand_simple_derive(tt, quote! { #krate::cmp::PartialOrd }) } #[cfg(test)] @@ -264,7 +293,7 @@ mod tests { known::Copy, ); - assert_eq!(expanded, "impl< >std::marker::CopyforFoo< >{}"); + assert_eq!(expanded, "impl< >core::marker::CopyforFoo< >{}"); } #[test] @@ -279,7 +308,7 @@ mod tests { assert_eq!( expanded, - "implstd::marker::CopyforFoo{}" + "implcore::marker::CopyforFoo{}" ); } @@ -297,7 +326,7 @@ mod tests { assert_eq!( expanded, - "implstd::marker::CopyforFoo{}" + "implcore::marker::CopyforFoo{}" ); } @@ -313,7 +342,7 @@ mod tests { assert_eq!( expanded, - "implstd::clone::CloneforFoo{}" + "implcore::clone::CloneforFoo{}" ); } } -- cgit v1.2.3 From 213d208e2d61576e104a9d5e003efc4ad1abc469 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 28 Apr 2020 02:10:17 +0800 Subject: Add test --- crates/ra_hir_expand/src/builtin_derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_expand') diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index dae623dd0..cc8c45347 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -165,7 +165,7 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { crates.iter().filter_map(|krate| cg[*krate].display_name.clone()).map(|it| it.to_string()); let tt = if crate_names.any(|name| name == "std" || name == "core") { - quote! { krate } + quote! { crate } } else { quote! { core } }; -- cgit v1.2.3 From 6d3b0af900e6cefb507939b311672b7795703461 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 28 Apr 2020 03:32:47 +0800 Subject: Use empty-deps tricks to detect it is core --- crates/ra_hir_expand/src/builtin_derive.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_expand') diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index cc8c45347..3bd3f7041 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -160,11 +160,17 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { let m: MacroCallId = id.into(); let file_id = m.as_file().original_file(db); let cg = db.crate_graph(); - let crates = db.relevant_crates(file_id); - let mut crate_names = - crates.iter().filter_map(|krate| cg[*krate].display_name.clone()).map(|it| it.to_string()); + let krates = db.relevant_crates(file_id); + let krate = match krates.get(0) { + Some(krate) => krate, + None => { + let tt = quote! { core }; + return tt.token_trees[0].clone(); + } + }; - let tt = if crate_names.any(|name| name == "std" || name == "core") { + // Check whether it has any deps, if not, it should be core: + let tt = if cg[*krate].dependencies.is_empty() { quote! { crate } } else { quote! { core } @@ -263,8 +269,18 @@ mod tests { fn expand_builtin_derive(s: &str, name: Name) -> String { let def = find_builtin_derive(&name).unwrap(); + let fixture = format!( + r#"//- /main.rs crate:main deps:core +<|> +{} +//- /lib.rs crate:core +// empty +"#, + s + ); - let (db, file_id) = TestDB::with_single_file(&s); + let (db, file_pos) = TestDB::with_position(&fixture); + let file_id = file_pos.file_id; let parsed = db.parse(file_id); let items: Vec<_> = parsed.syntax_node().descendants().filter_map(ast::ModuleItem::cast).collect(); -- cgit v1.2.3 From c69f9c1b0a849b2cf5349e707508358e42bc8bb5 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 28 Apr 2020 04:11:24 +0800 Subject: Check dep name to detect it is core --- crates/ra_hir_expand/src/builtin_derive.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_expand') diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index 3bd3f7041..e60f879a3 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -169,11 +169,13 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { } }; - // Check whether it has any deps, if not, it should be core: - let tt = if cg[*krate].dependencies.is_empty() { - quote! { crate } - } else { + // XXX + // All crates except core itself should have a dependency on core, + // We detect `core` by seeing whether it doesn't have such a dependency. + let tt = if cg[*krate].dependencies.iter().any(|dep| dep.name == "core") { quote! { core } + } else { + quote! { crate } }; tt.token_trees[0].clone() -- cgit v1.2.3