fix: imports_granularity module with path containing self

This commit is contained in:
Tom Milligan 2022-03-04 18:13:08 +00:00 committed by Caleb Cartwright
parent 18c0369688
commit b4de150dbc
3 changed files with 41 additions and 12 deletions

View File

@ -190,13 +190,17 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -
continue; continue;
} }
for flattened in use_tree.flatten() { for mut flattened in use_tree.flatten() {
if let Some(tree) = result if let Some(tree) = result
.iter_mut() .iter_mut()
.find(|tree| tree.share_prefix(&flattened, merge_by)) .find(|tree| tree.share_prefix(&flattened, merge_by))
{ {
tree.merge(&flattened, merge_by); tree.merge(&flattened, merge_by);
} else { } else {
// If this is the first tree with this prefix, handle potential trailing ::self
if merge_by == SharedPrefix::Module {
flattened = flattened.nest_trailing_self();
}
result.push(flattened); result.push(flattened);
} }
} }
@ -208,17 +212,7 @@ pub(crate) fn flatten_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
use_trees use_trees
.into_iter() .into_iter()
.flat_map(UseTree::flatten) .flat_map(UseTree::flatten)
.map(|mut tree| { .map(UseTree::nest_trailing_self)
// If a path ends in `::self`, rewrite it to `::{self}`.
if let Some(UseSegment::Slf(..)) = tree.path.last() {
let self_segment = tree.path.pop().unwrap();
tree.path.push(UseSegment::List(vec![UseTree::from_path(
vec![self_segment],
DUMMY_SP,
)]));
}
tree
})
.collect() .collect()
} }
@ -635,6 +629,18 @@ fn merge(&mut self, other: &UseTree, merge_by: SharedPrefix) {
self.span = self.span.to(other.span); self.span = self.span.to(other.span);
} }
} }
/// If this tree ends in `::self`, rewrite it to `::{self}`.
fn nest_trailing_self(mut self) -> UseTree {
if let Some(UseSegment::Slf(..)) = self.path.last() {
let self_segment = self.path.pop().unwrap();
self.path.push(UseSegment::List(vec![UseTree::from_path(
vec![self_segment],
DUMMY_SP,
)]));
}
self
}
} }
fn merge_rest( fn merge_rest(
@ -1311,4 +1317,24 @@ fn test_use_tree_ord() {
< parse_use_tree("std::cmp::{b, e, g, f}").normalize() < parse_use_tree("std::cmp::{b, e, g, f}").normalize()
); );
} }
#[test]
fn test_use_tree_nest_trailing_self() {
assert_eq!(
parse_use_tree("a::b::self").nest_trailing_self(),
parse_use_tree("a::b::{self}")
);
assert_eq!(
parse_use_tree("a::b::c").nest_trailing_self(),
parse_use_tree("a::b::c")
);
assert_eq!(
parse_use_tree("a::b::{c, d}").nest_trailing_self(),
parse_use_tree("a::b::{c, d}")
);
assert_eq!(
parse_use_tree("a::b::{self, c}").nest_trailing_self(),
parse_use_tree("a::b::{self, c}")
);
}
} }

View File

@ -4,6 +4,7 @@
use a::{f, g::{h, i}}; use a::{f, g::{h, i}};
use a::{j::{self, k::{self, l}, m}, n::{o::p, q}}; use a::{j::{self, k::{self, l}, m}, n::{o::p, q}};
pub use a::{r::s, t}; pub use a::{r::s, t};
use b::{c::d, self};
#[cfg(test)] #[cfg(test)]
use foo::{a::b, c::d}; use foo::{a::b, c::d};

View File

@ -10,6 +10,8 @@
use a::n::q; use a::n::q;
pub use a::r::s; pub use a::r::s;
pub use a::t; pub use a::t;
use b::c::d;
use b::{self};
use foo::e; use foo::e;
#[cfg(test)] #[cfg(test)]