mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-12-23 08:48:08 +00:00
Fix handling of blocks modules that are not the root module
This commit is contained in:
parent
7c810e9994
commit
44227800c6
8 changed files with 64 additions and 51 deletions
|
|
@ -370,18 +370,13 @@ impl<'a> Ctx<'a> {
|
||||||
});
|
});
|
||||||
match &vis {
|
match &vis {
|
||||||
RawVisibility::Public => RawVisibilityId::PUB,
|
RawVisibility::Public => RawVisibilityId::PUB,
|
||||||
RawVisibility::Module(path, explicitness) if path.segments().is_empty() => {
|
RawVisibility::PubSelf(VisibilityExplicitness::Explicit) => {
|
||||||
match (path.kind, explicitness) {
|
|
||||||
(PathKind::SELF, VisibilityExplicitness::Explicit) => {
|
|
||||||
RawVisibilityId::PRIV_EXPLICIT
|
RawVisibilityId::PRIV_EXPLICIT
|
||||||
}
|
}
|
||||||
(PathKind::SELF, VisibilityExplicitness::Implicit) => {
|
RawVisibility::PubSelf(VisibilityExplicitness::Implicit) => {
|
||||||
RawVisibilityId::PRIV_IMPLICIT
|
RawVisibilityId::PRIV_IMPLICIT
|
||||||
}
|
}
|
||||||
(PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
|
RawVisibility::PubCrate => RawVisibilityId::PUB_CRATE,
|
||||||
_ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
|
_ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -466,10 +461,7 @@ pub(crate) fn lower_use_tree(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn private_vis() -> RawVisibility {
|
fn private_vis() -> RawVisibility {
|
||||||
RawVisibility::Module(
|
RawVisibility::PubSelf(VisibilityExplicitness::Implicit)
|
||||||
Interned::new(ModPath::from_kind(PathKind::SELF)),
|
|
||||||
VisibilityExplicitness::Implicit,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn visibility_from_ast(
|
pub(crate) fn visibility_from_ast(
|
||||||
|
|
@ -486,9 +478,11 @@ pub(crate) fn visibility_from_ast(
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::VisibilityKind::PubCrate => ModPath::from_kind(PathKind::Crate),
|
ast::VisibilityKind::PubCrate => return RawVisibility::PubCrate,
|
||||||
ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)),
|
ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)),
|
||||||
ast::VisibilityKind::PubSelf => ModPath::from_kind(PathKind::SELF),
|
ast::VisibilityKind::PubSelf => {
|
||||||
|
return RawVisibility::PubSelf(VisibilityExplicitness::Explicit);
|
||||||
|
}
|
||||||
ast::VisibilityKind::Pub => return RawVisibility::Public,
|
ast::VisibilityKind::Pub => return RawVisibility::Public,
|
||||||
};
|
};
|
||||||
RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit)
|
RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit)
|
||||||
|
|
|
||||||
|
|
@ -1075,7 +1075,9 @@ fn resolver_for_scope_<'db>(
|
||||||
if let Some(block) = scopes.block(scope) {
|
if let Some(block) = scopes.block(scope) {
|
||||||
let def_map = block_def_map(db, block);
|
let def_map = block_def_map(db, block);
|
||||||
let local_def_map = block.lookup(db).module.only_local_def_map(db);
|
let local_def_map = block.lookup(db).module.only_local_def_map(db);
|
||||||
r = r.push_block_scope(def_map, local_def_map);
|
// Using `DefMap::ROOT` is okay here since inside modules other than the root,
|
||||||
|
// there can't directly be expressions.
|
||||||
|
r = r.push_block_scope(def_map, local_def_map, DefMap::ROOT);
|
||||||
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
||||||
// already traverses all parents, so this is O(n²). I think we could only store the
|
// already traverses all parents, so this is O(n²). I think we could only store the
|
||||||
// innermost module scope instead?
|
// innermost module scope instead?
|
||||||
|
|
@ -1108,12 +1110,9 @@ impl<'db> Resolver<'db> {
|
||||||
self,
|
self,
|
||||||
def_map: &'db DefMap,
|
def_map: &'db DefMap,
|
||||||
local_def_map: &'db LocalDefMap,
|
local_def_map: &'db LocalDefMap,
|
||||||
|
module_id: LocalModuleId,
|
||||||
) -> Resolver<'db> {
|
) -> Resolver<'db> {
|
||||||
self.push_scope(Scope::BlockScope(ModuleItemMap {
|
self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, module_id }))
|
||||||
def_map,
|
|
||||||
local_def_map,
|
|
||||||
module_id: DefMap::ROOT,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_expr_scope(
|
fn push_expr_scope(
|
||||||
|
|
@ -1273,7 +1272,7 @@ impl HasResolver for ModuleId {
|
||||||
let (mut def_map, local_def_map) = self.local_def_map(db);
|
let (mut def_map, local_def_map) = self.local_def_map(db);
|
||||||
let mut module_id = self.local_id;
|
let mut module_id = self.local_id;
|
||||||
|
|
||||||
if !self.is_block_module() {
|
if !self.is_within_block() {
|
||||||
return Resolver {
|
return Resolver {
|
||||||
scopes: vec![],
|
scopes: vec![],
|
||||||
module_scope: ModuleItemMap { def_map, local_def_map, module_id },
|
module_scope: ModuleItemMap { def_map, local_def_map, module_id },
|
||||||
|
|
@ -1283,9 +1282,9 @@ impl HasResolver for ModuleId {
|
||||||
let mut modules: SmallVec<[_; 1]> = smallvec![];
|
let mut modules: SmallVec<[_; 1]> = smallvec![];
|
||||||
while let Some(parent) = def_map.parent() {
|
while let Some(parent) = def_map.parent() {
|
||||||
let block_def_map = mem::replace(&mut def_map, parent.def_map(db));
|
let block_def_map = mem::replace(&mut def_map, parent.def_map(db));
|
||||||
modules.push(block_def_map);
|
let block_module_id = mem::replace(&mut module_id, parent.local_id);
|
||||||
if !parent.is_block_module() {
|
modules.push((block_def_map, block_module_id));
|
||||||
module_id = parent.local_id;
|
if !parent.is_within_block() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1293,8 +1292,8 @@ impl HasResolver for ModuleId {
|
||||||
scopes: Vec::with_capacity(modules.len()),
|
scopes: Vec::with_capacity(modules.len()),
|
||||||
module_scope: ModuleItemMap { def_map, local_def_map, module_id },
|
module_scope: ModuleItemMap { def_map, local_def_map, module_id },
|
||||||
};
|
};
|
||||||
for def_map in modules.into_iter().rev() {
|
for (def_map, module_id) in modules.into_iter().rev() {
|
||||||
resolver = resolver.push_block_scope(def_map, local_def_map);
|
resolver = resolver.push_block_scope(def_map, local_def_map, module_id);
|
||||||
}
|
}
|
||||||
resolver
|
resolver
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,18 +289,21 @@ pub(crate) fn field_visibilities_query(
|
||||||
|
|
||||||
pub fn visibility_from_ast(
|
pub fn visibility_from_ast(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
has_resolver: impl HasResolver,
|
has_resolver: impl HasResolver + HasModule,
|
||||||
ast_vis: InFile<Option<ast::Visibility>>,
|
ast_vis: InFile<Option<ast::Visibility>>,
|
||||||
) -> Visibility {
|
) -> Visibility {
|
||||||
let mut span_map = None;
|
let mut span_map = None;
|
||||||
let raw_vis = crate::item_tree::visibility_from_ast(db, ast_vis.value, &mut |range| {
|
let raw_vis = crate::item_tree::visibility_from_ast(db, ast_vis.value, &mut |range| {
|
||||||
span_map.get_or_insert_with(|| db.span_map(ast_vis.file_id)).span_for_range(range).ctx
|
span_map.get_or_insert_with(|| db.span_map(ast_vis.file_id)).span_for_range(range).ctx
|
||||||
});
|
});
|
||||||
if raw_vis == RawVisibility::Public {
|
match raw_vis {
|
||||||
return Visibility::Public;
|
RawVisibility::PubSelf(explicitness) => {
|
||||||
|
Visibility::Module(has_resolver.module(db), explicitness)
|
||||||
|
}
|
||||||
|
RawVisibility::PubCrate => Visibility::PubCrate(has_resolver.krate(db)),
|
||||||
|
RawVisibility::Public => Visibility::Public,
|
||||||
|
RawVisibility::Module(..) => Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis),
|
||||||
}
|
}
|
||||||
|
|
||||||
Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve visibility of a type alias.
|
/// Resolve visibility of a type alias.
|
||||||
|
|
|
||||||
|
|
@ -2078,9 +2078,10 @@ pub fn write_visibility<'db>(
|
||||||
if vis_id == module_id {
|
if vis_id == module_id {
|
||||||
// pub(self) or omitted
|
// pub(self) or omitted
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if root_module_id == vis_id {
|
} else if root_module_id == vis_id && !root_module_id.is_within_block() {
|
||||||
write!(f, "pub(crate) ")
|
write!(f, "pub(crate) ")
|
||||||
} else if module_id.containing_module(f.db) == Some(vis_id) {
|
} else if module_id.containing_module(f.db) == Some(vis_id) && !vis_id.is_block_module()
|
||||||
|
{
|
||||||
write!(f, "pub(super) ")
|
write!(f, "pub(super) ")
|
||||||
} else {
|
} else {
|
||||||
write!(f, "pub(in ...) ")
|
write!(f, "pub(in ...) ")
|
||||||
|
|
|
||||||
|
|
@ -2506,3 +2506,19 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn foo() {
|
||||||
|
check_types(
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
mod my_mod {
|
||||||
|
pub type Bool = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _: my_mod::Bool;
|
||||||
|
// ^ bool
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1594,7 +1594,6 @@ fn resolve_hir_path_(
|
||||||
Some(unresolved) => resolver
|
Some(unresolved) => resolver
|
||||||
.generic_def()
|
.generic_def()
|
||||||
.and_then(|def| {
|
.and_then(|def| {
|
||||||
hir_ty::attach_db(db, || {
|
|
||||||
hir_ty::associated_type_shorthand_candidates(
|
hir_ty::associated_type_shorthand_candidates(
|
||||||
db,
|
db,
|
||||||
def,
|
def,
|
||||||
|
|
@ -1602,7 +1601,6 @@ fn resolve_hir_path_(
|
||||||
|name, _| name == unresolved.name,
|
|name, _| name == unresolved.name,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.map(TypeAlias::from)
|
.map(TypeAlias::from)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map(PathResolution::Def),
|
.map(PathResolution::Def),
|
||||||
|
|
|
||||||
|
|
@ -387,12 +387,14 @@ impl Definition {
|
||||||
return SearchScope::reverse_dependencies(db, module.krate());
|
return SearchScope::reverse_dependencies(db, module.krate());
|
||||||
}
|
}
|
||||||
|
|
||||||
let vis = self.visibility(db);
|
if let Some(vis) = self.visibility(db) {
|
||||||
if let Some(Visibility::Public) = vis {
|
return match vis {
|
||||||
return SearchScope::reverse_dependencies(db, module.krate());
|
Visibility::Module(module, _) => {
|
||||||
|
SearchScope::module_and_children(db, module.into())
|
||||||
}
|
}
|
||||||
if let Some(Visibility::Module(module, _)) = vis {
|
Visibility::PubCrate(krate) => SearchScope::krate(db, krate.into()),
|
||||||
return SearchScope::module_and_children(db, module.into());
|
Visibility::Public => SearchScope::reverse_dependencies(db, module.krate()),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let range = match module_source {
|
let range = match module_source {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||||
<span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="struct declaration macro public">Bar</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
<span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="struct declaration macro public">Bar</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
||||||
<span class="keyword">fn</span> <span class="function declaration">func</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="module">y</span><span class="operator">::</span><span class="struct public">Bar</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
<span class="keyword">fn</span> <span class="function declaration">func</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="module">y</span><span class="operator">::</span><span class="struct public">Bar</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||||
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span>
|
<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span>
|
||||||
<span class="keyword">struct</span> <span class="struct declaration">Innerest</span><span class="angle"><</span><span class="keyword const">const</span> <span class="const_param const declaration">C</span><span class="colon">:</span> <span class="unresolved_reference">usize</span><span class="angle">></span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="brace">{</span><span class="const_param const">C</span><span class="brace">}</span><span class="bracket">]</span> <span class="brace">}</span>
|
<span class="keyword">struct</span> <span class="struct declaration">Innerest</span><span class="angle"><</span><span class="keyword const">const</span> <span class="const_param const declaration">C</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">></span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="brace">{</span><span class="const_param const">C</span><span class="brace">}</span><span class="bracket">]</span> <span class="brace">}</span>
|
||||||
<span class="brace">}</span>
|
<span class="brace">}</span>
|
||||||
<span class="brace">}</span>
|
<span class="brace">}</span>
|
||||||
<span class="brace">}</span>
|
<span class="brace">}</span>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue