db: &dyn DefDatabase,
node: InFile<Option<ast::Visibility>>,
) -> RawVisibility {
- Self::from_ast_with_hygiene(node.value, &Hygiene::new(db.upcast(), node.file_id))
+ Self::from_ast_with_hygiene(db, node.value, &Hygiene::new(db.upcast(), node.file_id))
}
pub(crate) fn from_ast_with_hygiene(
+ db: &dyn DefDatabase,
node: Option<ast::Visibility>,
hygiene: &Hygiene,
) -> RawVisibility {
- Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene)
+ Self::from_ast_with_hygiene_and_default(db, node, RawVisibility::private(), hygiene)
}
pub(crate) fn from_ast_with_hygiene_and_default(
+ db: &dyn DefDatabase,
node: Option<ast::Visibility>,
default: RawVisibility,
hygiene: &Hygiene,
};
match node.kind() {
ast::VisibilityKind::In(path) => {
- let path = ModPath::from_src(path, hygiene);
+ let path = ModPath::from_src(db.upcast(), path, hygiene);
let path = match path {
None => return RawVisibility::private(),
Some(path) => path,
// visibility as the containing module (even though no items are directly nameable from
// there, getting this right is important for method resolution).
// In that case, we adjust the visibility of `to_module` to point to the containing module.
- if to_module.is_block_root(db) {
- to_module = to_module.containing_module(db).unwrap();
+ // Additional complication: `to_module` might be in `from_module`'s `DefMap`, which we're
+ // currently computing, so we must not call the `def_map` query for it.
+ let arc;
+ let to_module_def_map =
+ if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() {
+ cov_mark::hit!(is_visible_from_same_block_def_map);
+ def_map
+ } else {
+ arc = to_module.def_map(db);
+ &arc
+ };
+ let is_block_root = match to_module.block {
+ Some(_) => to_module_def_map[to_module.local_id].parent.is_none(),
+ None => false,
+ };
+ if is_block_root {
+ to_module = to_module_def_map.containing_module(to_module.local_id).unwrap();
}
// from_module needs to be a descendant of to_module
/// visible in unrelated modules).
pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
match (self, other) {
- (Visibility::Module(_), Visibility::Public)
- | (Visibility::Public, Visibility::Module(_))
- | (Visibility::Public, Visibility::Public) => Some(Visibility::Public),
+ (Visibility::Module(_) | Visibility::Public, Visibility::Public)
+ | (Visibility::Public, Visibility::Module(_)) => Some(Visibility::Public),
(Visibility::Module(mod_a), Visibility::Module(mod_b)) => {
if mod_a.krate != mod_b.krate {
return None;