Restrict visibilities to the containing DefMap
This commit is contained in:
parent
f682627da4
commit
6990b89b26
2 changed files with 46 additions and 4 deletions
|
@ -259,3 +259,32 @@ fn main() {
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn underscore_import() {
|
||||||
|
// This used to panic, because the default (private) visibility inside block expressions would
|
||||||
|
// point into the containing `DefMap`, which visibilities should never be able to do.
|
||||||
|
mark::check!(adjust_vis_in_block_def_map);
|
||||||
|
check_at(
|
||||||
|
r#"
|
||||||
|
mod m {
|
||||||
|
fn main() {
|
||||||
|
use Tr as _;
|
||||||
|
trait Tr {}
|
||||||
|
$0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
block scope
|
||||||
|
_: t
|
||||||
|
Tr: t
|
||||||
|
|
||||||
|
crate
|
||||||
|
m: t
|
||||||
|
|
||||||
|
crate::m
|
||||||
|
main: v
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl DefMap {
|
||||||
original_module: LocalModuleId,
|
original_module: LocalModuleId,
|
||||||
visibility: &RawVisibility,
|
visibility: &RawVisibility,
|
||||||
) -> Option<Visibility> {
|
) -> Option<Visibility> {
|
||||||
match visibility {
|
let mut vis = match visibility {
|
||||||
RawVisibility::Module(path) => {
|
RawVisibility::Module(path) => {
|
||||||
let (result, remaining) =
|
let (result, remaining) =
|
||||||
self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
|
self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
|
||||||
|
@ -86,17 +86,30 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
let types = result.take_types()?;
|
let types = result.take_types()?;
|
||||||
match types {
|
match types {
|
||||||
ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)),
|
ModuleDefId::ModuleId(m) => Visibility::Module(m),
|
||||||
_ => {
|
_ => {
|
||||||
// error: visibility needs to refer to module
|
// error: visibility needs to refer to module
|
||||||
None
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RawVisibility::Public => Some(Visibility::Public),
|
RawVisibility::Public => Visibility::Public,
|
||||||
|
};
|
||||||
|
|
||||||
|
// In block expressions, `self` normally refers to the containing non-block module, and
|
||||||
|
// `super` to its parent (etc.). However, visibilities must only refer to a module in the
|
||||||
|
// DefMap they're written in, so we restrict them when that happens.
|
||||||
|
if let Visibility::Module(m) = vis {
|
||||||
|
if self.block_id() != m.block {
|
||||||
|
mark::hit!(adjust_vis_in_block_def_map);
|
||||||
|
vis = Visibility::Module(self.module_id(self.root()));
|
||||||
|
log::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(vis)
|
||||||
|
}
|
||||||
|
|
||||||
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
|
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
|
||||||
// the result.
|
// the result.
|
||||||
pub(super) fn resolve_path_fp_with_macro(
|
pub(super) fn resolve_path_fp_with_macro(
|
||||||
|
|
Loading…
Add table
Reference in a new issue