mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Fix: Handle block exprs as modules when finding their parents
This commit is contained in:
parent
28830ff2f1
commit
e09c2a08d7
4 changed files with 46 additions and 7 deletions
|
@ -497,10 +497,9 @@ impl Module {
|
||||||
|
|
||||||
/// Finds a parent module.
|
/// Finds a parent module.
|
||||||
pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> {
|
pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> {
|
||||||
// FIXME: handle block expressions as modules (their parent is in a different DefMap)
|
|
||||||
let def_map = self.id.def_map(db.upcast());
|
let def_map = self.id.def_map(db.upcast());
|
||||||
let parent_id = def_map[self.id.local_id].parent?;
|
let parent_id = def_map.containing_module(self.id.local_id)?;
|
||||||
Some(Module { id: def_map.module_id(parent_id) })
|
Some(Module { id: parent_id })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds nearest non-block ancestor `Module` (`self` included).
|
/// Finds nearest non-block ancestor `Module` (`self` included).
|
||||||
|
|
|
@ -7,7 +7,8 @@ mod tests;
|
||||||
use std::{iter, ops::ControlFlow};
|
use std::{iter, ops::ControlFlow};
|
||||||
|
|
||||||
use hir::{
|
use hir::{
|
||||||
HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo,
|
HasAttrs, Local, ModuleSource, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type,
|
||||||
|
TypeInfo,
|
||||||
};
|
};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::SourceDatabase, famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition,
|
base_db::SourceDatabase, famous_defs::FamousDefs, helpers::is_editable_crate, FilePosition,
|
||||||
|
@ -743,7 +744,12 @@ impl<'a> CompletionContext<'a> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let depth_from_crate_root = iter::successors(module.parent(db), |m| m.parent(db)).count();
|
let depth_from_crate_root = iter::successors(Some(module), |m| m.parent(db))
|
||||||
|
// `BlockExpr` modules are not count as module depth
|
||||||
|
.filter(|m| !matches!(m.definition_source(db).value, ModuleSource::BlockExpr(_)))
|
||||||
|
.count()
|
||||||
|
// exclude `m` itself
|
||||||
|
.saturating_sub(1);
|
||||||
|
|
||||||
let complete_semicolon = if config.add_semicolon_to_unit {
|
let complete_semicolon = if config.add_semicolon_to_unit {
|
||||||
let inside_closure_ret = token.parent_ancestors().try_for_each(|ancestor| {
|
let inside_closure_ret = token.parent_ancestors().try_for_each(|ancestor| {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::{mem, ops::Not};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{
|
use hir::{
|
||||||
db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind,
|
db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, AssocItemContainer, CaptureKind,
|
||||||
DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError,
|
DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError,
|
||||||
MethodViolationCode, Name, Semantics, Trait, Type, TypeInfo,
|
MethodViolationCode, Name, Semantics, Trait, Type, TypeInfo,
|
||||||
};
|
};
|
||||||
|
@ -813,7 +813,15 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition, edition: Edition) ->
|
||||||
if matches!(def, Definition::GenericParam(_) | Definition::Local(_) | Definition::Label(_)) {
|
if matches!(def, Definition::GenericParam(_) | Definition::Local(_) | Definition::Label(_)) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
def.module(db).map(|module| path(db, module, definition_owner_name(db, def, edition), edition))
|
let container: Option<Definition> =
|
||||||
|
def.as_assoc_item(db).and_then(|assoc| match assoc.container(db) {
|
||||||
|
AssocItemContainer::Trait(trait_) => Some(trait_.into()),
|
||||||
|
AssocItemContainer::Impl(impl_) => impl_.self_ty(db).as_adt().map(|adt| adt.into()),
|
||||||
|
});
|
||||||
|
container
|
||||||
|
.unwrap_or(*def)
|
||||||
|
.module(db)
|
||||||
|
.map(|module| path(db, module, definition_owner_name(db, def, edition), edition))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Markup {
|
fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Markup {
|
||||||
|
|
|
@ -8962,3 +8962,29 @@ fn test_hover_function_with_pat_param() {
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hover_path_inside_block_scope() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
mod m {
|
||||||
|
const _: () = {
|
||||||
|
mod m2 {
|
||||||
|
const C$0: () = ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
*C*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test::m::m2
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const C: () = ()
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue