aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yaml4
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/main.rs89
2 files changed, 92 insertions, 1 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 00f299ff1..13a11c95b 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -85,6 +85,10 @@ jobs:
85 - name: Compile 85 - name: Compile
86 run: cargo test --no-run 86 run: cargo test --no-run
87 87
88 # We have to build ra_proc_macro_srv first for running related heavy tests
89 - name: Build ra_proc_macro_srv
90 run: cargo build -p ra_proc_macro_srv
91
88 - name: Test 92 - name: Test
89 run: cargo test 93 run: cargo test
90 94
diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs
index 638813311..26ab81a8f 100644
--- a/crates/rust-analyzer/tests/heavy_tests/main.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/main.rs
@@ -9,7 +9,7 @@ use lsp_types::{
9}; 9};
10use rust_analyzer::req::{ 10use rust_analyzer::req::{
11 CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument, 11 CodeActionParams, CodeActionRequest, Completion, CompletionParams, DidOpenTextDocument,
12 Formatting, GotoDefinition, OnEnter, Runnables, RunnablesParams, 12 Formatting, GotoDefinition, HoverRequest, OnEnter, Runnables, RunnablesParams,
13}; 13};
14use serde_json::json; 14use serde_json::json;
15use tempfile::TempDir; 15use tempfile::TempDir;
@@ -625,3 +625,90 @@ fn main() { message(); }
625 )); 625 ));
626 assert!(format!("{}", res).contains("hello.rs")); 626 assert!(format!("{}", res).contains("hello.rs"));
627} 627}
628
629#[test]
630fn resolve_proc_macro() {
631 if skip_slow_tests() {
632 return;
633 }
634 let server = Project::with_fixture(
635 r###"
636//- foo/Cargo.toml
637[package]
638name = "foo"
639version = "0.0.0"
640edition = "2018"
641[dependencies]
642bar = {path = "../bar"}
643
644//- foo/src/main.rs
645use bar::Bar;
646trait Bar {
647 fn bar();
648}
649#[derive(Bar)]
650struct Foo {}
651fn main() {
652 Foo::bar();
653}
654
655//- bar/Cargo.toml
656[package]
657name = "bar"
658version = "0.0.0"
659edition = "2018"
660
661[lib]
662proc-macro = true
663
664//- bar/src/lib.rs
665extern crate proc_macro;
666use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
667macro_rules! t {
668 ($n:literal) => {
669 TokenTree::from(Ident::new($n, Span::call_site()))
670 };
671 ({}) => {
672 TokenTree::from(Group::new(Delimiter::Brace, TokenStream::new()))
673 };
674 (()) => {
675 TokenTree::from(Group::new(Delimiter::Parenthesis, TokenStream::new()))
676 };
677}
678#[proc_macro_derive(Bar)]
679pub fn foo(_input: TokenStream) -> TokenStream {
680 // We hard code the output here for preventing to use any deps
681 let mut res = TokenStream::new();
682
683 // impl Bar for Foo { fn bar() {} }
684 let mut tokens = vec![t!("impl"), t!("Bar"), t!("for"), t!("Foo")];
685 let mut fn_stream = TokenStream::new();
686 fn_stream.extend(vec![t!("fn"), t!("bar"), t!(()), t!({})]);
687 tokens.push(Group::new(Delimiter::Brace, fn_stream).into());
688 res.extend(tokens);
689 res
690}
691
692"###,
693 )
694 .with_config(|config| {
695 let macro_srv_path = std::path::Path::new(std::env!("CARGO_MANIFEST_DIR"))
696 .join("../../target/debug/ra_proc_macro_srv")
697 .to_string_lossy()
698 .to_string();
699
700 config.cargo.load_out_dirs_from_check = true;
701 config.proc_macro_srv = Some(macro_srv_path)
702 })
703 .root("foo")
704 .root("bar")
705 .server();
706 server.wait_until_workspace_is_loaded();
707 let res = server.send_request::<HoverRequest>(TextDocumentPositionParams::new(
708 server.doc_id("foo/src/main.rs"),
709 Position::new(7, 9),
710 ));
711
712 let value = res.get("contents").unwrap().get("value").unwrap().to_string();
713 assert_eq!(value, r#""```rust\nfoo::Bar\nfn bar()\n```""#)
714}