88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use { Module , ModuleKind , NameBinding , NameBindingKind , Resolver , AmbiguityError } ;
11+ use { AmbiguityError , Resolver , ResolutionError , resolve_error} ;
12+ use { Module , ModuleKind , NameBinding , NameBindingKind , PathScope , PathResult } ;
1213use Namespace :: { self , MacroNS } ;
1314use build_reduced_graph:: BuildReducedGraphVisitor ;
1415use resolve_imports:: ImportResolver ;
@@ -25,6 +26,7 @@ use syntax::ext::base::{NormalTT, SyntaxExtension};
2526use syntax:: ext:: expand:: Expansion ;
2627use syntax:: ext:: hygiene:: Mark ;
2728use syntax:: ext:: tt:: macro_rules;
29+ use syntax:: feature_gate:: { emit_feature_err, GateIssue } ;
2830use syntax:: fold:: Folder ;
2931use syntax:: ptr:: P ;
3032use syntax:: util:: lev_distance:: find_best_match_for_name;
@@ -193,7 +195,7 @@ impl<'a> base::Resolver for Resolver<'a> {
193195 fn find_attr_invoc ( & mut self , attrs : & mut Vec < ast:: Attribute > ) -> Option < ast:: Attribute > {
194196 for i in 0 ..attrs. len ( ) {
195197 match self . builtin_macros . get ( & attrs[ i] . name ( ) ) . cloned ( ) {
196- Some ( binding) => match * self . get_macro ( binding ) {
198+ Some ( binding) => match * binding . get_macro ( self ) {
197199 MultiModifier ( ..) | MultiDecorator ( ..) | SyntaxExtension :: AttrProcMacro ( ..) => {
198200 return Some ( attrs. remove ( i) )
199201 }
@@ -207,75 +209,103 @@ impl<'a> base::Resolver for Resolver<'a> {
207209
208210 fn resolve_macro ( & mut self , scope : Mark , path : & ast:: Path , force : bool )
209211 -> Result < Rc < SyntaxExtension > , Determinacy > {
210- if path. segments . len ( ) > 1 || path. global || !path. segments [ 0 ] . parameters . is_empty ( ) {
211- self . session . span_err ( path. span , "expected macro name without module separators" ) ;
212+ let ast:: Path { ref segments, global, span } = * path;
213+ if segments. iter ( ) . any ( |segment| !segment. parameters . is_empty ( ) ) {
214+ let kind =
215+ if segments. last ( ) . unwrap ( ) . parameters . is_empty ( ) { "module" } else { "macro" } ;
216+ let msg = format ! ( "type parameters are not allowed on {}s" , kind) ;
217+ self . session . span_err ( path. span , & msg) ;
212218 return Err ( Determinacy :: Determined ) ;
213219 }
214- let name = path. segments [ 0 ] . identifier . name ;
215220
221+ let path_scope = if global { PathScope :: Global } else { PathScope :: Lexical } ;
222+ let path: Vec < _ > = segments. iter ( ) . map ( |seg| seg. identifier ) . collect ( ) ;
216223 let invocation = self . invocations [ & scope] ;
217224 self . current_module = invocation. module . get ( ) ;
225+
226+ if path. len ( ) > 1 || global {
227+ if !self . use_extern_macros {
228+ let msg = "non-ident macro paths are experimental" ;
229+ let feature = "use_extern_macros" ;
230+ emit_feature_err ( & self . session . parse_sess , feature, span, GateIssue :: Language , msg) ;
231+ return Err ( Determinacy :: Determined ) ;
232+ }
233+
234+ let ext = match self . resolve_path ( & path, path_scope, Some ( MacroNS ) , None ) {
235+ PathResult :: NonModule ( path_res) => Ok ( self . get_macro ( path_res. base_def ) ) ,
236+ PathResult :: Module ( ..) => unreachable ! ( ) ,
237+ PathResult :: Indeterminate if !force => return Err ( Determinacy :: Undetermined ) ,
238+ _ => Err ( Determinacy :: Determined ) ,
239+ } ;
240+ self . current_module . macro_resolutions . borrow_mut ( )
241+ . push ( ( path. into_boxed_slice ( ) , path_scope, span) ) ;
242+ return ext;
243+ }
244+
245+ let name = path[ 0 ] . name ;
218246 let result = match self . resolve_legacy_scope ( & invocation. legacy_scope , name, false ) {
219247 Some ( MacroBinding :: Legacy ( binding) ) => Ok ( binding. ext . clone ( ) ) ,
220- Some ( MacroBinding :: Modern ( binding) ) => Ok ( self . get_macro ( binding) ) ,
221- None => match self . resolve_in_item_lexical_scope ( name, MacroNS , None ) {
222- Some ( binding) => Ok ( self . get_macro ( binding) ) ,
223- None => return Err ( if force {
248+ Some ( MacroBinding :: Modern ( binding) ) => Ok ( binding. get_macro ( self ) ) ,
249+ None => match self . resolve_lexical_macro_path_segment ( name, MacroNS , None ) {
250+ Ok ( binding) => Ok ( binding. get_macro ( self ) ) ,
251+ Err ( Determinacy :: Undetermined ) if !force => return Err ( Determinacy :: Undetermined ) ,
252+ _ => {
224253 let msg = format ! ( "macro undefined: '{}!'" , name) ;
225- let mut err = self . session . struct_span_err ( path . span , & msg) ;
254+ let mut err = self . session . struct_span_err ( span, & msg) ;
226255 self . suggest_macro_name ( & name. as_str ( ) , & mut err) ;
227256 err. emit ( ) ;
228- Determinacy :: Determined
229- } else {
230- Determinacy :: Undetermined
231- } ) ,
257+ return Err ( Determinacy :: Determined ) ;
258+ } ,
232259 } ,
233260 } ;
234261
235262 if self . use_extern_macros {
236- self . current_module . legacy_macro_resolutions . borrow_mut ( )
237- . push ( ( scope, name, path. span ) ) ;
263+ self . current_module . legacy_macro_resolutions . borrow_mut ( ) . push ( ( scope, name, span) ) ;
238264 }
239265 result
240266 }
241267}
242268
243269impl < ' a > Resolver < ' a > {
244- // Resolve the name in the module's lexical scope, excluding non-items.
245- fn resolve_in_item_lexical_scope ( & mut self ,
246- name : Name ,
247- ns : Namespace ,
248- record_used : Option < Span > )
249- -> Option < & ' a NameBinding < ' a > > {
270+ // Resolve the initial segment of a non-global macro path (e.g. `foo` in `foo::bar!();`)
271+ pub fn resolve_lexical_macro_path_segment ( & mut self ,
272+ name : Name ,
273+ ns : Namespace ,
274+ record_used : Option < Span > )
275+ -> Result < & ' a NameBinding < ' a > , Determinacy > {
250276 let mut module = self . current_module ;
251- let mut potential_expanded_shadower = None ;
277+ let mut potential_expanded_shadower: Option < & NameBinding > = None ;
252278 loop {
253279 // Since expanded macros may not shadow the lexical scope (enforced below),
254280 // we can ignore unresolved invocations (indicated by the penultimate argument).
255281 match self . resolve_name_in_module ( module, name, ns, true , record_used) {
256282 Ok ( binding) => {
257283 let span = match record_used {
258284 Some ( span) => span,
259- None => return Some ( binding) ,
285+ None => return Ok ( binding) ,
260286 } ;
261- if let Some ( shadower ) = potential_expanded_shadower {
262- self . ambiguity_errors . push ( AmbiguityError {
263- span : span , name : name , b1 : shadower , b2 : binding , lexical : true ,
264- } ) ;
265- return Some ( shadower ) ;
266- } else if binding . expansion == Mark :: root ( ) {
267- return Some ( binding ) ;
268- } else {
269- potential_expanded_shadower = Some ( binding) ;
287+ match potential_expanded_shadower {
288+ Some ( shadower ) if shadower . def ( ) != binding . def ( ) => {
289+ self . ambiguity_errors . push ( AmbiguityError {
290+ span : span , name : name , b1 : shadower , b2 : binding , lexical : true ,
291+ } ) ;
292+ return Ok ( shadower ) ;
293+ }
294+ _ if binding . expansion == Mark :: root ( ) => return Ok ( binding ) ,
295+ _ => potential_expanded_shadower = Some ( binding) ,
270296 }
271297 } ,
272- Err ( Determinacy :: Undetermined ) => return None ,
298+ Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
273299 Err ( Determinacy :: Determined ) => { }
274300 }
275301
276302 match module. kind {
277303 ModuleKind :: Block ( ..) => module = module. parent . unwrap ( ) ,
278- ModuleKind :: Def ( ..) => return potential_expanded_shadower,
304+ ModuleKind :: Def ( ..) => return match potential_expanded_shadower {
305+ Some ( binding) => Ok ( binding) ,
306+ None if record_used. is_some ( ) => Err ( Determinacy :: Determined ) ,
307+ None => Err ( Determinacy :: Undetermined ) ,
308+ } ,
279309 }
280310 }
281311 }
@@ -343,12 +373,22 @@ impl<'a> Resolver<'a> {
343373
344374 pub fn finalize_current_module_macro_resolutions ( & mut self ) {
345375 let module = self . current_module ;
376+ for & ( ref path, scope, span) in module. macro_resolutions . borrow ( ) . iter ( ) {
377+ match self . resolve_path ( path, scope, Some ( MacroNS ) , Some ( span) ) {
378+ PathResult :: NonModule ( _) => { } ,
379+ PathResult :: Failed ( msg, _) => {
380+ resolve_error ( self , span, ResolutionError :: FailedToResolve ( & msg) ) ;
381+ }
382+ _ => unreachable ! ( ) ,
383+ }
384+ }
385+
346386 for & ( mark, name, span) in module. legacy_macro_resolutions . borrow ( ) . iter ( ) {
347387 let legacy_scope = & self . invocations [ & mark] . legacy_scope ;
348388 let legacy_resolution = self . resolve_legacy_scope ( legacy_scope, name, true ) ;
349- let resolution = self . resolve_in_item_lexical_scope ( name, MacroNS , Some ( span) ) ;
389+ let resolution = self . resolve_lexical_macro_path_segment ( name, MacroNS , Some ( span) ) ;
350390 let ( legacy_resolution, resolution) = match ( legacy_resolution, resolution) {
351- ( Some ( legacy_resolution) , Some ( resolution) ) => ( legacy_resolution, resolution) ,
391+ ( Some ( legacy_resolution) , Ok ( resolution) ) => ( legacy_resolution, resolution) ,
352392 _ => continue ,
353393 } ;
354394 let ( legacy_span, participle) = match legacy_resolution {
0 commit comments