11#![ deny( rustc:: untranslatable_diagnostic) ]
22
3+ use crate :: base:: ast:: NestedMetaItem ;
34use crate :: errors;
45use crate :: expand:: { self , AstFragment , Invocation } ;
56use crate :: module:: DirOwnership ;
@@ -19,6 +20,7 @@ use rustc_feature::Features;
1920use rustc_lint_defs:: builtin:: PROC_MACRO_BACK_COMPAT ;
2021use rustc_lint_defs:: { BufferedEarlyLint , BuiltinLintDiagnostics , RegisteredTools } ;
2122use rustc_parse:: { parser, MACRO_ARGUMENTS } ;
23+ use rustc_session:: config:: CollapseMacroDebuginfo ;
2224use rustc_session:: errors:: report_lit_error;
2325use rustc_session:: { parse:: ParseSess , Limit , Session } ;
2426use rustc_span:: def_id:: { CrateNum , DefId , LocalDefId } ;
@@ -761,6 +763,75 @@ impl SyntaxExtension {
761763 }
762764 }
763765
766+ fn collapse_debuginfo_by_name ( sess : & Session , attr : & Attribute ) -> CollapseMacroDebuginfo {
767+ use crate :: errors:: CollapseMacroDebuginfoIllegal ;
768+ // #[collapse_debuginfo] without enum value (#[collapse_debuginfo(no/external/yes)])
769+ // considered as `yes`
770+ attr. meta_item_list ( ) . map_or ( CollapseMacroDebuginfo :: Yes , |l| {
771+ let [ NestedMetaItem :: MetaItem ( _item) ] = & l[ ..] else {
772+ sess. dcx ( ) . emit_err ( CollapseMacroDebuginfoIllegal { span : attr. span } ) ;
773+ return CollapseMacroDebuginfo :: Unspecified ;
774+ } ;
775+ let item = l[ 0 ] . meta_item ( ) ;
776+ item. map_or ( CollapseMacroDebuginfo :: Unspecified , |mi| {
777+ if !mi. is_word ( ) {
778+ sess. dcx ( ) . emit_err ( CollapseMacroDebuginfoIllegal { span : mi. span } ) ;
779+ CollapseMacroDebuginfo :: Unspecified
780+ } else {
781+ match mi. name_or_empty ( ) {
782+ sym:: no => CollapseMacroDebuginfo :: No ,
783+ sym:: external => CollapseMacroDebuginfo :: External ,
784+ sym:: yes => CollapseMacroDebuginfo :: Yes ,
785+ _ => {
786+ sess. dcx ( ) . emit_err ( CollapseMacroDebuginfoIllegal { span : mi. span } ) ;
787+ CollapseMacroDebuginfo :: Unspecified
788+ }
789+ }
790+ }
791+ } )
792+ } )
793+ }
794+
795+ /// if-ext - if macro from different crate (related to callsite code)
796+ /// | cmd \ attr | no | (unspecified) | external | yes |
797+ /// | no | no | no | no | no |
798+ /// | (unspecified) | no | no | if-ext | yes |
799+ /// | external | no | if-ext | if-ext | yes |
800+ /// | yes | yes | yes | yes | yes |
801+ pub fn should_collapse (
802+ flag : CollapseMacroDebuginfo ,
803+ attr : CollapseMacroDebuginfo ,
804+ ext : bool ,
805+ ) -> bool {
806+ #[ rustfmt:: skip]
807+ let collapse_table = [
808+ [ false , false , false , false ] ,
809+ [ false , false , ext, true ] ,
810+ [ false , ext, ext, true ] ,
811+ [ true , true , true , true ] ,
812+ ] ;
813+ let rv = collapse_table[ flag as usize ] [ attr as usize ] ;
814+ tracing:: debug!( ?flag, ?attr, ?ext, ?rv) ;
815+ rv
816+ }
817+
818+ fn get_collapse_debuginfo (
819+ sess : & Session ,
820+ span : Span ,
821+ attrs : & [ ast:: Attribute ] ,
822+ is_local : bool ,
823+ ) -> bool {
824+ let collapse_debuginfo_attr = attr:: find_by_name ( attrs, sym:: collapse_debuginfo)
825+ . map ( |v| Self :: collapse_debuginfo_by_name ( sess, v) )
826+ . unwrap_or ( CollapseMacroDebuginfo :: Unspecified ) ;
827+ debug ! ( "get_collapse_debuginfo span {:?} attrs: {:?}, is_ext: {}" , span, attrs, !is_local) ;
828+ Self :: should_collapse (
829+ sess. opts . unstable_opts . collapse_macro_debuginfo ,
830+ collapse_debuginfo_attr,
831+ !is_local,
832+ )
833+ }
834+
764835 /// Constructs a syntax extension with the given properties
765836 /// and other properties converted from attributes.
766837 pub fn new (
@@ -772,6 +843,7 @@ impl SyntaxExtension {
772843 edition : Edition ,
773844 name : Symbol ,
774845 attrs : & [ ast:: Attribute ] ,
846+ is_local : bool ,
775847 ) -> SyntaxExtension {
776848 let allow_internal_unstable =
777849 attr:: allow_internal_unstable ( sess, attrs) . collect :: < Vec < Symbol > > ( ) ;
@@ -780,8 +852,8 @@ impl SyntaxExtension {
780852 let local_inner_macros = attr:: find_by_name ( attrs, sym:: macro_export)
781853 . and_then ( |macro_export| macro_export. meta_item_list ( ) )
782854 . is_some_and ( |l| attr:: list_contains_name ( & l, sym:: local_inner_macros) ) ;
783- let collapse_debuginfo = attr :: contains_name ( attrs, sym :: collapse_debuginfo ) ;
784- tracing:: debug!( ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe) ;
855+ let collapse_debuginfo = Self :: get_collapse_debuginfo ( sess , span , attrs, is_local ) ;
856+ tracing:: debug!( ?name , ? local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe) ;
785857
786858 let ( builtin_name, helper_attrs) = attr:: find_by_name ( attrs, sym:: rustc_builtin_macro)
787859 . map ( |attr| {
0 commit comments