@@ -12,24 +12,24 @@ use rustc_ast_pretty::pprust;
1212use rustc_attr:: StabilityLevel ;
1313use rustc_data_structures:: fx:: FxHashSet ;
1414use rustc_data_structures:: ptr_key:: PtrKey ;
15+ use rustc_data_structures:: sync:: Lrc ;
1516use rustc_errors:: struct_span_err;
1617use rustc_expand:: base:: { Indeterminate , InvocationRes , ResolverExpand , SyntaxExtension } ;
1718use rustc_expand:: compile_declarative_macro;
18- use rustc_expand:: expand:: { AstFragment , AstFragmentKind , Invocation , InvocationKind } ;
19+ use rustc_expand:: expand:: { AstFragment , Invocation , InvocationKind } ;
1920use rustc_feature:: is_builtin_attr_name;
2021use rustc_hir:: def:: { self , DefKind , NonMacroAttrKind } ;
2122use rustc_hir:: def_id;
2223use rustc_middle:: middle:: stability;
2324use rustc_middle:: ty;
2425use rustc_session:: lint:: builtin:: UNUSED_MACROS ;
26+ use rustc_session:: parse:: feature_err;
2527use rustc_session:: Session ;
2628use rustc_span:: edition:: Edition ;
2729use rustc_span:: hygiene:: { self , ExpnData , ExpnId , ExpnKind } ;
30+ use rustc_span:: hygiene:: { AstPass , MacroKind } ;
2831use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
2932use rustc_span:: { Span , DUMMY_SP } ;
30-
31- use rustc_data_structures:: sync:: Lrc ;
32- use rustc_span:: hygiene:: { AstPass , MacroKind } ;
3333use std:: cell:: Cell ;
3434use std:: { mem, ptr} ;
3535
@@ -241,15 +241,20 @@ impl<'a> ResolverExpand for Resolver<'a> {
241241 }
242242 } ;
243243
244- let ( path, kind, derives, after_derive) = match invoc. kind {
244+ let ( path, kind, inner_attr , derives, after_derive) = match invoc. kind {
245245 InvocationKind :: Attr { ref attr, ref derives, after_derive, .. } => (
246246 & attr. get_normal_item ( ) . path ,
247247 MacroKind :: Attr ,
248+ attr. style == ast:: AttrStyle :: Inner ,
248249 self . arenas . alloc_ast_paths ( derives) ,
249250 after_derive,
250251 ) ,
251- InvocationKind :: Bang { ref mac, .. } => ( & mac. path , MacroKind :: Bang , & [ ] [ ..] , false ) ,
252- InvocationKind :: Derive { ref path, .. } => ( path, MacroKind :: Derive , & [ ] [ ..] , false ) ,
252+ InvocationKind :: Bang { ref mac, .. } => {
253+ ( & mac. path , MacroKind :: Bang , false , & [ ] [ ..] , false )
254+ }
255+ InvocationKind :: Derive { ref path, .. } => {
256+ ( path, MacroKind :: Derive , false , & [ ] [ ..] , false )
257+ }
253258 InvocationKind :: DeriveContainer { ref derives, .. } => {
254259 // Block expansion of the container until we resolve all derives in it.
255260 // This is required for two reasons:
@@ -299,8 +304,17 @@ impl<'a> ResolverExpand for Resolver<'a> {
299304
300305 // Derives are not included when `invocations` are collected, so we have to add them here.
301306 let parent_scope = & ParentScope { derives, ..parent_scope } ;
307+ let require_inert = !invoc. fragment_kind . supports_macro_expansion ( ) ;
302308 let node_id = self . lint_node_id ( eager_expansion_root) ;
303- let ( ext, res) = self . smart_resolve_macro_path ( path, kind, parent_scope, node_id, force) ?;
309+ let ( ext, res) = self . smart_resolve_macro_path (
310+ path,
311+ kind,
312+ require_inert,
313+ inner_attr,
314+ parent_scope,
315+ node_id,
316+ force,
317+ ) ?;
304318
305319 let span = invoc. span ( ) ;
306320 invoc_id. set_expn_data ( ext. expn_data (
@@ -318,29 +332,6 @@ impl<'a> ResolverExpand for Resolver<'a> {
318332 self . definitions . add_parent_module_of_macro_def ( invoc_id, normal_module_def_id) ;
319333 }
320334
321- match invoc. fragment_kind {
322- AstFragmentKind :: Arms
323- | AstFragmentKind :: Fields
324- | AstFragmentKind :: FieldPats
325- | AstFragmentKind :: GenericParams
326- | AstFragmentKind :: Params
327- | AstFragmentKind :: StructFields
328- | AstFragmentKind :: Variants => {
329- if let Res :: Def ( ..) = res {
330- self . session . span_err (
331- span,
332- & format ! (
333- "expected an inert attribute, found {} {}" ,
334- res. article( ) ,
335- res. descr( )
336- ) ,
337- ) ;
338- return Ok ( InvocationRes :: Single ( self . dummy_ext ( kind) ) ) ;
339- }
340- }
341- _ => { }
342- }
343-
344335 Ok ( InvocationRes :: Single ( ext) )
345336 }
346337
@@ -403,18 +394,21 @@ impl<'a> ResolverExpand for Resolver<'a> {
403394
404395impl < ' a > Resolver < ' a > {
405396 /// Resolve macro path with error reporting and recovery.
397+ /// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
398+ /// for better error recovery.
406399 fn smart_resolve_macro_path (
407400 & mut self ,
408401 path : & ast:: Path ,
409402 kind : MacroKind ,
403+ require_inert : bool ,
404+ inner_attr : bool ,
410405 parent_scope : & ParentScope < ' a > ,
411406 node_id : NodeId ,
412407 force : bool ,
413408 ) -> Result < ( Lrc < SyntaxExtension > , Res ) , Indeterminate > {
414409 let ( ext, res) = match self . resolve_macro_path ( path, Some ( kind) , parent_scope, true , force)
415410 {
416411 Ok ( ( Some ( ext) , res) ) => ( ext, res) ,
417- // Use dummy syntax extensions for unresolved macros for better recovery.
418412 Ok ( ( None , res) ) => ( self . dummy_ext ( kind) , res) ,
419413 Err ( Determinacy :: Determined ) => ( self . dummy_ext ( kind) , Res :: Err ) ,
420414 Err ( Determinacy :: Undetermined ) => return Err ( Indeterminate ) ,
@@ -451,19 +445,43 @@ impl<'a> Resolver<'a> {
451445
452446 self . check_stability_and_deprecation ( & ext, path, node_id) ;
453447
454- Ok ( if ext. macro_kind ( ) != kind {
455- let expected = kind. descr_expected ( ) ;
448+ let unexpected_res = if ext. macro_kind ( ) != kind {
449+ Some ( ( kind. article ( ) , kind. descr_expected ( ) ) )
450+ } else if require_inert && matches ! ( res, Res :: Def ( ..) ) {
451+ Some ( ( "a" , "non-macro attribute" ) )
452+ } else {
453+ None
454+ } ;
455+ if let Some ( ( article, expected) ) = unexpected_res {
456456 let path_str = pprust:: path_to_string ( path) ;
457457 let msg = format ! ( "expected {}, found {} `{}`" , expected, res. descr( ) , path_str) ;
458458 self . session
459459 . struct_span_err ( path. span , & msg)
460- . span_label ( path. span , format ! ( "not {} {}" , kind . article( ) , expected) )
460+ . span_label ( path. span , format ! ( "not {} {}" , article, expected) )
461461 . emit ( ) ;
462- // Use dummy syntax extensions for unexpected macro kinds for better recovery.
463- ( self . dummy_ext ( kind) , Res :: Err )
464- } else {
465- ( ext, res)
466- } )
462+ return Ok ( ( self . dummy_ext ( kind) , Res :: Err ) ) ;
463+ }
464+
465+ // We are trying to avoid reporting this error if other related errors were reported.
466+ if inner_attr
467+ && !self . session . features_untracked ( ) . custom_inner_attributes
468+ && path != & sym:: test
469+ && res != Res :: Err
470+ {
471+ feature_err (
472+ & self . session . parse_sess ,
473+ sym:: custom_inner_attributes,
474+ path. span ,
475+ match res {
476+ Res :: Def ( ..) => "inner macro attributes are unstable" ,
477+ Res :: NonMacroAttr ( ..) => "custom inner attributes are unstable" ,
478+ _ => unreachable ! ( ) ,
479+ } ,
480+ )
481+ . emit ( ) ;
482+ }
483+
484+ Ok ( ( ext, res) )
467485 }
468486
469487 pub fn resolve_macro_path (
0 commit comments