mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Change resolve_path to return the fully resolved path or PerNs::none
This also adds new pub(crate) resolve_path_segments which returns the PathResult, which may or may not be fully resolved. PathResult is also now pub(crate) since it is an implementation detail.
This commit is contained in:
parent
39679d499f
commit
247d1c17b3
5 changed files with 38 additions and 36 deletions
|
@ -88,7 +88,7 @@ impl ImplBlock {
|
||||||
if let Some(TypeRef::Path(path)) = self.target_trait_ref(db) {
|
if let Some(TypeRef::Path(path)) = self.target_trait_ref(db) {
|
||||||
let resolver = self.resolver(db);
|
let resolver = self.resolver(db);
|
||||||
if let Some(Resolution::Def(ModuleDef::Trait(tr))) =
|
if let Some(Resolution::Def(ModuleDef::Trait(tr))) =
|
||||||
resolver.resolve_path(db, &path).into_per_ns().take_types()
|
resolver.resolve_path(db, &path).take_types()
|
||||||
{
|
{
|
||||||
return Some(tr);
|
return Some(tr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub(crate) struct ExprScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PathResult {
|
pub(crate) struct PathResult {
|
||||||
/// The actual path resolution
|
/// The actual path resolution
|
||||||
resolution: PerNs<Resolution>,
|
resolution: PerNs<Resolution>,
|
||||||
/// The first index in the path that we
|
/// The first index in the path that we
|
||||||
|
@ -45,7 +45,7 @@ pub struct PathResult {
|
||||||
impl PathResult {
|
impl PathResult {
|
||||||
/// Returns the remaining index in the result
|
/// Returns the remaining index in the result
|
||||||
/// returns None if the path was fully resolved
|
/// returns None if the path was fully resolved
|
||||||
pub fn remaining_index(&self) -> Option<usize> {
|
pub(crate) fn remaining_index(&self) -> Option<usize> {
|
||||||
if self.remaining_index > 0 {
|
if self.remaining_index > 0 {
|
||||||
Some(self.remaining_index)
|
Some(self.remaining_index)
|
||||||
} else {
|
} else {
|
||||||
|
@ -55,8 +55,8 @@ impl PathResult {
|
||||||
|
|
||||||
/// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
|
/// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
|
||||||
/// if the path was fully resolved, meaning we have no remaining items
|
/// if the path was fully resolved, meaning we have no remaining items
|
||||||
pub fn into_per_ns(self) -> PerNs<Resolution> {
|
pub(crate) fn into_fully_resolved(self) -> PerNs<Resolution> {
|
||||||
if self.remaining_index().is_none() {
|
if self.is_fully_resolved() {
|
||||||
self.resolution
|
self.resolution
|
||||||
} else {
|
} else {
|
||||||
PerNs::none()
|
PerNs::none()
|
||||||
|
@ -65,23 +65,17 @@ impl PathResult {
|
||||||
|
|
||||||
/// Consumes `PathResult` and returns the resolution and the
|
/// Consumes `PathResult` and returns the resolution and the
|
||||||
/// remaining_index as a tuple.
|
/// remaining_index as a tuple.
|
||||||
pub fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) {
|
pub(crate) fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) {
|
||||||
let index = self.remaining_index();
|
let index = self.remaining_index();
|
||||||
(self.resolution, index)
|
(self.resolution, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Path is fully resolved when `remaining_index` is none
|
/// Path is fully resolved when `remaining_index` is none
|
||||||
/// and the resolution contains anything
|
/// and the resolution contains anything
|
||||||
pub fn is_fully_resolved(&self) -> bool {
|
pub(crate) fn is_fully_resolved(&self) -> bool {
|
||||||
!self.resolution.is_none() && self.remaining_index().is_none()
|
!self.resolution.is_none() && self.remaining_index().is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Empty path result is where the resolution is `none`
|
|
||||||
/// and the remaining index is 0
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.resolution.is_none() && self.remaining_index().is_none()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn empty() -> PathResult {
|
fn empty() -> PathResult {
|
||||||
PathResult { resolution: PerNs::none(), remaining_index: 0 }
|
PathResult { resolution: PerNs::none(), remaining_index: 0 }
|
||||||
}
|
}
|
||||||
|
@ -134,7 +128,9 @@ impl Resolver {
|
||||||
resolution
|
resolution
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
|
/// Returns the resolved path segments
|
||||||
|
/// Which may be fully resolved, empty or partially resolved.
|
||||||
|
pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
|
||||||
if let Some(name) = path.as_ident() {
|
if let Some(name) = path.as_ident() {
|
||||||
PathResult::from_resolution(self.resolve_name(db, name))
|
PathResult::from_resolution(self.resolve_name(db, name))
|
||||||
} else if path.is_self() {
|
} else if path.is_self() {
|
||||||
|
@ -156,6 +152,13 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the fully resolved path if we were able to resolve it.
|
||||||
|
/// otherwise returns `PerNs::none`
|
||||||
|
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> {
|
||||||
|
// into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise
|
||||||
|
self.resolve_path_segments(db, path).into_fully_resolved()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> {
|
pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> {
|
||||||
let mut names = FxHashMap::default();
|
let mut names = FxHashMap::default();
|
||||||
for scope in self.scopes.iter().rev() {
|
for scope in self.scopes.iter().rev() {
|
||||||
|
|
|
@ -370,7 +370,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the path (in type namespace)
|
// Resolve the path (in type namespace)
|
||||||
let resolution = resolver.resolve_path(db, path).into_per_ns().take_types();
|
let resolution = resolver.resolve_path(db, path).take_types();
|
||||||
|
|
||||||
let def = match resolution {
|
let def = match resolution {
|
||||||
Some(Resolution::Def(def)) => def,
|
Some(Resolution::Def(def)) => def,
|
||||||
|
@ -1172,7 +1172,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
|
fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
|
||||||
let resolved = resolver.resolve_path(self.db, &path);
|
let resolved = resolver.resolve_path_segments(self.db, &path);
|
||||||
|
|
||||||
let (def, remaining_index) = resolved.into_inner();
|
let (def, remaining_index) = resolved.into_inner();
|
||||||
|
|
||||||
|
@ -1244,8 +1244,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
None => return (Ty::Unknown, None),
|
None => return (Ty::Unknown, None),
|
||||||
};
|
};
|
||||||
let resolver = &self.resolver;
|
let resolver = &self.resolver;
|
||||||
let typable: Option<TypableDef> =
|
let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() {
|
||||||
match resolver.resolve_path(self.db, &path).into_per_ns().take_types() {
|
|
||||||
Some(Resolution::Def(def)) => def.into(),
|
Some(Resolution::Def(def)) => def.into(),
|
||||||
Some(Resolution::LocalBinding(..)) => {
|
Some(Resolution::LocalBinding(..)) => {
|
||||||
// this cannot happen
|
// this cannot happen
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
Some(path) => path.clone(),
|
Some(path) => path.clone(),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let def = match ctx.resolver.resolve_path(ctx.db, &path).into_per_ns().take_types() {
|
let def = match ctx.resolver.resolve_path(ctx.db, &path).take_types() {
|
||||||
Some(Resolution::Def(def)) => def,
|
Some(Resolution::Def(def)) => def,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn reference_definition(
|
||||||
if let Some(path) =
|
if let Some(path) =
|
||||||
name_ref.syntax().ancestors().find_map(ast::Path::cast).and_then(hir::Path::from_ast)
|
name_ref.syntax().ancestors().find_map(ast::Path::cast).and_then(hir::Path::from_ast)
|
||||||
{
|
{
|
||||||
let resolved = resolver.resolve_path(db, &path).into_per_ns();
|
let resolved = resolver.resolve_path(db, &path);
|
||||||
match resolved.clone().take_types().or_else(|| resolved.take_values()) {
|
match resolved.clone().take_types().or_else(|| resolved.take_values()) {
|
||||||
Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)),
|
Some(Resolution::Def(def)) => return Exact(NavigationTarget::from_def(db, def)),
|
||||||
Some(Resolution::LocalBinding(pat)) => {
|
Some(Resolution::LocalBinding(pat)) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue