@@ -38,23 +38,23 @@ impl<'a> Resolver<'a> {
38
38
39
39
/// Contains data for specific types of import directives.
40
40
#[ derive( Clone , Debug ) ]
41
- pub enum ImportDirectiveSubclass {
41
+ pub enum ImportDirectiveSubclass < ' a > {
42
42
SingleImport {
43
43
target : Name ,
44
44
source : Name ,
45
- type_determined : Cell < bool > ,
46
- value_determined : Cell < bool > ,
45
+ value_result : Cell < Result < & ' a NameBinding < ' a > , bool /* determined? */ > > ,
46
+ type_result : Cell < Result < & ' a NameBinding < ' a > , bool /* determined? */ > > ,
47
47
} ,
48
48
GlobImport { is_prelude : bool } ,
49
49
}
50
50
51
- impl ImportDirectiveSubclass {
51
+ impl < ' a > ImportDirectiveSubclass < ' a > {
52
52
pub fn single ( target : Name , source : Name ) -> Self {
53
53
SingleImport {
54
54
target : target,
55
55
source : source,
56
- type_determined : Cell :: new ( false ) ,
57
- value_determined : Cell :: new ( false ) ,
56
+ type_result : Cell :: new ( Err ( false ) ) ,
57
+ value_result : Cell :: new ( Err ( false ) ) ,
58
58
}
59
59
}
60
60
}
@@ -66,7 +66,7 @@ pub struct ImportDirective<'a> {
66
66
parent : Module < ' a > ,
67
67
module_path : Vec < Name > ,
68
68
target_module : Cell < Option < Module < ' a > > > , // the resolution of `module_path`
69
- subclass : ImportDirectiveSubclass ,
69
+ subclass : ImportDirectiveSubclass < ' a > ,
70
70
span : Span ,
71
71
vis : ty:: Visibility , // see note in ImportResolutionPerNamespace about how to use this
72
72
}
@@ -235,7 +235,7 @@ impl<'a> Resolver<'a> {
235
235
// Add an import directive to the current module.
236
236
pub fn add_import_directive ( & mut self ,
237
237
module_path : Vec < Name > ,
238
- subclass : ImportDirectiveSubclass ,
238
+ subclass : ImportDirectiveSubclass < ' a > ,
239
239
span : Span ,
240
240
id : NodeId ,
241
241
vis : ty:: Visibility ) {
@@ -488,30 +488,35 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
488
488
} ;
489
489
490
490
directive. target_module . set ( Some ( target_module) ) ;
491
- let ( source, target, value_determined , type_determined ) = match directive. subclass {
492
- SingleImport { source, target, ref value_determined , ref type_determined } =>
493
- ( source, target, value_determined , type_determined ) ,
491
+ let ( source, target, value_result , type_result ) = match directive. subclass {
492
+ SingleImport { source, target, ref value_result , ref type_result } =>
493
+ ( source, target, value_result , type_result ) ,
494
494
GlobImport { .. } => return self . resolve_glob_import ( target_module, directive) ,
495
495
} ;
496
496
497
- // We need to resolve both namespaces for this to succeed.
498
- let span = directive. span ;
499
- let value_result =
500
- self . resolve_name_in_module ( target_module, source, ValueNS , false , Some ( span) ) ;
501
- let type_result =
502
- self . resolve_name_in_module ( target_module, source, TypeNS , false , Some ( span) ) ;
503
-
504
497
let mut privacy_error = true ;
505
- for & ( ns, result, determined) in & [ ( ValueNS , & value_result, value_determined) ,
506
- ( TypeNS , & type_result, type_determined) ] {
507
- match * result {
508
- Failed ( ..) if !determined. get ( ) => {
509
- determined. set ( true ) ;
498
+ for & ( ns, result) in & [ ( ValueNS , value_result) , ( TypeNS , type_result) ] {
499
+ let was_determined = if let Err ( false ) = result. get ( ) {
500
+ result. set ( {
501
+ let span = Some ( directive. span ) ;
502
+ match self . resolve_name_in_module ( target_module, source, ns, false , span) {
503
+ Success ( binding) => Ok ( binding) ,
504
+ Indeterminate => Err ( false ) ,
505
+ Failed ( _) => Err ( true ) ,
506
+ }
507
+ } ) ;
508
+ false
509
+ } else {
510
+ true
511
+ } ;
512
+
513
+ match result. get ( ) {
514
+ Err ( true ) if !was_determined => {
510
515
self . update_resolution ( module, target, ns, |_, resolution| {
511
516
resolution. single_imports . directive_failed ( )
512
517
} ) ;
513
518
}
514
- Success ( binding) if !binding. is_importable ( ) => {
519
+ Ok ( binding) if !binding. is_importable ( ) => {
515
520
let msg = format ! ( "`{}` is not directly importable" , target) ;
516
521
struct_span_err ! ( self . session, directive. span, E0253 , "{}" , & msg)
517
522
. span_label ( directive. span , & format ! ( "cannot be imported directly" ) )
@@ -521,9 +526,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
521
526
self . import_dummy_binding ( directive) ;
522
527
return Success ( ( ) ) ;
523
528
}
524
- Success ( binding) if !self . is_accessible ( binding. vis ) => { }
525
- Success ( binding) if !determined. get ( ) => {
526
- determined. set ( true ) ;
529
+ Ok ( binding) if !self . is_accessible ( binding. vis ) => { }
530
+ Ok ( binding) if !was_determined => {
527
531
let imported_binding = self . import ( binding, directive) ;
528
532
let conflict = self . try_define ( module, target, ns, imported_binding) ;
529
533
if let Err ( old_binding) = conflict {
@@ -532,14 +536,15 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
532
536
}
533
537
privacy_error = false ;
534
538
}
535
- Success ( _) => privacy_error = false ,
539
+ Ok ( _) => privacy_error = false ,
536
540
_ => { }
537
541
}
538
542
}
539
543
540
- match ( & value_result, & type_result) {
541
- ( & Indeterminate , _) | ( _, & Indeterminate ) => return Indeterminate ,
542
- ( & Failed ( _) , & Failed ( _) ) => {
544
+ let ( value_result, type_result) = ( value_result. get ( ) , type_result. get ( ) ) ;
545
+ match ( value_result, type_result) {
546
+ ( Err ( false ) , _) | ( _, Err ( false ) ) => return Indeterminate ,
547
+ ( Err ( true ) , Err ( true ) ) => {
543
548
let resolutions = target_module. resolutions . borrow ( ) ;
544
549
let names = resolutions. iter ( ) . filter_map ( |( & ( ref name, _) , resolution) | {
545
550
if * name == source { return None ; } // Never suggest the same name
@@ -565,17 +570,17 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
565
570
}
566
571
567
572
if privacy_error {
568
- for & ( ns, result) in & [ ( ValueNS , & value_result) , ( TypeNS , & type_result) ] {
569
- let binding = match * result { Success ( binding) => binding, _ => continue } ;
573
+ for & ( ns, result) in & [ ( ValueNS , value_result) , ( TypeNS , type_result) ] {
574
+ let binding = match result { Ok ( binding) => binding, _ => continue } ;
570
575
self . privacy_errors . push ( PrivacyError ( directive. span , source, binding) ) ;
571
576
let imported_binding = self . import ( binding, directive) ;
572
577
let _ = self . try_define ( module, target, ns, imported_binding) ;
573
578
}
574
579
}
575
580
576
- match ( & value_result, & type_result) {
577
- ( & Success ( binding) , _) if !binding. pseudo_vis ( ) . is_at_least ( directive. vis , self ) &&
578
- self . is_accessible ( binding. vis ) => {
581
+ match ( value_result, type_result) {
582
+ ( Ok ( binding) , _) if !binding. pseudo_vis ( ) . is_at_least ( directive. vis , self ) &&
583
+ self . is_accessible ( binding. vis ) => {
579
584
let msg = format ! ( "`{}` is private, and cannot be reexported" , source) ;
580
585
let note_msg = format ! ( "consider marking `{}` as `pub` in the imported module" ,
581
586
source) ;
@@ -584,8 +589,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
584
589
. emit ( ) ;
585
590
}
586
591
587
- ( _, & Success ( binding) ) if !binding. pseudo_vis ( ) . is_at_least ( directive. vis , self ) &&
588
- self . is_accessible ( binding. vis ) => {
592
+ ( _, Ok ( binding) ) if !binding. pseudo_vis ( ) . is_at_least ( directive. vis , self ) &&
593
+ self . is_accessible ( binding. vis ) => {
589
594
if binding. is_extern_crate ( ) {
590
595
let msg = format ! ( "extern crate `{}` is private, and cannot be reexported \
591
596
(error E0364), consider declaring with `pub`",
@@ -607,9 +612,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
607
612
// Record what this import resolves to for later uses in documentation,
608
613
// this may resolve to either a value or a type, but for documentation
609
614
// purposes it's good enough to just favor one over the other.
610
- let def = match type_result. success ( ) . and_then ( NameBinding :: def) {
615
+ let def = match type_result. ok ( ) . and_then ( NameBinding :: def) {
611
616
Some ( def) => def,
612
- None => value_result. success ( ) . and_then ( NameBinding :: def) . unwrap ( ) ,
617
+ None => value_result. ok ( ) . and_then ( NameBinding :: def) . unwrap ( ) ,
613
618
} ;
614
619
let path_resolution = PathResolution :: new ( def) ;
615
620
self . def_map . insert ( directive. id , path_resolution) ;
0 commit comments