diff options
author | Lukas Wirth <[email protected]> | 2020-09-12 22:54:49 +0100 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2020-09-12 22:54:49 +0100 |
commit | b874721752e07673f28ef07a003fe8582d4f1645 (patch) | |
tree | 42b4c9db2325eaac38c2a73bb24c506755db650d /crates | |
parent | cd6cd91bf345d47cbf22e00fc4cddced4ae67ae6 (diff) |
Fix merge imports failing if the `self` module import is in the wrong tree
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/utils/insert_use.rs | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs index 99f0b5b75..4972085d6 100644 --- a/crates/assists/src/utils/insert_use.rs +++ b/crates/assists/src/utils/insert_use.rs | |||
@@ -149,31 +149,31 @@ fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) - | |||
149 | } | 149 | } |
150 | 150 | ||
151 | pub(crate) fn try_merge_imports( | 151 | pub(crate) fn try_merge_imports( |
152 | old: &ast::Use, | 152 | lhs: &ast::Use, |
153 | new: &ast::Use, | 153 | rhs: &ast::Use, |
154 | merge_behaviour: MergeBehaviour, | 154 | merge_behaviour: MergeBehaviour, |
155 | ) -> Option<ast::Use> { | 155 | ) -> Option<ast::Use> { |
156 | // don't merge imports with different visibilities | 156 | // don't merge imports with different visibilities |
157 | if !eq_visibility(old.visibility(), new.visibility()) { | 157 | if !eq_visibility(lhs.visibility(), rhs.visibility()) { |
158 | return None; | 158 | return None; |
159 | } | 159 | } |
160 | let old_tree = old.use_tree()?; | 160 | let lhs_tree = lhs.use_tree()?; |
161 | let new_tree = new.use_tree()?; | 161 | let rhs_tree = rhs.use_tree()?; |
162 | let merged = try_merge_trees(&old_tree, &new_tree, merge_behaviour)?; | 162 | let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behaviour)?; |
163 | Some(old.with_use_tree(merged)) | 163 | Some(lhs.with_use_tree(merged)) |
164 | } | 164 | } |
165 | 165 | ||
166 | pub(crate) fn try_merge_trees( | 166 | pub(crate) fn try_merge_trees( |
167 | old: &ast::UseTree, | 167 | lhs: &ast::UseTree, |
168 | new: &ast::UseTree, | 168 | rhs: &ast::UseTree, |
169 | merge: MergeBehaviour, | 169 | merge: MergeBehaviour, |
170 | ) -> Option<ast::UseTree> { | 170 | ) -> Option<ast::UseTree> { |
171 | let lhs_path = old.path()?; | 171 | let lhs_path = lhs.path()?; |
172 | let rhs_path = new.path()?; | 172 | let rhs_path = rhs.path()?; |
173 | 173 | ||
174 | let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?; | 174 | let (lhs_prefix, rhs_prefix) = common_prefix(&lhs_path, &rhs_path)?; |
175 | let lhs = old.split_prefix(&lhs_prefix); | 175 | let lhs = lhs.split_prefix(&lhs_prefix); |
176 | let rhs = new.split_prefix(&rhs_prefix); | 176 | let rhs = rhs.split_prefix(&rhs_prefix); |
177 | recursive_merge(&lhs, &rhs, merge).map(|(merged, _)| merged) | 177 | recursive_merge(&lhs, &rhs, merge).map(|(merged, _)| merged) |
178 | } | 178 | } |
179 | 179 | ||
@@ -209,13 +209,18 @@ fn recursive_merge( | |||
209 | }; | 209 | }; |
210 | // check if only one of the two trees has a tree list, and whether that then contains `self` or not. | 210 | // check if only one of the two trees has a tree list, and whether that then contains `self` or not. |
211 | // If this is the case we can skip this iteration since the path without the list is already included in the other one via `self` | 211 | // If this is the case we can skip this iteration since the path without the list is already included in the other one via `self` |
212 | if lhs_t | 212 | let tree_contains_self = |tree: &ast::UseTree| { |
213 | .use_tree_list() | 213 | tree.use_tree_list() |
214 | .xor(rhs_t.use_tree_list()) | 214 | .map(|tree_list| tree_list.use_trees().any(tree_is_self)) |
215 | .map(|tree_list| tree_list.use_trees().any(tree_is_self)) | 215 | .unwrap_or(false) |
216 | .unwrap_or(false) | 216 | }; |
217 | { | 217 | match (tree_contains_self(&lhs_t), tree_contains_self(&rhs_t)) { |
218 | continue; | 218 | (true, false) => continue, |
219 | (false, true) => { | ||
220 | *lhs_t = rhs_t; | ||
221 | continue; | ||
222 | } | ||
223 | _ => (), | ||
219 | } | 224 | } |
220 | 225 | ||
221 | // glob imports arent part of the use-tree lists so we need to special handle them here as well | 226 | // glob imports arent part of the use-tree lists so we need to special handle them here as well |
@@ -255,6 +260,13 @@ fn recursive_merge( | |||
255 | None => use_trees.insert(idx, rhs_t), | 260 | None => use_trees.insert(idx, rhs_t), |
256 | } | 261 | } |
257 | } | 262 | } |
263 | Err(_) | ||
264 | if merge == MergeBehaviour::Last | ||
265 | && use_trees.len() > 0 | ||
266 | && rhs_t.use_tree_list().is_some() => | ||
267 | { | ||
268 | return None | ||
269 | } | ||
258 | Err(idx) => { | 270 | Err(idx) => { |
259 | use_trees.insert(idx, rhs_t); | 271 | use_trees.insert(idx, rhs_t); |
260 | } | 272 | } |
@@ -819,8 +831,8 @@ use std::io;", | |||
819 | fn merge_glob_nested() { | 831 | fn merge_glob_nested() { |
820 | check_full( | 832 | check_full( |
821 | "foo::bar::quux::Fez", | 833 | "foo::bar::quux::Fez", |
822 | r"use foo::bar::{Baz, quux::*;", | 834 | r"use foo::bar::{Baz, quux::*};", |
823 | r"use foo::bar::{Baz, quux::{self::*, Fez}}", | 835 | r"use foo::bar::{Baz, quux::{self::*, Fez}};", |
824 | ) | 836 | ) |
825 | } | 837 | } |
826 | 838 | ||