Auto merge of #16582 - Veykril:find-path-length, r=Veykril
fix: Respect textual length of paths in find-path Fixes https://github.com/rust-lang/rust-analyzer/issues/16572
This commit is contained in:
commit
a01655552d
@ -447,18 +447,25 @@ fn select_best_path(
|
||||
}
|
||||
const STD_CRATES: [Name; 3] = [known::std, known::core, known::alloc];
|
||||
|
||||
let choose = |new_path: (ModPath, _), old_path: (ModPath, _)| {
|
||||
let new_has_prelude = new_path.0.segments().iter().any(|seg| seg == &known::prelude);
|
||||
let old_has_prelude = old_path.0.segments().iter().any(|seg| seg == &known::prelude);
|
||||
let choose = |new: (ModPath, _), old: (ModPath, _)| {
|
||||
let (new_path, _) = &new;
|
||||
let (old_path, _) = &old;
|
||||
let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude);
|
||||
let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude);
|
||||
match (new_has_prelude, old_has_prelude, prefer_prelude) {
|
||||
(true, false, true) | (false, true, false) => new_path,
|
||||
(true, false, false) | (false, true, true) => old_path,
|
||||
// no prelude difference in the paths, so pick the smaller one
|
||||
(true, false, true) | (false, true, false) => new,
|
||||
(true, false, false) | (false, true, true) => old,
|
||||
// no prelude difference in the paths, so pick the shorter one
|
||||
(true, true, _) | (false, false, _) => {
|
||||
if new_path.0.len() < old_path.0.len() {
|
||||
new_path
|
||||
let new_path_is_shorter = new_path
|
||||
.len()
|
||||
.cmp(&old_path.len())
|
||||
.then_with(|| new_path.textual_len().cmp(&old_path.textual_len()))
|
||||
.is_lt();
|
||||
if new_path_is_shorter {
|
||||
new
|
||||
} else {
|
||||
old_path
|
||||
old
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -469,8 +476,8 @@ fn select_best_path(
|
||||
let rank = match prefer_no_std {
|
||||
false => |name: &Name| match name {
|
||||
name if name == &known::core => 0,
|
||||
name if name == &known::alloc => 0,
|
||||
name if name == &known::std => 1,
|
||||
name if name == &known::alloc => 1,
|
||||
name if name == &known::std => 2,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
true => |name: &Name| match name {
|
||||
@ -1539,4 +1546,38 @@ pub mod foo {
|
||||
"krate::prelude::Foo",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn respect_segment_length() {
|
||||
check_found_path(
|
||||
r#"
|
||||
//- /main.rs crate:main deps:petgraph
|
||||
$0
|
||||
//- /petgraph.rs crate:petgraph
|
||||
pub mod graph {
|
||||
pub use crate::graph_impl::{
|
||||
NodeIndex
|
||||
};
|
||||
}
|
||||
|
||||
mod graph_impl {
|
||||
pub struct NodeIndex<Ix>(Ix);
|
||||
}
|
||||
|
||||
pub mod stable_graph {
|
||||
#[doc(no_inline)]
|
||||
pub use crate::graph::{NodeIndex};
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
#[doc(no_inline)]
|
||||
pub use crate::graph::{NodeIndex};
|
||||
}
|
||||
"#,
|
||||
"petgraph::graph::NodeIndex",
|
||||
"petgraph::graph::NodeIndex",
|
||||
"petgraph::graph::NodeIndex",
|
||||
"petgraph::graph::NodeIndex",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +182,7 @@ pub enum Expr {
|
||||
tail: Option<ExprId>,
|
||||
},
|
||||
Const(ConstBlockId),
|
||||
// FIXME: Fold this into Block with an unsafe flag?
|
||||
Unsafe {
|
||||
id: Option<BlockId>,
|
||||
statements: Box<[Statement]>,
|
||||
|
@ -94,6 +94,21 @@ pub fn len(&self) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn textual_len(&self) -> usize {
|
||||
let base = match self.kind {
|
||||
PathKind::Plain => 0,
|
||||
PathKind::Super(0) => "self".len(),
|
||||
PathKind::Super(i) => "super".len() * i as usize,
|
||||
PathKind::Crate => "crate".len(),
|
||||
PathKind::Abs => 0,
|
||||
PathKind::DollarCrate(_) => "$crate".len(),
|
||||
};
|
||||
self.segments()
|
||||
.iter()
|
||||
.map(|segment| segment.as_str().map_or(0, str::len))
|
||||
.fold(base, core::ops::Add::add)
|
||||
}
|
||||
|
||||
pub fn is_ident(&self) -> bool {
|
||||
self.as_ident().is_some()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user