File tree Expand file tree Collapse file tree 2 files changed +21
-1
lines changed Expand file tree Collapse file tree 2 files changed +21
-1
lines changed Original file line number Diff line number Diff line change @@ -108,6 +108,18 @@ impl ModuleId {
108108 pub fn containing_module ( & self , db : & dyn db:: DefDatabase ) -> Option < ModuleId > {
109109 self . def_map ( db) . containing_module ( self . local_id )
110110 }
111+
112+ /// Returns `true` if this module represents a block expression.
113+ ///
114+ /// Returns `false` if this module is a submodule *inside* a block expression
115+ /// (eg. `m` in `{ mod m {} }`).
116+ pub fn is_block_root ( & self , db : & dyn db:: DefDatabase ) -> bool {
117+ if self . block . is_none ( ) {
118+ return false ;
119+ }
120+
121+ self . def_map ( db) [ self . local_id ] . parent . is_none ( )
122+ }
111123}
112124
113125/// An ID of a module, **local** to a specific crate
Original file line number Diff line number Diff line change @@ -123,11 +123,19 @@ impl Visibility {
123123 def_map : & DefMap ,
124124 mut from_module : crate :: LocalModuleId ,
125125 ) -> bool {
126- let to_module = match self {
126+ let mut to_module = match self {
127127 Visibility :: Module ( m) => m,
128128 Visibility :: Public => return true ,
129129 } ;
130130
131+ // `to_module` might be the root module of a block expression. Those have the same
132+ // visibility as the containing module (even though no items are directly nameable from
133+ // there, getting this right is important for method resolution).
134+ // In that case, we adjust the visibility of `to_module` to point to the containing module.
135+ if to_module. is_block_root ( db) {
136+ to_module = to_module. containing_module ( db) . unwrap ( ) ;
137+ }
138+
131139 // from_module needs to be a descendant of to_module
132140 let mut def_map = def_map;
133141 let mut parent_arc;
You can’t perform that action at this time.
0 commit comments