1
1
use rustc_ast:: { DUMMY_NODE_ID , EIIImpl , EiiMacroFor , ItemKind , ast} ;
2
+ use rustc_ast_pretty:: pprust:: path_to_string;
2
3
use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
3
4
use rustc_span:: { Span , kw} ;
4
5
6
+ use crate :: errors:: {
7
+ EIIMacroExpectedFunction , EIIMacroExpectedMaxOneArgument , EIIMacroForExpectedList ,
8
+ EIIMacroForExpectedMacro , EIIMacroForExpectedUnsafe ,
9
+ } ;
10
+
5
11
pub ( crate ) fn eii_macro_for (
6
12
ecx : & mut ExtCtxt < ' _ > ,
7
- _span : Span ,
13
+ span : Span ,
8
14
meta_item : & ast:: MetaItem ,
9
15
mut item : Annotatable ,
10
16
) -> 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
+ } ;
13
30
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
+ }
15
35
16
36
let Some ( extern_item_path) = list. get ( 0 ) . and_then ( |i| i. meta_item ( ) ) . map ( |i| i. path . clone ( ) )
17
37
else {
18
- panic ! ( "expected a path to an `extern` item" ) ;
38
+ ecx. dcx ( ) . emit_err ( EIIMacroForExpectedList { span : meta_item. span } ) ;
39
+ return vec ! [ item] ;
19
40
} ;
20
41
21
42
let impl_unsafe = if let Some ( i) = list. get ( 1 ) {
22
43
if i. lit ( ) . and_then ( |i| i. kind . str ( ) ) . is_some_and ( |i| i == kw:: Unsafe ) {
23
44
true
24
45
} 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] ;
26
48
}
27
49
} else {
28
50
false
@@ -40,11 +62,32 @@ pub(crate) fn eii_macro(
40
62
meta_item : & ast:: MetaItem ,
41
63
mut item : Annotatable ,
42
64
) -> 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
+ } ;
44
70
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
+ } ;
46
76
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
+ } ;
48
91
49
92
f. eii_impl . push ( EIIImpl {
50
93
node_id : DUMMY_NODE_ID ,
0 commit comments