Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--Cargo.lock4
-rw-r--r--crates/cfg/Cargo.toml2
-rw-r--r--crates/hir_def/Cargo.toml2
-rw-r--r--crates/hir_def/src/macro_expansion_tests.rs34
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe.rs272
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe/matching.rs12
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs6
-rw-r--r--crates/hir_expand/Cargo.toml2
-rw-r--r--crates/hir_ty/Cargo.toml2
-rw-r--r--crates/ide/Cargo.toml2
-rw-r--r--crates/ide_assists/Cargo.toml2
-rw-r--r--crates/ide_completion/Cargo.toml2
-rw-r--r--crates/ide_db/Cargo.toml2
-rw-r--r--crates/ide_diagnostics/Cargo.toml2
-rw-r--r--crates/ide_ssr/Cargo.toml2
-rw-r--r--crates/mbe/Cargo.toml2
-rw-r--r--crates/mbe/src/tests/expand.rs229
-rw-r--r--crates/proc_macro_srv/Cargo.toml2
-rw-r--r--crates/project_model/Cargo.toml2
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/lib.rs7
22 files changed, 309 insertions, 285 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5aba6387f0..68c8536b2f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -345,9 +345,9 @@ dependencies = [
[[package]]
name = "expect-test"
-version = "1.1.0"
+version = "1.2.0-pre.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2300477aab3a378f2ca00a4fbd4dc713654ab7ed790e4017493cb33656280633"
+checksum = "3a2f1664bc69648747878bfe3430ad9b58bc8d9b50b3b1df9f3c081345e33197"
dependencies = [
"dissimilar",
"once_cell",
diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml
index 132505fbf4..f86199c8c3 100644
--- a/crates/cfg/Cargo.toml
+++ b/crates/cfg/Cargo.toml
@@ -16,7 +16,7 @@ tt = { path = "../tt", version = "0.0.0" }
[dev-dependencies]
mbe = { path = "../mbe" }
syntax = { path = "../syntax" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
oorandom = "11"
# We depend on both individually instead of using `features = ["derive"]` to microoptimize the
# build graph: if the feature was enabled, syn would be built early on in the graph if `smolstr`
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml
index f5e60a4f54..9573d5ac35 100644
--- a/crates/hir_def/Cargo.toml
+++ b/crates/hir_def/Cargo.toml
@@ -35,4 +35,4 @@ limit = { path = "../limit", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs
index 96957471c8..c66c75c143 100644
--- a/crates/hir_def/src/macro_expansion_tests.rs
+++ b/crates/hir_def/src/macro_expansion_tests.rs
@@ -28,7 +28,7 @@ use crate::{
db::DefDatabase, nameres::ModuleSource, resolver::HasResolver, test_db::TestDB, AsMacroCall,
};
-fn check(ra_fixture: &str, expect: Expect) {
+fn check(ra_fixture: &str, mut expect: Expect) {
let db = TestDB::with_files(ra_fixture);
let krate = db.crate_graph().iter().next().unwrap();
let def_map = db.crate_def_map(krate);
@@ -65,16 +65,29 @@ fn check(ra_fixture: &str, expect: Expect) {
format_to!(expn_text, "/* error: {} */", err);
}
if let Some((parse, _token_map)) = exp.value {
+ assert!(
+ parse.errors().is_empty(),
+ "parse errors in expansion: \n{:#?}",
+ parse.errors()
+ );
let pp = pretty_print_macro_expansion(parse.syntax_node());
let indent = IndentLevel::from_node(call.syntax());
let pp = reindent(indent, pp);
format_to!(expn_text, "{}", pp);
+ if call.to_string().contains("// +tree") {
+ let tree = format!("{:#?}", parse.syntax_node())
+ .split_inclusive("\n")
+ .map(|line| format!("// {}", line))
+ .collect::<String>();
+ format_to!(expn_text, "\n{}", tree)
+ }
}
let range = call.syntax().text_range();
let range: Range<usize> = range.into();
expanded_text.replace_range(range, &expn_text)
}
+ expect.indent(false);
expect.assert_eq(&expanded_text);
}
@@ -97,20 +110,37 @@ fn reindent(indent: IndentLevel, pp: String) -> String {
fn pretty_print_macro_expansion(expn: SyntaxNode) -> String {
let mut res = String::new();
let mut prev_kind = SyntaxKind::EOF;
+ let mut indent_level = 0;
for token in iter::successors(expn.first_token(), |t| t.next_token()) {
let curr_kind = token.kind();
let space = match (prev_kind, curr_kind) {
_ if prev_kind.is_trivia() || curr_kind.is_trivia() => "",
+ (T!['{'], T!['}']) => "",
(T![=], _) | (_, T![=]) => " ",
(_, T!['{']) => " ",
- (T![;] | T!['}'], _) => "\n",
+ (T![;] | T!['{'] | T!['}'], _) => "\n",
+ (_, T!['}']) => "\n",
(IDENT | LIFETIME_IDENT, IDENT | LIFETIME_IDENT) => " ",
(IDENT, _) if curr_kind.is_keyword() => " ",
(_, IDENT) if prev_kind.is_keyword() => " ",
+ (T![>], IDENT) => " ",
+ (T![>], _) if curr_kind.is_keyword() => " ",
+ (T![->], _) | (_, T![->]) => " ",
+ (T![&&], _) | (_, T![&&]) => " ",
_ => "",
};
+ match prev_kind {
+ T!['{'] => indent_level += 1,
+ T!['}'] => indent_level -= 1,
+ _ => (),
+ }
+
res.push_str(space);
+ if space == "\n" {
+ let level = if curr_kind == T!['}'] { indent_level - 1 } else { indent_level };
+ res.push_str(&" ".repeat(level));
+ }
prev_kind = curr_kind;
format_to!(res, "{}", token)
}
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe.rs b/crates/hir_def/src/macro_expansion_tests/mbe.rs
index c57e9cd838..384c70028d 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs
@@ -10,6 +10,45 @@ use expect_test::expect;
use crate::macro_expansion_tests::check;
#[test]
+fn mbe_smoke_test() {
+ check(
+ r#"
+macro_rules! impl_froms {
+ ($e:ident: $($v:ident),*) => {
+ $(
+ impl From<$v> for $e {
+ fn from(it: $v) -> $e { $e::$v(it) }
+ }
+ )*
+ }
+}
+impl_froms!(TokenTree: Leaf, Subtree);
+"#,
+ expect![[r#"
+macro_rules! impl_froms {
+ ($e:ident: $($v:ident),*) => {
+ $(
+ impl From<$v> for $e {
+ fn from(it: $v) -> $e { $e::$v(it) }
+ }
+ )*
+ }
+}
+impl From<Leaf> for TokenTree {
+ fn from(it:Leaf) -> TokenTree {
+ TokenTree::Leaf(it)
+ }
+}
+impl From<Subtree> for TokenTree {
+ fn from(it:Subtree) -> TokenTree {
+ TokenTree::Subtree(it)
+ }
+}
+"#]],
+ );
+}
+
+#[test]
fn expansion_does_not_parse_as_expression() {
check(
r#"
@@ -52,9 +91,9 @@ fn match_by_first_token_literally() {
check(
r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- (= $ i:ident) => ( fn $ i() {} );
- (+ $ i:ident) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ (= $i:ident) => ( fn $i() {} );
+ (+ $i:ident) => ( struct $i; )
}
m! { foo }
m! { = bar }
@@ -62,9 +101,9 @@ m! { + Baz }
"#,
expect![[r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- (= $ i:ident) => ( fn $ i() {} );
- (+ $ i:ident) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ (= $i:ident) => ( fn $i() {} );
+ (+ $i:ident) => ( struct $i; )
}
mod foo {}
fn bar() {}
@@ -78,9 +117,9 @@ fn match_by_last_token_literally() {
check(
r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- ($ i:ident =) => ( fn $ i() {} );
- ($ i:ident +) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ ($i:ident =) => ( fn $i() {} );
+ ($i:ident +) => ( struct $i; )
}
m! { foo }
m! { bar = }
@@ -88,9 +127,9 @@ m! { Baz + }
"#,
expect![[r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- ($ i:ident =) => ( fn $ i() {} );
- ($ i:ident +) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ ($i:ident =) => ( fn $i() {} );
+ ($i:ident +) => ( struct $i; )
}
mod foo {}
fn bar() {}
@@ -104,9 +143,9 @@ fn match_by_ident() {
check(
r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- (spam $ i:ident) => ( fn $ i() {} );
- (eggs $ i:ident) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ (spam $i:ident) => ( fn $i() {} );
+ (eggs $i:ident) => ( struct $i; )
}
m! { foo }
m! { spam bar }
@@ -114,9 +153,9 @@ m! { eggs Baz }
"#,
expect![[r#"
macro_rules! m {
- ($ i:ident) => ( mod $ i {} );
- (spam $ i:ident) => ( fn $ i() {} );
- (eggs $ i:ident) => ( struct $ i; )
+ ($i:ident) => ( mod $i {} );
+ (spam $i:ident) => ( fn $i() {} );
+ (eggs $i:ident) => ( struct $i; )
}
mod foo {}
fn bar() {}
@@ -130,9 +169,9 @@ fn match_by_separator_token() {
check(
r#"
macro_rules! m {
- ($ ($ i:ident),*) => ($ ( mod $ i {} )*);
- ($ ($ i:ident)#*) => ($ ( fn $ i() {} )*);
- ($ i:ident ,# $ j:ident) => ( struct $ i; struct $ j; )
+ ($($i:ident),*) => ($(mod $i {} )*);
+ ($($i:ident)#*) => ($(fn $i() {} )*);
+ ($i:ident ,# $ j:ident) => ( struct $i; struct $ j; )
}
m! { foo, bar }
@@ -143,9 +182,9 @@ m! { Foo,# Bar }
"#,
expect![[r##"
macro_rules! m {
- ($ ($ i:ident),*) => ($ ( mod $ i {} )*);
- ($ ($ i:ident)#*) => ($ ( fn $ i() {} )*);
- ($ i:ident ,# $ j:ident) => ( struct $ i; struct $ j; )
+ ($($i:ident),*) => ($(mod $i {} )*);
+ ($($i:ident)#*) => ($(fn $i() {} )*);
+ ($i:ident ,# $ j:ident) => ( struct $i; struct $ j; )
}
mod foo {}
@@ -159,3 +198,188 @@ struct Bar;
"##]],
);
}
+
+#[test]
+fn test_match_group_pattern_with_multiple_defs() {
+ check(
+ r#"
+macro_rules! m {
+ ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
+}
+m! { foo, bar }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
+}
+impl Bar {
+ fn foo() {}
+ fn bar() {}
+}
+"#]],
+ );
+}
+
+#[test]
+fn test_match_group_pattern_with_multiple_statement() {
+ check(
+ r#"
+macro_rules! m {
+ ($($i:ident),*) => ( fn baz() { $($i ();)* } );
+}
+m! { foo, bar }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($($i:ident),*) => ( fn baz() { $($i ();)* } );
+}
+fn baz() {
+ foo();
+ bar();
+}
+"#]],
+ )
+}
+
+#[test]
+fn test_match_group_pattern_with_multiple_statement_without_semi() {
+ check(
+ r#"
+macro_rules! m {
+ ($($i:ident),*) => ( fn baz() { $($i() );* } );
+}
+m! { foo, bar }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($($i:ident),*) => ( fn baz() { $($i() );* } );
+}
+fn baz() {
+ foo();
+ bar()
+}
+"#]],
+ )
+}
+
+#[test]
+fn test_match_group_empty_fixed_token() {
+ check(
+ r#"
+macro_rules! m {
+ ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
+}
+m!{#abc}
+"#,
+ expect![[r##"
+macro_rules! m {
+ ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
+}
+fn baz() {}
+"##]],
+ )
+}
+
+#[test]
+fn test_match_group_in_subtree() {
+ check(
+ r#"
+macro_rules! m {
+ (fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } );
+}
+m! { fn baz { a b } }
+"#,
+ expect![[r#"
+macro_rules! m {
+ (fn $name:ident { $($i:ident)* } ) => ( fn $name() { $($i ();)* } );
+}
+fn baz() {
+ a();
+ b();
+}
+"#]],
+ )
+}
+
+#[test]
+fn test_expr_order() {
+ check(
+ r#"
+macro_rules! m {
+ ($ i:expr) => { fn bar() { $ i * 3; } }
+}
+// +tree
+m! { 1 + 2 }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($ i:expr) => { fn bar() { $ i * 3; } }
+}
+fn bar() {
+ 1+2*3;
+}
+
+"#]],
+ )
+}
+
+#[test]
+fn test_match_group_with_multichar_sep() {
+ check(
+ r#"
+macro_rules! m {
+ (fn $name:ident { $($i:literal)* }) => ( fn $name() -> bool { $($i)&&* } );
+}
+m! (fn baz { true false } );
+"#,
+ expect![[r#"
+macro_rules! m {
+ (fn $name:ident { $($i:literal)* }) => ( fn $name() -> bool { $($i)&&* } );
+}
+fn baz() -> bool {
+ true && false
+}
+"#]],
+ );
+
+ check(
+ r#"
+macro_rules! m {
+ (fn $name:ident { $($i:literal)&&* }) => ( fn $name() -> bool { $($i)&&* } );
+}
+m! (fn baz { true && false } );
+"#,
+ expect![[r#"
+macro_rules! m {
+ (fn $name:ident { $($i:literal)&&* }) => ( fn $name() -> bool { $($i)&&* } );
+}
+fn baz() -> bool {
+ true && false
+}
+"#]],
+ );
+}
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe/matching.rs b/crates/hir_def/src/macro_expansion_tests/mbe/matching.rs
index 11317cfa9d..5bdabfc598 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe/matching.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe/matching.rs
@@ -8,18 +8,18 @@ use crate::macro_expansion_tests::check;
fn unary_minus_is_a_literal() {
check(
r#"
-macro_rules! m { ($x:literal) => (literal!()); ($x:tt) => (not_a_literal!()); }
+macro_rules! m { ($x:literal) => (literal!();); ($x:tt) => (not_a_literal!();); }
m!(92);
m!(-92);
m!(-9.2);
m!(--92);
"#,
expect![[r#"
-macro_rules! m { ($x:literal) => (literal!()); ($x:tt) => (not_a_literal!()); }
-literal!()
-literal!()
-literal!()
-/* error: leftover tokens */not_a_literal!()
+macro_rules! m { ($x:literal) => (literal!();); ($x:tt) => (not_a_literal!();); }
+literal!();
+literal!();
+literal!();
+/* error: leftover tokens */not_a_literal!();
"#]],
)
}
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs b/crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs
index 4249c2507e..d434c88244 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe/meta_syntax.rs
@@ -16,7 +16,7 @@ macro_rules! m {
($($i:ident)*) => ($_);
($($true:ident)*) => ($true);
($($false:ident)*) => ($false);
- ($) => ($);
+ ($) => (m!($););
}
m!($);
"#,
@@ -29,9 +29,9 @@ macro_rules! m {
($($i:ident)*) => ($_);
($($true:ident)*) => ($true);
($($false:ident)*) => ($false);
- ($) => ($);
+ ($) => (m!($););
}
-$
+m!($);
"#]],
)
}
diff --git a/crates/hir_expand/Cargo.toml b/crates/hir_expand/Cargo.toml
index b39de7cfae..240193f9cf 100644
--- a/crates/hir_expand/Cargo.toml
+++ b/crates/hir_expand/Cargo.toml
@@ -25,4 +25,4 @@ mbe = { path = "../mbe", version = "0.0.0" }
limit = { path = "../limit", version = "0.0.0" }
[dev-dependencies]
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 7566bf687b..0f1e75958a 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -33,7 +33,7 @@ limit = { path = "../limit", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
tracing = "0.1"
tracing-subscriber = { version = "0.2", default-features = false, features = [
"env-filter",
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 804002a4b3..bccadacdb2 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -38,4 +38,4 @@ hir = { path = "../hir", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/ide_assists/Cargo.toml b/crates/ide_assists/Cargo.toml
index c34798d0ea..629aadb5b1 100644
--- a/crates/ide_assists/Cargo.toml
+++ b/crates/ide_assists/Cargo.toml
@@ -25,4 +25,4 @@ hir = { path = "../hir", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
sourcegen = { path = "../sourcegen" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/ide_completion/Cargo.toml b/crates/ide_completion/Cargo.toml
index 0d4413978d..5b2f0b35f9 100644
--- a/crates/ide_completion/Cargo.toml
+++ b/crates/ide_completion/Cargo.toml
@@ -28,7 +28,7 @@ profile = { path = "../profile", version = "0.0.0" }
hir = { path = "../hir", version = "0.0.0" }
[dev-dependencies]
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
xshell = "0.1"
test_utils = { path = "../test_utils" }
diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml
index cdaff0ce39..e3c60edda1 100644
--- a/crates/ide_db/Cargo.toml
+++ b/crates/ide_db/Cargo.toml
@@ -31,4 +31,4 @@ limit = { path = "../limit", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/ide_diagnostics/Cargo.toml b/crates/ide_diagnostics/Cargo.toml
index 3389e67d9d..7e36b1a3bd 100644
--- a/crates/ide_diagnostics/Cargo.toml
+++ b/crates/ide_diagnostics/Cargo.toml
@@ -23,7 +23,7 @@ hir = { path = "../hir", version = "0.0.0" }
ide_db = { path = "../ide_db", version = "0.0.0" }
[dev-dependencies]
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
test_utils = { path = "../test_utils" }
sourcegen = { path = "../sourcegen" }
diff --git a/crates/ide_ssr/Cargo.toml b/crates/ide_ssr/Cargo.toml
index 28aacd349c..275f923f2b 100644
--- a/crates/ide_ssr/Cargo.toml
+++ b/crates/ide_ssr/Cargo.toml
@@ -21,4 +21,4 @@ hir = { path = "../hir", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml
index 22bda57669..5378516e70 100644
--- a/crates/mbe/Cargo.toml
+++ b/crates/mbe/Cargo.toml
@@ -12,7 +12,7 @@ doctest = false
cov-mark = "2.0.0-pre.1"
rustc-hash = "1.1.0"
smallvec = "1.2.0"
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
tracing = "0.1"
syntax = { path = "../syntax", version = "0.0.0" }
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs
index 7becaa6658..c08788cda1 100644
--- a/crates/mbe/src/tests/expand.rs
+++ b/crates/mbe/src/tests/expand.rs
@@ -72,235 +72,6 @@ macro_rules! foobar {
}
#[test]
-fn test_convert_tt() {
- parse_macro(r#"
-macro_rules! impl_froms {
- ($e:ident: $($v:ident),*) => {
- $(
- impl From<$v> for $e {
- fn from(it: $v) -> $e {
- $e::$v(it)
- }
- }
- )*
- }
-}
-"#)
- .assert_expand_tt(
- "impl_froms!(TokenTree: Leaf, Subtree);",
- "impl From <Leaf > for TokenTree {fn from (it : Leaf) -> TokenTree {TokenTree ::Leaf (it)}} \
- impl From <Subtree > for TokenTree {fn from (it : Subtree) -> TokenTree {TokenTree ::Subtree (it)}}"
- );
-}
-
-#[test]
-fn test_convert_tt2() {
- parse_macro(
- r#"
-macro_rules! impl_froms {
- ($e:ident: $($v:ident),*) => {
- $(
- impl From<$v> for $e {
- fn from(it: $v) -> $e {
- $e::$v(it)
- }
- }
- )*
- }
-}
-"#,
- )
- .assert_expand(
- "impl_froms!(TokenTree: Leaf, Subtree);",
- r#"
-SUBTREE $
- IDENT impl 20
- IDENT From 21
- PUNCH < [joint] 22
- IDENT Leaf 53
- PUNCH > [alone] 25
- IDENT for 26
- IDENT TokenTree 51
- SUBTREE {} 29
- IDENT fn 30
- IDENT from 31
- SUBTREE () 32
- IDENT it 33
- PUNCH : [alone] 34
- IDENT Leaf 53
- PUNCH - [joint] 37
- PUNCH > [alone] 38
- IDENT TokenTree 51
- SUBTREE {} 41
- IDENT TokenTree 51
- PUNCH : [joint] 44
- PUNCH : [joint] 45
- IDENT Leaf 53
- SUBTREE () 48
- IDENT it 49
- IDENT impl 20
- IDENT From 21
- PUNCH < [joint] 22
- IDENT Subtree 55
- PUNCH > [alone] 25
- IDENT for 26
- IDENT TokenTree 51
- SUBTREE {} 29
- IDENT fn 30
- IDENT from 31
- SUBTREE () 32
- IDENT it 33
- PUNCH : [alone] 34
- IDENT Subtree 55
- PUNCH - [joint] 37
- PUNCH > [alone] 38
- IDENT TokenTree 51
- SUBTREE {} 41
- IDENT TokenTree 51
- PUNCH : [joint] 44
- PUNCH : [joint] 45
- IDENT Subtree 55
- SUBTREE () 48
- IDENT it 49
-"#,
- );
-}
-
-#[test]
-fn test_expr_order() {
- let expanded = parse_macro(
- r#"
- macro_rules! foo {
- ($ i:expr) => {
- fn bar() { $ i * 2; }
- }
- }
-"#,
- )
- .expand_items("foo! { 1 + 1}");
-
- let dump = format!("{:#?}", expanded);
- assert_eq_text!(
- dump.trim()
- );
-}
-
-#[test]
-fn test_match_group_pattern_with_multiple_defs() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ ($ i:ident),*) => ( struct Bar { $ (
- fn $ i {}
- )*} );
- }
-"#,
- )
- .assert_expand_items("foo! { foo, bar }", "struct Bar {fn foo {} fn bar {}}");
-}
-
-#[test]
-fn test_match_group_pattern_with_multiple_statement() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ ($ i:ident),*) => ( fn baz { $ (
- $ i ();
- )*} );
- }
-"#,
- )
- .assert_expand_items("foo! { foo, bar }", "fn baz {foo () ; bar () ;}");
-}
-
-#[test]
-fn test_match_group_pattern_with_multiple_statement_without_semi() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ ($ i:ident),*) => ( fn baz { $ (
- $i()
- );*} );
- }
-"#,
- )
- .assert_expand_items("foo! { foo, bar }", "fn baz {foo () ;bar ()}");
-}
-
-#[test]
-fn test_match_group_empty_fixed_token() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ ($ i:ident)* #abc) => ( fn baz { $ (
- $ i ();
- )*} );
- }
-"#,
- )
- .assert_expand_items("foo! {#abc}", "fn baz {}");
-}
-
-#[test]
-fn test_match_group_in_subtree() {
- parse_macro(
- r#"
- macro_rules! foo {
- (fn $name:ident {$($i:ident)*} ) => ( fn $name() { $ (
- $ i ();
- )*} );
- }"#,
- )
- .assert_expand_items("foo! {fn baz {a b} }", "fn baz () {a () ; b () ;}");
-}
-
-#[test]
-fn test_match_group_with_multichar_sep() {
- parse_macro(
- r#"
- macro_rules! foo {
- (fn $name:ident {$($i:literal)*} ) => ( fn $name() -> bool { $($i)&&*} );
- }"#,
- )
- .assert_expand_items("foo! (fn baz {true true} );", "fn baz () -> bool {true &&true}");
-}
-
-#[test]
-fn test_match_group_with_multichar_sep2() {
- parse_macro(
- r#"
- macro_rules! foo {
- (fn $name:ident {$($i:literal)&&*} ) => ( fn $name() -> bool { $($i)&&*} );
- }"#,
- )
- .assert_expand_items("foo! (fn baz {true && true} );", "fn baz () -> bool {true &&true}");
-}
-
-#[test]
fn test_match_group_zero_match() {
parse_macro(
r#"
diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml
index d0e6bd9990..6048c5e6cc 100644
--- a/crates/proc_macro_srv/Cargo.toml
+++ b/crates/proc_macro_srv/Cargo.toml
@@ -25,7 +25,7 @@ paths = { path = "../paths", version = "0.0.0" }
proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
[dev-dependencies]
-expect-test = "1.1.0"
+expect-test = "1.2.0-pre.1"
# used as proc macro test targets
proc_macro_test = { path = "../proc_macro_test" }
diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml
index cea2c16a63..949325fc82 100644
--- a/crates/project_model/Cargo.toml
+++ b/crates/project_model/Cargo.toml
@@ -16,7 +16,7 @@ semver = "1"
serde = { version = "1.0.106", features = ["derive"] }
serde_json = "1.0.48"
anyhow = "1.0.26"
-expect-test = "1"
+expect-test = "1.2.0-pre.1"
la-arena = { version = "0.2.0", path = "../../lib/arena" }
cfg = { path = "../cfg", version = "0.0.0" }
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 29a3fbb67e..8275f6e3d5 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -67,7 +67,7 @@ winapi = "0.3.8"
jemallocator = { version = "0.4.1", package = "tikv-jemallocator", optional = true }
[dev-dependencies]
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
xshell = "0.1"
test_utils = { path = "../test_utils" }
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index fba5db9a93..a34522435a 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -26,7 +26,7 @@ profile = { path = "../profile", version = "0.0.0" }
[dev-dependencies]
rayon = "1"
-expect-test = "1.1"
+expect-test = "1.2.0-pre.1"
proc-macro2 = "1.0.8"
quote = "1.0.2"
ungrammar = "=1.14.8"
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index 132d300674..24a099cb3c 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -89,6 +89,9 @@ impl<T> Parse<T> {
pub fn syntax_node(&self) -> SyntaxNode {
SyntaxNode::new_root(self.green.clone())
}
+ pub fn errors(&self) -> &[SyntaxError] {
+ &*self.errors
+ }
}
impl<T: AstNode> Parse<T> {
@@ -100,10 +103,6 @@ impl<T: AstNode> Parse<T> {
T::cast(self.syntax_node()).unwrap()
}
- pub fn errors(&self) -> &[SyntaxError] {
- &*self.errors
- }
-
pub fn ok(self) -> Result<T, Arc<Vec<SyntaxError>>> {
if self.errors.is_empty() {
Ok(self.tree())