9
9
// except according to those terms.
10
10
11
11
use { AmbiguityError , AmbiguityKind , AmbiguityErrorMisc } ;
12
- use { CrateLint , DeterminacyExt , Resolver , ResolutionError , is_known_tool , resolve_error } ;
12
+ use { CrateLint , DeterminacyExt , Resolver , ResolutionError } ;
13
13
use { Module , ModuleKind , NameBinding , NameBindingKind , PathResult , ToNameBinding } ;
14
+ use { is_known_tool, names_to_string, resolve_error} ;
14
15
use ModuleOrUniformRoot ;
15
16
use Namespace :: { self , * } ;
16
17
use build_reduced_graph:: { BuildReducedGraphVisitor , IsMacroExport } ;
@@ -450,6 +451,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
450
451
return Err ( Determinacy :: Determined ) ;
451
452
}
452
453
}
454
+ Def :: Err => {
455
+ return Err ( Determinacy :: Determined ) ;
456
+ }
453
457
_ => panic ! ( "expected `Def::Macro` or `Def::NonMacroAttr`" ) ,
454
458
}
455
459
@@ -476,29 +480,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
476
480
if path. len ( ) > 1 {
477
481
let def = match self . resolve_path ( & path, Some ( MacroNS ) , parent_scope,
478
482
false , path_span, CrateLint :: No ) {
479
- PathResult :: NonModule ( path_res) => match path_res. base_def ( ) {
480
- Def :: Err => Err ( Determinacy :: Determined ) ,
481
- def @ _ => {
482
- if path_res. unresolved_segments ( ) > 0 {
483
- self . found_unresolved_macro = true ;
484
- self . session . span_err ( path_span,
485
- "fail to resolve non-ident macro path" ) ;
486
- Err ( Determinacy :: Determined )
487
- } else {
488
- Ok ( def)
489
- }
490
- }
491
- } ,
492
- PathResult :: Module ( ..) => unreachable ! ( ) ,
483
+ PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
484
+ Ok ( path_res. base_def ( ) )
485
+ }
493
486
PathResult :: Indeterminate if !force => return Err ( Determinacy :: Undetermined ) ,
494
- _ => {
487
+ PathResult :: NonModule ( .. ) | PathResult :: Indeterminate | PathResult :: Failed ( .. ) => {
495
488
self . found_unresolved_macro = true ;
496
489
Err ( Determinacy :: Determined )
497
- } ,
490
+ }
491
+ PathResult :: Module ( ..) => unreachable ! ( ) ,
498
492
} ;
499
493
500
- parent_scope. module . macro_resolutions . borrow_mut ( )
501
- . push ( ( path, parent_scope. clone ( ) , path_span ) ) ;
494
+ parent_scope. module . multi_segment_macro_resolutions . borrow_mut ( )
495
+ . push ( ( path, path_span , kind , parent_scope. clone ( ) , def . ok ( ) ) ) ;
502
496
503
497
def
504
498
} else {
@@ -511,7 +505,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
511
505
Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
512
506
}
513
507
514
- parent_scope. module . legacy_macro_resolutions . borrow_mut ( )
508
+ parent_scope. module . single_segment_macro_resolutions . borrow_mut ( )
515
509
. push ( ( path[ 0 ] , kind, parent_scope. clone ( ) , binding. ok ( ) ) ) ;
516
510
517
511
binding. map ( |binding| binding. def_ignoring_ambiguity ( ) )
@@ -918,48 +912,66 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
918
912
pub fn finalize_current_module_macro_resolutions ( & mut self ) {
919
913
let module = self . current_module ;
920
914
915
+ let check_consistency = |this : & mut Self , path : & [ Ident ] , span,
916
+ kind : MacroKind , initial_def, def| {
917
+ if let Some ( initial_def) = initial_def {
918
+ if def != initial_def && def != Def :: Err && this. ambiguity_errors . is_empty ( ) {
919
+ // Make sure compilation does not succeed if preferred macro resolution
920
+ // has changed after the macro had been expanded. In theory all such
921
+ // situations should be reported as ambiguity errors, so this is a bug.
922
+ span_bug ! ( span, "inconsistent resolution for a macro" ) ;
923
+ }
924
+ } else {
925
+ // It's possible that the macro was unresolved (indeterminate) and silently
926
+ // expanded into a dummy fragment for recovery during expansion.
927
+ // Now, post-expansion, the resolution may succeed, but we can't change the
928
+ // past and need to report an error.
929
+ // However, non-speculative `resolve_path` can successfully return private items
930
+ // even if speculative `resolve_path` returned nothing previously, so we skip this
931
+ // less informative error if the privacy error is reported elsewhere.
932
+ if this. privacy_errors . is_empty ( ) {
933
+ let msg = format ! ( "cannot determine resolution for the {} `{}`" ,
934
+ kind. descr( ) , names_to_string( path) ) ;
935
+ let msg_note = "import resolution is stuck, try simplifying macro imports" ;
936
+ this. session . struct_span_err ( span, & msg) . note ( msg_note) . emit ( ) ;
937
+ }
938
+ }
939
+ } ;
940
+
921
941
let macro_resolutions =
922
- mem:: replace ( & mut * module. macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
923
- for ( path, parent_scope, path_span ) in macro_resolutions {
942
+ mem:: replace ( & mut * module. multi_segment_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
943
+ for ( path, path_span , kind , parent_scope, initial_def ) in macro_resolutions {
924
944
match self . resolve_path ( & path, Some ( MacroNS ) , & parent_scope,
925
945
true , path_span, CrateLint :: No ) {
926
- PathResult :: NonModule ( _) => { } ,
927
- PathResult :: Failed ( span, msg, _) => {
946
+ PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
947
+ let def = path_res. base_def ( ) ;
948
+ check_consistency ( self , & path, path_span, kind, initial_def, def) ;
949
+ }
950
+ path_res @ PathResult :: NonModule ( ..) | path_res @ PathResult :: Failed ( ..) => {
951
+ let ( span, msg) = if let PathResult :: Failed ( span, msg, ..) = path_res {
952
+ ( span, msg)
953
+ } else {
954
+ ( path_span, format ! ( "partially resolved path in {} {}" ,
955
+ kind. article( ) , kind. descr( ) ) )
956
+ } ;
928
957
resolve_error ( self , span, ResolutionError :: FailedToResolve ( & msg) ) ;
929
958
}
930
- _ => unreachable ! ( ) ,
959
+ PathResult :: Module ( .. ) | PathResult :: Indeterminate => unreachable ! ( ) ,
931
960
}
932
961
}
933
962
934
- let legacy_macro_resolutions =
935
- mem:: replace ( & mut * module. legacy_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
936
- for ( ident, kind, parent_scope, initial_binding) in legacy_macro_resolutions {
937
- let binding = self . early_resolve_ident_in_lexical_scope (
938
- ident, MacroNS , Some ( kind) , false , & parent_scope, true , true , ident. span
939
- ) ;
940
- match binding {
963
+ let macro_resolutions =
964
+ mem:: replace ( & mut * module. single_segment_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
965
+ for ( ident, kind, parent_scope, initial_binding) in macro_resolutions {
966
+ match self . early_resolve_ident_in_lexical_scope ( ident, MacroNS , Some ( kind) , false ,
967
+ & parent_scope, true , true , ident. span ) {
941
968
Ok ( binding) => {
942
- let def = binding. def_ignoring_ambiguity ( ) ;
943
- if let Some ( initial_binding) = initial_binding {
969
+ let initial_def = initial_binding. map ( |initial_binding| {
944
970
self . record_use ( ident, MacroNS , initial_binding) ;
945
- let initial_def = initial_binding. def_ignoring_ambiguity ( ) ;
946
- if self . ambiguity_errors . is_empty ( ) &&
947
- def != initial_def && def != Def :: Err {
948
- // Make sure compilation does not succeed if preferred macro resolution
949
- // has changed after the macro had been expanded. In theory all such
950
- // situations should be reported as ambiguity errors, so this is a bug.
951
- span_bug ! ( ident. span, "inconsistent resolution for a macro" ) ;
952
- }
953
- } else {
954
- // It's possible that the macro was unresolved (indeterminate) and silently
955
- // expanded into a dummy fragment for recovery during expansion.
956
- // Now, post-expansion, the resolution may succeed, but we can't change the
957
- // past and need to report an error.
958
- let msg = format ! ( "cannot determine resolution for the {} `{}`" ,
959
- kind. descr( ) , ident) ;
960
- let msg_note = "import resolution is stuck, try simplifying macro imports" ;
961
- self . session . struct_span_err ( ident. span , & msg) . note ( msg_note) . emit ( ) ;
962
- }
971
+ initial_binding. def_ignoring_ambiguity ( )
972
+ } ) ;
973
+ let def = binding. def_ignoring_ambiguity ( ) ;
974
+ check_consistency ( self , & [ ident] , ident. span , kind, initial_def, def) ;
963
975
}
964
976
Err ( ..) => {
965
977
assert ! ( initial_binding. is_none( ) ) ;
0 commit comments