99// except according to those terms.
1010
1111use { AmbiguityError , AmbiguityKind , AmbiguityErrorMisc } ;
12- use { CrateLint , DeterminacyExt , Resolver , ResolutionError , is_known_tool , resolve_error } ;
12+ use { CrateLint , DeterminacyExt , Resolver , ResolutionError } ;
1313use { Module , ModuleKind , NameBinding , NameBindingKind , PathResult , ToNameBinding } ;
14+ use { is_known_tool, names_to_string, resolve_error} ;
1415use ModuleOrUniformRoot ;
1516use Namespace :: { self , * } ;
1617use build_reduced_graph:: { BuildReducedGraphVisitor , IsMacroExport } ;
@@ -480,29 +481,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
480481 if path. len ( ) > 1 {
481482 let def = match self . resolve_path ( & path, Some ( MacroNS ) , parent_scope,
482483 false , path_span, CrateLint :: No ) {
483- PathResult :: NonModule ( path_res) => match path_res. base_def ( ) {
484- Def :: Err => Err ( Determinacy :: Determined ) ,
485- def @ _ => {
486- if path_res. unresolved_segments ( ) > 0 {
487- self . found_unresolved_macro = true ;
488- self . session . span_err ( path_span,
489- "fail to resolve non-ident macro path" ) ;
490- Err ( Determinacy :: Determined )
491- } else {
492- Ok ( def)
493- }
494- }
495- } ,
496- PathResult :: Module ( ..) => unreachable ! ( ) ,
484+ PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
485+ Ok ( path_res. base_def ( ) )
486+ }
497487 PathResult :: Indeterminate if !force => return Err ( Determinacy :: Undetermined ) ,
498- _ => {
488+ PathResult :: NonModule ( .. ) | PathResult :: Indeterminate | PathResult :: Failed ( .. ) => {
499489 self . found_unresolved_macro = true ;
500490 Err ( Determinacy :: Determined )
501- } ,
491+ }
492+ PathResult :: Module ( ..) => unreachable ! ( ) ,
502493 } ;
503494
504- parent_scope. module . macro_resolutions . borrow_mut ( )
505- . push ( ( path, parent_scope. clone ( ) , path_span ) ) ;
495+ parent_scope. module . multi_segment_macro_resolutions . borrow_mut ( )
496+ . push ( ( path, path_span , kind , parent_scope. clone ( ) , def . ok ( ) ) ) ;
506497
507498 def
508499 } else {
@@ -515,7 +506,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
515506 Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
516507 }
517508
518- parent_scope. module . legacy_macro_resolutions . borrow_mut ( )
509+ parent_scope. module . single_segment_macro_resolutions . borrow_mut ( )
519510 . push ( ( path[ 0 ] . ident , kind, parent_scope. clone ( ) , binding. ok ( ) ) ) ;
520511
521512 binding. map ( |binding| binding. def_ignoring_ambiguity ( ) )
@@ -922,50 +913,68 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
922913 pub fn finalize_current_module_macro_resolutions ( & mut self ) {
923914 let module = self . current_module ;
924915
916+ let check_consistency = |this : & mut Self , path : & [ Ident ] , span,
917+ kind : MacroKind , initial_def, def| {
918+ if let Some ( initial_def) = initial_def {
919+ if def != initial_def && def != Def :: Err && this. ambiguity_errors . is_empty ( ) {
920+ // Make sure compilation does not succeed if preferred macro resolution
921+ // has changed after the macro had been expanded. In theory all such
922+ // situations should be reported as ambiguity errors, so this is a bug.
923+ span_bug ! ( span, "inconsistent resolution for a macro" ) ;
924+ }
925+ } else {
926+ // It's possible that the macro was unresolved (indeterminate) and silently
927+ // expanded into a dummy fragment for recovery during expansion.
928+ // Now, post-expansion, the resolution may succeed, but we can't change the
929+ // past and need to report an error.
930+ // However, non-speculative `resolve_path` can successfully return private items
931+ // even if speculative `resolve_path` returned nothing previously, so we skip this
932+ // less informative error if the privacy error is reported elsewhere.
933+ if this. privacy_errors . is_empty ( ) {
934+ let msg = format ! ( "cannot determine resolution for the {} `{}`" ,
935+ kind. descr( ) , names_to_string( path) ) ;
936+ let msg_note = "import resolution is stuck, try simplifying macro imports" ;
937+ this. session . struct_span_err ( span, & msg) . note ( msg_note) . emit ( ) ;
938+ }
939+ }
940+ } ;
941+
925942 let macro_resolutions =
926- mem:: replace ( & mut * module. macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
927- for ( mut path, parent_scope, path_span ) in macro_resolutions {
943+ mem:: replace ( & mut * module. multi_segment_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
944+ for ( mut path, path_span , kind , parent_scope, initial_def ) in macro_resolutions {
928945 // FIXME: Path resolution will ICE if segment IDs present.
929946 for seg in & mut path { seg. id = None ; }
930947 match self . resolve_path ( & path, Some ( MacroNS ) , & parent_scope,
931948 true , path_span, CrateLint :: No ) {
932- PathResult :: NonModule ( _) => { } ,
933- PathResult :: Failed ( span, msg, _) => {
949+ PathResult :: NonModule ( path_res) if path_res. unresolved_segments ( ) == 0 => {
950+ let def = path_res. base_def ( ) ;
951+ check_consistency ( self , & path, path_span, kind, initial_def, def) ;
952+ }
953+ path_res @ PathResult :: NonModule ( ..) | path_res @ PathResult :: Failed ( ..) => {
954+ let ( span, msg) = if let PathResult :: Failed ( span, msg, ..) = path_res {
955+ ( span, msg)
956+ } else {
957+ ( path_span, format ! ( "partially resolved path in {} {}" ,
958+ kind. article( ) , kind. descr( ) ) )
959+ } ;
934960 resolve_error ( self , span, ResolutionError :: FailedToResolve ( & msg) ) ;
935961 }
936- _ => unreachable ! ( ) ,
962+ PathResult :: Module ( .. ) | PathResult :: Indeterminate => unreachable ! ( ) ,
937963 }
938964 }
939965
940- let legacy_macro_resolutions =
941- mem:: replace ( & mut * module. legacy_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
942- for ( ident, kind, parent_scope, initial_binding) in legacy_macro_resolutions {
943- let binding = self . early_resolve_ident_in_lexical_scope (
944- ident, MacroNS , Some ( kind) , false , & parent_scope, true , true , ident. span
945- ) ;
946- match binding {
966+ let macro_resolutions =
967+ mem:: replace ( & mut * module. single_segment_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
968+ for ( ident, kind, parent_scope, initial_binding) in macro_resolutions {
969+ match self . early_resolve_ident_in_lexical_scope ( ident, MacroNS , Some ( kind) , false ,
970+ & parent_scope, true , true , ident. span ) {
947971 Ok ( binding) => {
948- let def = binding. def_ignoring_ambiguity ( ) ;
949- if let Some ( initial_binding) = initial_binding {
972+ let initial_def = initial_binding. map ( |initial_binding| {
950973 self . record_use ( ident, MacroNS , initial_binding) ;
951- let initial_def = initial_binding. def_ignoring_ambiguity ( ) ;
952- if self . ambiguity_errors . is_empty ( ) &&
953- def != initial_def && def != Def :: Err {
954- // Make sure compilation does not succeed if preferred macro resolution
955- // has changed after the macro had been expanded. In theory all such
956- // situations should be reported as ambiguity errors, so this is a bug.
957- span_bug ! ( ident. span, "inconsistent resolution for a macro" ) ;
958- }
959- } else {
960- // It's possible that the macro was unresolved (indeterminate) and silently
961- // expanded into a dummy fragment for recovery during expansion.
962- // Now, post-expansion, the resolution may succeed, but we can't change the
963- // past and need to report an error.
964- let msg = format ! ( "cannot determine resolution for the {} `{}`" ,
965- kind. descr( ) , ident) ;
966- let msg_note = "import resolution is stuck, try simplifying macro imports" ;
967- self . session . struct_span_err ( ident. span , & msg) . note ( msg_note) . emit ( ) ;
968- }
974+ initial_binding. def_ignoring_ambiguity ( )
975+ } ) ;
976+ let def = binding. def_ignoring_ambiguity ( ) ;
977+ check_consistency ( self , & [ ident] , ident. span , kind, initial_def, def) ;
969978 }
970979 Err ( ..) => {
971980 assert ! ( initial_binding. is_none( ) ) ;
0 commit comments