@@ -22,9 +22,6 @@ pub struct Context {
2222 pub resolve_features : im_rc:: HashMap < PackageId , FeaturesSet > ,
2323 /// get the package that will be linking to a native library by its links attribute
2424 pub links : im_rc:: HashMap < InternedString , PackageId > ,
25- /// for each package the list of names it can see,
26- /// then for each name the exact version that name represents and whether the name is public.
27- pub public_dependency : Option < PublicDependency > ,
2825
2926 /// a way to look up for a package in activations what packages required it
3027 /// and all of the exact deps that it fulfilled.
@@ -74,16 +71,11 @@ impl PackageId {
7471}
7572
7673impl Context {
77- pub fn new ( check_public_visible_dependencies : bool ) -> Context {
74+ pub fn new ( ) -> Context {
7875 Context {
7976 age : 0 ,
8077 resolve_features : im_rc:: HashMap :: new ( ) ,
8178 links : im_rc:: HashMap :: new ( ) ,
82- public_dependency : if check_public_visible_dependencies {
83- Some ( PublicDependency :: new ( ) )
84- } else {
85- None
86- } ,
8779 parents : Graph :: new ( ) ,
8880 activations : im_rc:: HashMap :: new ( ) ,
8981 }
@@ -192,42 +184,6 @@ impl Context {
192184 . and_then ( |( s, l) | if s. package_id ( ) == id { Some ( * l) } else { None } )
193185 }
194186
195- /// If the conflict reason on the package still applies returns the `ContextAge` when it was added
196- pub fn still_applies ( & self , id : PackageId , reason : & ConflictReason ) -> Option < ContextAge > {
197- self . is_active ( id) . and_then ( |mut max| {
198- match reason {
199- ConflictReason :: PublicDependency ( name) => {
200- if & id == name {
201- return Some ( max) ;
202- }
203- max = std:: cmp:: max ( max, self . is_active ( * name) ?) ;
204- max = std:: cmp:: max (
205- max,
206- self . public_dependency
207- . as_ref ( )
208- . unwrap ( )
209- . can_see_item ( * name, id) ?,
210- ) ;
211- }
212- ConflictReason :: PubliclyExports ( name) => {
213- if & id == name {
214- return Some ( max) ;
215- }
216- max = std:: cmp:: max ( max, self . is_active ( * name) ?) ;
217- max = std:: cmp:: max (
218- max,
219- self . public_dependency
220- . as_ref ( )
221- . unwrap ( )
222- . publicly_exports_item ( * name, id) ?,
223- ) ;
224- }
225- _ => { }
226- }
227- Some ( max)
228- } )
229- }
230-
231187 /// Checks whether all of `parent` and the keys of `conflicting activations`
232188 /// are still active.
233189 /// If so returns the `ContextAge` when the newest one was added.
@@ -241,8 +197,8 @@ impl Context {
241197 max = std:: cmp:: max ( max, self . is_active ( parent) ?) ;
242198 }
243199
244- for ( id , reason ) in conflicting_activations. iter ( ) {
245- max = std:: cmp:: max ( max, self . still_applies ( * id, reason ) ?) ;
200+ for id in conflicting_activations. keys ( ) {
201+ max = std:: cmp:: max ( max, self . is_active ( * id) ?) ;
246202 }
247203 Some ( max)
248204 }
@@ -280,158 +236,3 @@ impl Graph<PackageId, im_rc::HashSet<Dependency>> {
280236 . map ( |( grand, d) | ( * grand, d. iter ( ) . any ( |x| x. is_public ( ) ) ) )
281237 }
282238}
283-
284- #[ derive( Clone , Debug , Default ) ]
285- pub struct PublicDependency {
286- /// For each active package the set of all the names it can see,
287- /// for each name the exact package that name resolves to,
288- /// the `ContextAge` when it was first visible,
289- /// and the `ContextAge` when it was first exported.
290- inner : im_rc:: HashMap <
291- PackageId ,
292- im_rc:: HashMap < InternedString , ( PackageId , ContextAge , Option < ContextAge > ) > ,
293- > ,
294- }
295-
296- impl PublicDependency {
297- fn new ( ) -> Self {
298- PublicDependency {
299- inner : im_rc:: HashMap :: new ( ) ,
300- }
301- }
302- fn publicly_exports ( & self , candidate_pid : PackageId ) -> Vec < PackageId > {
303- self . inner
304- . get ( & candidate_pid) // if we have seen it before
305- . iter ( )
306- . flat_map ( |x| x. values ( ) ) // all the things we have stored
307- . filter ( |x| x. 2 . is_some ( ) ) // as publicly exported
308- . map ( |x| x. 0 )
309- . chain ( Some ( candidate_pid) ) // but even if not we know that everything exports itself
310- . collect ( )
311- }
312- fn publicly_exports_item (
313- & self ,
314- candidate_pid : PackageId ,
315- target : PackageId ,
316- ) -> Option < ContextAge > {
317- debug_assert_ne ! ( candidate_pid, target) ;
318- let out = self
319- . inner
320- . get ( & candidate_pid)
321- . and_then ( |names| names. get ( & target. name ( ) ) )
322- . filter ( |( p, _, _) | * p == target)
323- . and_then ( |( _, _, age) | * age) ;
324- debug_assert_eq ! (
325- out. is_some( ) ,
326- self . publicly_exports( candidate_pid) . contains( & target)
327- ) ;
328- out
329- }
330- pub fn can_see_item ( & self , candidate_pid : PackageId , target : PackageId ) -> Option < ContextAge > {
331- self . inner
332- . get ( & candidate_pid)
333- . and_then ( |names| names. get ( & target. name ( ) ) )
334- . filter ( |( p, _, _) | * p == target)
335- . map ( |( _, age, _) | * age)
336- }
337- pub fn add_edge (
338- & mut self ,
339- candidate_pid : PackageId ,
340- parent_pid : PackageId ,
341- is_public : bool ,
342- age : ContextAge ,
343- parents : & Graph < PackageId , im_rc:: HashSet < Dependency > > ,
344- ) {
345- // one tricky part is that `candidate_pid` may already be active and
346- // have public dependencies of its own. So we not only need to mark
347- // `candidate_pid` as visible to its parents but also all of its existing
348- // publicly exported dependencies.
349- for c in self . publicly_exports ( candidate_pid) {
350- // for each (transitive) parent that can newly see `t`
351- let mut stack = vec ! [ ( parent_pid, is_public) ] ;
352- while let Some ( ( p, public) ) = stack. pop ( ) {
353- match self . inner . entry ( p) . or_default ( ) . entry ( c. name ( ) ) {
354- im_rc:: hashmap:: Entry :: Occupied ( mut o) => {
355- // the (transitive) parent can already see something by `c`s name, it had better be `c`.
356- assert_eq ! ( o. get( ) . 0 , c) ;
357- if o. get ( ) . 2 . is_some ( ) {
358- // The previous time the parent saw `c`, it was a public dependency.
359- // So all of its parents already know about `c`
360- // and we can save some time by stopping now.
361- continue ;
362- }
363- if public {
364- // Mark that `c` has now bean seen publicly
365- let old_age = o. get ( ) . 1 ;
366- o. insert ( ( c, old_age, if public { Some ( age) } else { None } ) ) ;
367- }
368- }
369- im_rc:: hashmap:: Entry :: Vacant ( v) => {
370- // The (transitive) parent does not have anything by `c`s name,
371- // so we add `c`.
372- v. insert ( ( c, age, if public { Some ( age) } else { None } ) ) ;
373- }
374- }
375- // if `candidate_pid` was a private dependency of `p` then `p` parents can't see `c` thru `p`
376- if public {
377- // if it was public, then we add all of `p`s parents to be checked
378- stack. extend ( parents. parents_of ( p) ) ;
379- }
380- }
381- }
382- }
383- pub fn can_add_edge (
384- & self ,
385- b_id : PackageId ,
386- parent : PackageId ,
387- is_public : bool ,
388- parents : & Graph < PackageId , im_rc:: HashSet < Dependency > > ,
389- ) -> Result <
390- ( ) ,
391- (
392- ( ( PackageId , ConflictReason ) , ( PackageId , ConflictReason ) ) ,
393- Option < ( PackageId , ConflictReason ) > ,
394- ) ,
395- > {
396- // one tricky part is that `candidate_pid` may already be active and
397- // have public dependencies of its own. So we not only need to check
398- // `b_id` as visible to its parents but also all of its existing
399- // publicly exported dependencies.
400- for t in self . publicly_exports ( b_id) {
401- // for each (transitive) parent that can newly see `t`
402- let mut stack = vec ! [ ( parent, is_public) ] ;
403- while let Some ( ( p, public) ) = stack. pop ( ) {
404- // TODO: don't look at the same thing more than once
405- if let Some ( o) = self . inner . get ( & p) . and_then ( |x| x. get ( & t. name ( ) ) ) {
406- if o. 0 != t {
407- // the (transitive) parent can already see a different version by `t`s name.
408- // So, adding `b` will cause `p` to have a public dependency conflict on `t`.
409- return Err ( (
410- ( o. 0 , ConflictReason :: PublicDependency ( p) ) , // p can see the other version and
411- ( parent, ConflictReason :: PublicDependency ( p) ) , // p can see us
412- ) )
413- . map_err ( |e| {
414- if t == b_id {
415- ( e, None )
416- } else {
417- ( e, Some ( ( t, ConflictReason :: PubliclyExports ( b_id) ) ) )
418- }
419- } ) ;
420- }
421- if o. 2 . is_some ( ) {
422- // The previous time the parent saw `t`, it was a public dependency.
423- // So all of its parents already know about `t`
424- // and we can save some time by stopping now.
425- continue ;
426- }
427- }
428- // if `b` was a private dependency of `p` then `p` parents can't see `t` thru `p`
429- if public {
430- // if it was public, then we add all of `p`s parents to be checked
431- stack. extend ( parents. parents_of ( p) ) ;
432- }
433- }
434- }
435- Ok ( ( ) )
436- }
437- }
0 commit comments