aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-17 09:41:30 +0000
committerGitHub <[email protected]>2020-03-17 09:41:30 +0000
commit6aa432d86b7e4fb691600032ebdf6f2301152447 (patch)
treeaa012212c11e43a95547f553b5116922631f9896 /crates/ra_ide
parentcf4ae9aa591729dde25a7df3fa5c22ca0fd94145 (diff)
parent6c20d7e979b967eb20207414c0a0bf875bbcb98d (diff)
Merge #3580
3580: More error-resilient MBE expansion r=matklad a=flodiebold This is the beginning of an attempt to make macro-by-example expansion more resilient, so that we still get an expansion even if no rule exactly matches, with the goal to make completion work better in macro calls. The general idea is to make everything return `(T, Option<ExpandError>)` instead of `Result<T, ExpandError>`; and then to try each macro arm in turn, and somehow choose the 'best' matching rule if none matches without errors. Finding that 'best' match isn't done yet; I'm currently counting how many tokens were consumed from the args before an error, but it also needs to take into account whether there were further patterns that had nothing to match. I'll continue this later, but I'm interested whether you think this is the right path, @matklad & @edwin0cheng. Co-authored-by: Florian Diebold <[email protected]> Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs50
-rw-r--r--crates/ra_ide/src/completion/complete_pattern.rs13
-rw-r--r--crates/ra_ide/src/completion/complete_scope.rs92
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs2
-rw-r--r--crates/ra_ide/src/expand_macro.rs2
5 files changed, 153 insertions, 6 deletions
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index f07611d88..82ec16913 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -720,7 +720,18 @@ mod tests {
720 } 720 }
721 ", 721 ",
722 ), 722 ),
723 @r###"[]"### 723 @r###"
724 [
725 CompletionItem {
726 label: "the_field",
727 source_range: [156; 156),
728 delete: [156; 156),
729 insert: "the_field",
730 kind: Field,
731 detail: "u32",
732 },
733 ]
734 "###
724 ); 735 );
725 } 736 }
726 737
@@ -752,6 +763,43 @@ mod tests {
752 } 763 }
753 764
754 #[test] 765 #[test]
766 fn macro_expansion_resilient() {
767 assert_debug_snapshot!(
768 do_ref_completion(
769 r"
770 macro_rules! dbg {
771 () => {};
772 ($val:expr) => {
773 match $val { tmp => { tmp } }
774 };
775 // Trailing comma with single argument is ignored
776 ($val:expr,) => { $crate::dbg!($val) };
777 ($($val:expr),+ $(,)?) => {
778 ($($crate::dbg!($val)),+,)
779 };
780 }
781 struct A { the_field: u32 }
782 fn foo(a: A) {
783 dbg!(a.<|>)
784 }
785 ",
786 ),
787 @r###"
788 [
789 CompletionItem {
790 label: "the_field",
791 source_range: [552; 552),
792 delete: [552; 552),
793 insert: "the_field",
794 kind: Field,
795 detail: "u32",
796 },
797 ]
798 "###
799 );
800 }
801
802 #[test]
755 fn test_method_completion_3547() { 803 fn test_method_completion_3547() {
756 assert_debug_snapshot!( 804 assert_debug_snapshot!(
757 do_ref_completion( 805 do_ref_completion(
diff --git a/crates/ra_ide/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs
index 6a1a66ef1..cb84bb934 100644
--- a/crates/ra_ide/src/completion/complete_pattern.rs
+++ b/crates/ra_ide/src/completion/complete_pattern.rs
@@ -89,7 +89,6 @@ mod tests {
89 89
90 #[test] 90 #[test]
91 fn completes_in_simple_macro_call() { 91 fn completes_in_simple_macro_call() {
92 // FIXME: doesn't work yet because of missing error recovery in macro expansion
93 let completions = complete( 92 let completions = complete(
94 r" 93 r"
95 macro_rules! m { ($e:expr) => { $e } } 94 macro_rules! m { ($e:expr) => { $e } }
@@ -102,6 +101,16 @@ mod tests {
102 } 101 }
103 ", 102 ",
104 ); 103 );
105 assert_debug_snapshot!(completions, @r###"[]"###); 104 assert_debug_snapshot!(completions, @r###"
105 [
106 CompletionItem {
107 label: "E",
108 source_range: [151; 151),
109 delete: [151; 151),
110 insert: "E",
111 kind: Enum,
112 },
113 ]
114 "###);
106 } 115 }
107} 116}
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs
index 5ffff5a1c..81d3cc1b6 100644
--- a/crates/ra_ide/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_scope.rs
@@ -811,7 +811,44 @@ mod tests {
811 } 811 }
812 " 812 "
813 ), 813 ),
814 @"[]" 814 @r###"
815 [
816 CompletionItem {
817 label: "m!",
818 source_range: [145; 145),
819 delete: [145; 145),
820 insert: "m!($0)",
821 kind: Macro,
822 detail: "macro_rules! m",
823 },
824 CompletionItem {
825 label: "quux(…)",
826 source_range: [145; 145),
827 delete: [145; 145),
828 insert: "quux(${1:x})$0",
829 kind: Function,
830 lookup: "quux",
831 detail: "fn quux(x: i32)",
832 trigger_call_info: true,
833 },
834 CompletionItem {
835 label: "x",
836 source_range: [145; 145),
837 delete: [145; 145),
838 insert: "x",
839 kind: Binding,
840 detail: "i32",
841 },
842 CompletionItem {
843 label: "y",
844 source_range: [145; 145),
845 delete: [145; 145),
846 insert: "y",
847 kind: Binding,
848 detail: "i32",
849 },
850 ]
851 "###
815 ); 852 );
816 } 853 }
817 854
@@ -869,6 +906,59 @@ mod tests {
869 } 906 }
870 907
871 #[test] 908 #[test]
909 fn completes_in_simple_macro_without_closing_parens() {
910 assert_debug_snapshot!(
911 do_reference_completion(
912 r"
913 macro_rules! m { ($e:expr) => { $e } }
914 fn quux(x: i32) {
915 let y = 92;
916 m!(x<|>
917 }
918 "
919 ),
920 @r###"
921 [
922 CompletionItem {
923 label: "m!",
924 source_range: [145; 146),
925 delete: [145; 146),
926 insert: "m!($0)",
927 kind: Macro,
928 detail: "macro_rules! m",
929 },
930 CompletionItem {
931 label: "quux(…)",
932 source_range: [145; 146),
933 delete: [145; 146),
934 insert: "quux(${1:x})$0",
935 kind: Function,
936 lookup: "quux",
937 detail: "fn quux(x: i32)",
938 trigger_call_info: true,
939 },
940 CompletionItem {
941 label: "x",
942 source_range: [145; 146),
943 delete: [145; 146),
944 insert: "x",
945 kind: Binding,
946 detail: "i32",
947 },
948 CompletionItem {
949 label: "y",
950 source_range: [145; 146),
951 delete: [145; 146),
952 insert: "y",
953 kind: Binding,
954 detail: "i32",
955 },
956 ]
957 "###
958 );
959 }
960
961 #[test]
872 fn completes_unresolved_uses() { 962 fn completes_unresolved_uses() {
873 assert_debug_snapshot!( 963 assert_debug_snapshot!(
874 do_reference_completion( 964 do_reference_completion(
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 3646fb8dc..54589a2a8 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -135,7 +135,7 @@ impl<'a> CompletionContext<'a> {
135 ), 135 ),
136 ) { 136 ) {
137 let new_offset = hypothetical_expansion.1.text_range().start(); 137 let new_offset = hypothetical_expansion.1.text_range().start();
138 if new_offset >= actual_expansion.text_range().end() { 138 if new_offset > actual_expansion.text_range().end() {
139 break; 139 break;
140 } 140 }
141 original_file = actual_expansion; 141 original_file = actual_expansion;
diff --git a/crates/ra_ide/src/expand_macro.rs b/crates/ra_ide/src/expand_macro.rs
index f6667cb33..e58526f31 100644
--- a/crates/ra_ide/src/expand_macro.rs
+++ b/crates/ra_ide/src/expand_macro.rs
@@ -259,7 +259,7 @@ fn some_thing() -> u32 {
259 ); 259 );
260 260
261 assert_eq!(res.name, "foo"); 261 assert_eq!(res.name, "foo");
262 assert_snapshot!(res.expansion, @r###"bar!()"###); 262 assert_snapshot!(res.expansion, @r###""###);
263 } 263 }
264 264
265 #[test] 265 #[test]