2
2
3
3
use std:: iter;
4
4
5
+ use base_db:: Crate ;
5
6
use hir_expand:: { InFile , Lookup } ;
6
7
use la_arena:: ArenaMap ;
7
8
use syntax:: ast:: { self , HasVisibility } ;
@@ -19,6 +20,8 @@ pub use crate::item_tree::{RawVisibility, VisibilityExplicitness};
19
20
pub enum Visibility {
20
21
/// Visibility is restricted to a certain module.
21
22
Module ( ModuleId , VisibilityExplicitness ) ,
23
+ /// Visibility is restricted to the crate.
24
+ PubCrate ( Crate ) ,
22
25
/// Visibility is unrestricted.
23
26
Public ,
24
27
}
@@ -41,6 +44,7 @@ impl Visibility {
41
44
pub fn is_visible_from ( self , db : & dyn DefDatabase , from_module : ModuleId ) -> bool {
42
45
let to_module = match self {
43
46
Visibility :: Module ( m, _) => m,
47
+ Visibility :: PubCrate ( krate) => return from_module. krate == krate,
44
48
Visibility :: Public => return true ,
45
49
} ;
46
50
// if they're not in the same crate, it can't be visible
@@ -59,6 +63,7 @@ impl Visibility {
59
63
) -> bool {
60
64
let to_module = match self {
61
65
Visibility :: Module ( m, _) => m,
66
+ Visibility :: PubCrate ( krate) => return def_map. krate ( ) == krate,
62
67
Visibility :: Public => return true ,
63
68
} ;
64
69
// if they're not in the same crate, it can't be visible
@@ -132,26 +137,41 @@ impl Visibility {
132
137
pub ( crate ) fn max ( self , other : Visibility , def_map : & DefMap ) -> Option < Visibility > {
133
138
match ( self , other) {
134
139
( _, Visibility :: Public ) | ( Visibility :: Public , _) => Some ( Visibility :: Public ) ,
140
+ ( Visibility :: PubCrate ( krate) , Visibility :: PubCrate ( krateb) ) => {
141
+ if krate == krateb {
142
+ Some ( Visibility :: PubCrate ( krate) )
143
+ } else {
144
+ None
145
+ }
146
+ }
147
+ ( Visibility :: Module ( mod_, _) , Visibility :: PubCrate ( krate) )
148
+ | ( Visibility :: PubCrate ( krate) , Visibility :: Module ( mod_, _) ) => {
149
+ if mod_. krate == krate {
150
+ Some ( Visibility :: PubCrate ( krate) )
151
+ } else {
152
+ None
153
+ }
154
+ }
135
155
( Visibility :: Module ( mod_a, expl_a) , Visibility :: Module ( mod_b, expl_b) ) => {
136
- if mod_a. krate != mod_b. krate {
156
+ if mod_a. krate != def_map . krate ( ) || mod_b. krate != def_map . krate ( ) {
137
157
return None ;
138
158
}
139
159
140
160
let def_block = def_map. block_id ( ) ;
141
- if ( mod_a. containing_block ( ) , mod_b. containing_block ( ) ) != ( def_block, def_block ) {
161
+ if mod_a. containing_block ( ) != def_block || mod_b. containing_block ( ) != def_block {
142
162
return None ;
143
163
}
144
164
145
165
let mut a_ancestors =
146
166
iter:: successors ( Some ( mod_a. local_id ) , |& m| def_map[ m] . parent ) ;
147
- let mut b_ancestors =
148
- iter:: successors ( Some ( mod_b. local_id ) , |& m| def_map[ m] . parent ) ;
149
167
150
168
if a_ancestors. any ( |m| m == mod_b. local_id ) {
151
169
// B is above A
152
170
return Some ( Visibility :: Module ( mod_b, expl_b) ) ;
153
171
}
154
172
173
+ let mut b_ancestors =
174
+ iter:: successors ( Some ( mod_b. local_id ) , |& m| def_map[ m] . parent ) ;
155
175
if b_ancestors. any ( |m| m == mod_a. local_id ) {
156
176
// A is above B
157
177
return Some ( Visibility :: Module ( mod_a, expl_a) ) ;
@@ -169,26 +189,37 @@ impl Visibility {
169
189
pub ( crate ) fn min ( self , other : Visibility , def_map : & DefMap ) -> Option < Visibility > {
170
190
match ( self , other) {
171
191
( vis, Visibility :: Public ) | ( Visibility :: Public , vis) => Some ( vis) ,
192
+ ( Visibility :: PubCrate ( krate) , Visibility :: PubCrate ( krateb) ) => {
193
+ if krate == krateb {
194
+ Some ( Visibility :: PubCrate ( krate) )
195
+ } else {
196
+ None
197
+ }
198
+ }
199
+ ( Visibility :: Module ( mod_, exp) , Visibility :: PubCrate ( krate) )
200
+ | ( Visibility :: PubCrate ( krate) , Visibility :: Module ( mod_, exp) ) => {
201
+ if mod_. krate == krate { Some ( Visibility :: Module ( mod_, exp) ) } else { None }
202
+ }
172
203
( Visibility :: Module ( mod_a, expl_a) , Visibility :: Module ( mod_b, expl_b) ) => {
173
- if mod_a. krate != mod_b. krate {
204
+ if mod_a. krate != def_map . krate ( ) || mod_b. krate != def_map . krate ( ) {
174
205
return None ;
175
206
}
176
207
177
208
let def_block = def_map. block_id ( ) ;
178
- if ( mod_a. containing_block ( ) , mod_b. containing_block ( ) ) != ( def_block, def_block ) {
209
+ if mod_a. containing_block ( ) != def_block || mod_b. containing_block ( ) != def_block {
179
210
return None ;
180
211
}
181
212
182
213
let mut a_ancestors =
183
214
iter:: successors ( Some ( mod_a. local_id ) , |& m| def_map[ m] . parent ) ;
184
- let mut b_ancestors =
185
- iter:: successors ( Some ( mod_b. local_id ) , |& m| def_map[ m] . parent ) ;
186
215
187
216
if a_ancestors. any ( |m| m == mod_b. local_id ) {
188
217
// B is above A
189
218
return Some ( Visibility :: Module ( mod_a, expl_a) ) ;
190
219
}
191
220
221
+ let mut b_ancestors =
222
+ iter:: successors ( Some ( mod_b. local_id ) , |& m| def_map[ m] . parent ) ;
192
223
if b_ancestors. any ( |m| m == mod_a. local_id ) {
193
224
// A is above B
194
225
return Some ( Visibility :: Module ( mod_b, expl_b) ) ;
0 commit comments