@@ -41,6 +41,7 @@ use tracing::{debug, trace};
4141
4242use crate :: def_id:: { CRATE_DEF_ID , CrateNum , DefId , LOCAL_CRATE , StableCrateId } ;
4343use crate :: edition:: Edition ;
44+ use crate :: source_map:: SourceMap ;
4445use crate :: symbol:: { Symbol , kw, sym} ;
4546use crate :: { DUMMY_SP , HashStableContext , Span , SpanDecoder , SpanEncoder , with_session_globals} ;
4647
@@ -907,6 +908,30 @@ impl SyntaxContext {
907908 pub fn edition ( self ) -> Edition {
908909 HygieneData :: with ( |data| data. expn_data ( data. outer_expn ( self ) ) . edition )
909910 }
911+
912+ /// Returns whether this context originates in a foreign crate's external macro.
913+ ///
914+ /// This is used to test whether a lint should not even begin to figure out whether it should
915+ /// be reported on the current node.
916+ pub fn in_external_macro ( self , sm : & SourceMap ) -> bool {
917+ let expn_data = self . outer_expn_data ( ) ;
918+ match expn_data. kind {
919+ ExpnKind :: Root
920+ | ExpnKind :: Desugaring (
921+ DesugaringKind :: ForLoop
922+ | DesugaringKind :: WhileLoop
923+ | DesugaringKind :: OpaqueTy
924+ | DesugaringKind :: Async
925+ | DesugaringKind :: Await ,
926+ ) => false ,
927+ ExpnKind :: AstPass ( _) | ExpnKind :: Desugaring ( _) => true , // well, it's "external"
928+ ExpnKind :: Macro ( MacroKind :: Bang , _) => {
929+ // Dummy span for the `def_site` means it's an external macro.
930+ expn_data. def_site . is_dummy ( ) || sm. is_imported ( expn_data. def_site )
931+ }
932+ ExpnKind :: Macro { .. } => true , // definitely a plugin
933+ }
934+ }
910935}
911936
912937impl fmt:: Debug for SyntaxContext {
0 commit comments