11use rustc_ast:: { DUMMY_NODE_ID , EIIImpl , EiiMacroFor , ItemKind , ast} ;
2+ use rustc_ast_pretty:: pprust:: path_to_string;
23use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
34use rustc_span:: { Span , kw} ;
45
6+ use crate :: errors:: {
7+ EIIMacroExpectedFunction , EIIMacroExpectedMaxOneArgument , EIIMacroForExpectedList ,
8+ EIIMacroForExpectedMacro , EIIMacroForExpectedUnsafe ,
9+ } ;
10+
511pub ( crate ) fn eii_macro_for (
612 ecx : & mut ExtCtxt < ' _ > ,
7- _span : Span ,
13+ span : Span ,
814 meta_item : & ast:: MetaItem ,
915 mut item : Annotatable ,
1016) -> Vec < Annotatable > {
11- let Annotatable :: Item ( i) = & mut item else { panic ! ( "expected item" ) } ;
12- let ItemKind :: MacroDef ( _, d) = & mut i. kind else { panic ! ( "expected macro def" ) } ;
17+ let Annotatable :: Item ( i) = & mut item else {
18+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedMacro { span } ) ;
19+ return vec ! [ item] ;
20+ } ;
21+ let ItemKind :: MacroDef ( _, d) = & mut i. kind else {
22+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedMacro { span } ) ;
23+ return vec ! [ item] ;
24+ } ;
25+
26+ let Some ( list) = meta_item. meta_item_list ( ) else {
27+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedList { span : meta_item. span } ) ;
28+ return vec ! [ item] ;
29+ } ;
1330
14- let Some ( list) = meta_item. meta_item_list ( ) else { panic ! ( "expected list" ) } ;
31+ if list. len ( ) > 2 {
32+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedList { span : meta_item. span } ) ;
33+ return vec ! [ item] ;
34+ }
1535
1636 let Some ( extern_item_path) = list. get ( 0 ) . and_then ( |i| i. meta_item ( ) ) . map ( |i| i. path . clone ( ) )
1737 else {
18- panic ! ( "expected a path to an `extern` item" ) ;
38+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedList { span : meta_item. span } ) ;
39+ return vec ! [ item] ;
1940 } ;
2041
2142 let impl_unsafe = if let Some ( i) = list. get ( 1 ) {
2243 if i. lit ( ) . and_then ( |i| i. kind . str ( ) ) . is_some_and ( |i| i == kw:: Unsafe ) {
2344 true
2445 } else {
25- panic ! ( "expected the string `\" unsafe\" ` here or no other arguments" ) ;
46+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedUnsafe { span : i. span ( ) } ) ;
47+ return vec ! [ item] ;
2648 }
2749 } else {
2850 false
@@ -40,11 +62,32 @@ pub(crate) fn eii_macro(
4062 meta_item : & ast:: MetaItem ,
4163 mut item : Annotatable ,
4264) -> Vec < Annotatable > {
43- let Annotatable :: Item ( i) = & mut item else { panic ! ( "expected item" ) } ;
65+ let Annotatable :: Item ( i) = & mut item else {
66+ ecx. dcx ( )
67+ . emit_err ( EIIMacroExpectedFunction { span, name : path_to_string ( & meta_item. path ) } ) ;
68+ return vec ! [ item] ;
69+ } ;
4470
45- let ItemKind :: Fn ( f) = & mut i. kind else { panic ! ( "expected function" ) } ;
71+ let ItemKind :: Fn ( f) = & mut i. kind else {
72+ ecx. dcx ( )
73+ . emit_err ( EIIMacroExpectedFunction { span, name : path_to_string ( & meta_item. path ) } ) ;
74+ return vec ! [ item] ;
75+ } ;
4676
47- assert ! ( meta_item. is_word( ) ) ;
77+ let is_default = if meta_item. is_word ( ) {
78+ false
79+ } else if let Some ( [ first] ) = meta_item. meta_item_list ( )
80+ && let Some ( m) = first. meta_item ( )
81+ && m. path . segments . len ( ) == 1
82+ {
83+ m. path . segments [ 0 ] . ident . name == kw:: Default
84+ } else {
85+ ecx. dcx ( ) . emit_err ( EIIMacroExpectedMaxOneArgument {
86+ span : meta_item. span ,
87+ name : path_to_string ( & meta_item. path ) ,
88+ } ) ;
89+ return vec ! [ item] ;
90+ } ;
4891
4992 f. eii_impl . push ( EIIImpl {
5093 node_id : DUMMY_NODE_ID ,
0 commit comments