aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-10-14 00:39:58 +0100
committerLukas Wirth <[email protected]>2020-10-14 00:43:56 +0100
commit03b77b03fefa4dc260b5a63223db253706d41ca8 (patch)
treed1be625f446431c12068bfdbd7ae162737671384 /crates/assists/src
parent0fb069c5b02072239891ce564feaa7d1890c6d6f (diff)
Fix stackoverflow in insert_use::recursive_merge
Diffstat (limited to 'crates/assists/src')
-rw-r--r--crates/assists/src/handlers/merge_imports.rs14
-rw-r--r--crates/assists/src/handlers/replace_qualified_name_with_use.rs17
-rw-r--r--crates/assists/src/utils/insert_use.rs24
3 files changed, 53 insertions, 2 deletions
diff --git a/crates/assists/src/handlers/merge_imports.rs b/crates/assists/src/handlers/merge_imports.rs
index fe33cee53..fd9c9e03c 100644
--- a/crates/assists/src/handlers/merge_imports.rs
+++ b/crates/assists/src/handlers/merge_imports.rs
@@ -73,6 +73,20 @@ mod tests {
73 use super::*; 73 use super::*;
74 74
75 #[test] 75 #[test]
76 fn test_merge_equal() {
77 check_assist(
78 merge_imports,
79 r"
80use std::fmt<|>::{Display, Debug};
81use std::fmt::{Display, Debug};
82",
83 r"
84use std::fmt::{Debug, Display};
85",
86 )
87 }
88
89 #[test]
76 fn test_merge_first() { 90 fn test_merge_first() {
77 check_assist( 91 check_assist(
78 merge_imports, 92 merge_imports,
diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
index e95b971a4..c50bc7604 100644
--- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
@@ -124,6 +124,23 @@ mod tests {
124 use super::*; 124 use super::*;
125 125
126 #[test] 126 #[test]
127 fn test_replace_already_imported() {
128 check_assist(
129 replace_qualified_name_with_use,
130 r"use std::fs;
131
132fn main() {
133 std::f<|>s::Path
134}",
135 r"use std::fs;
136
137fn main() {
138 fs::Path
139}",
140 )
141 }
142
143 #[test]
127 fn test_replace_add_use_no_anchor() { 144 fn test_replace_add_use_no_anchor() {
128 check_assist( 145 check_assist(
129 replace_qualified_name_with_use, 146 replace_qualified_name_with_use,
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index bfd457d18..409985b3b 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -173,8 +173,15 @@ pub(crate) fn try_merge_trees(
173 let rhs_path = rhs.path()?; 173 let rhs_path = rhs.path()?;
174 174
175 let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?; 175 let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?;
176 let lhs = lhs.split_prefix(&lhs_prefix); 176 let (lhs, rhs) = if is_simple_path(lhs)
177 let rhs = rhs.split_prefix(&rhs_prefix); 177 && is_simple_path(rhs)
178 && lhs_path == lhs_prefix
179 && rhs_path == rhs_prefix
180 {
181 (lhs.clone(), rhs.clone())
182 } else {
183 (lhs.split_prefix(&lhs_prefix), rhs.split_prefix(&rhs_prefix))
184 };
178 recursive_merge(&lhs, &rhs, merge) 185 recursive_merge(&lhs, &rhs, merge)
179} 186}
180 187
@@ -250,6 +257,10 @@ fn recursive_merge(
250 use_trees.insert(idx, make::glob_use_tree()); 257 use_trees.insert(idx, make::glob_use_tree());
251 continue; 258 continue;
252 } 259 }
260
261 if lhs_t.use_tree_list().is_none() && rhs_t.use_tree_list().is_none() {
262 continue;
263 }
253 } 264 }
254 let lhs = lhs_t.split_prefix(&lhs_prefix); 265 let lhs = lhs_t.split_prefix(&lhs_prefix);
255 let rhs = rhs_t.split_prefix(&rhs_prefix); 266 let rhs = rhs_t.split_prefix(&rhs_prefix);
@@ -295,6 +306,10 @@ fn common_prefix(lhs: &ast::Path, rhs: &ast::Path) -> Option<(ast::Path, ast::Pa
295 } 306 }
296} 307}
297 308
309fn is_simple_path(use_tree: &ast::UseTree) -> bool {
310 use_tree.use_tree_list().is_none() && use_tree.star_token().is_none()
311}
312
298fn path_is_self(path: &ast::Path) -> bool { 313fn path_is_self(path: &ast::Path) -> bool {
299 path.segment().and_then(|seg| seg.self_token()).is_some() && path.qualifier().is_none() 314 path.segment().and_then(|seg| seg.self_token()).is_some() && path.qualifier().is_none()
300} 315}
@@ -524,6 +539,11 @@ mod tests {
524 use test_utils::assert_eq_text; 539 use test_utils::assert_eq_text;
525 540
526 #[test] 541 #[test]
542 fn insert_existing() {
543 check_full("std::fs", "use std::fs;", "use std::fs;")
544 }
545
546 #[test]
527 fn insert_start() { 547 fn insert_start() {
528 check_none( 548 check_none(
529 "std::bar::AA", 549 "std::bar::AA",