@@ -26,19 +26,89 @@ use crate::{
2626} ;
2727
2828use base_db:: CrateId ;
29+ use mbe:: ExpandResult ;
2930use parser:: FragmentKind ;
3031use std:: sync:: Arc ;
3132use syntax:: { algo:: SyntaxRewriter , SyntaxNode } ;
3233
34+ pub struct ErrorEmitted {
35+ _private : ( ) ,
36+ }
37+
38+ trait ErrorSink {
39+ fn emit ( & mut self , err : mbe:: ExpandError ) ;
40+
41+ fn option < T > (
42+ & mut self ,
43+ opt : Option < T > ,
44+ error : impl FnOnce ( ) -> mbe:: ExpandError ,
45+ ) -> Result < T , ErrorEmitted > {
46+ match opt {
47+ Some ( it) => Ok ( it) ,
48+ None => {
49+ self . emit ( error ( ) ) ;
50+ Err ( ErrorEmitted { _private : ( ) } )
51+ }
52+ }
53+ }
54+
55+ fn option_with < T > (
56+ & mut self ,
57+ opt : impl FnOnce ( ) -> Option < T > ,
58+ error : impl FnOnce ( ) -> mbe:: ExpandError ,
59+ ) -> Result < T , ErrorEmitted > {
60+ self . option ( opt ( ) , error)
61+ }
62+
63+ fn result < T > ( & mut self , res : Result < T , mbe:: ExpandError > ) -> Result < T , ErrorEmitted > {
64+ match res {
65+ Ok ( it) => Ok ( it) ,
66+ Err ( e) => {
67+ self . emit ( e) ;
68+ Err ( ErrorEmitted { _private : ( ) } )
69+ }
70+ }
71+ }
72+
73+ fn expand_result_option < T > ( & mut self , res : ExpandResult < Option < T > > ) -> Result < T , ErrorEmitted > {
74+ match ( res. value , res. err ) {
75+ ( None , Some ( err) ) => {
76+ self . emit ( err) ;
77+ Err ( ErrorEmitted { _private : ( ) } )
78+ }
79+ ( Some ( value) , opt_err) => {
80+ if let Some ( err) = opt_err {
81+ self . emit ( err) ;
82+ }
83+ Ok ( value)
84+ }
85+ ( None , None ) => unreachable ! ( "`ExpandResult` without value or error" ) ,
86+ }
87+ }
88+ }
89+
90+ impl ErrorSink for & ' _ mut dyn FnMut ( mbe:: ExpandError ) {
91+ fn emit ( & mut self , err : mbe:: ExpandError ) {
92+ self ( err) ;
93+ }
94+ }
95+
96+ fn err ( msg : impl Into < String > ) -> mbe:: ExpandError {
97+ mbe:: ExpandError :: Other ( msg. into ( ) )
98+ }
99+
33100pub fn expand_eager_macro (
34101 db : & dyn AstDatabase ,
35102 krate : CrateId ,
36103 macro_call : InFile < ast:: MacroCall > ,
37104 def : MacroDefId ,
38105 resolver : & dyn Fn ( ast:: Path ) -> Option < MacroDefId > ,
39- ) -> Option < EagerMacroId > {
40- let args = macro_call. value . token_tree ( ) ?;
41- let parsed_args = mbe:: ast_to_token_tree ( & args) ?. 0 ;
106+ mut error_sink : & mut dyn FnMut ( mbe:: ExpandError ) ,
107+ ) -> Result < EagerMacroId , ErrorEmitted > {
108+ let parsed_args = error_sink. option_with (
109+ || Some ( mbe:: ast_to_token_tree ( & macro_call. value . token_tree ( ) ?) ?. 0 ) ,
110+ || err ( "malformed macro invocation" ) ,
111+ ) ?;
42112
43113 // Note:
44114 // When `lazy_expand` is called, its *parent* file must be already exists.
@@ -55,17 +125,21 @@ pub fn expand_eager_macro(
55125 } ) ;
56126 let arg_file_id: MacroCallId = arg_id. into ( ) ;
57127
58- let parsed_args = mbe:: token_tree_to_syntax_node ( & parsed_args, FragmentKind :: Expr ) . ok ( ) ?. 0 ;
128+ let parsed_args =
129+ error_sink. result ( mbe:: token_tree_to_syntax_node ( & parsed_args, FragmentKind :: Expr ) ) ?. 0 ;
59130 let result = eager_macro_recur (
60131 db,
61132 InFile :: new ( arg_file_id. as_file ( ) , parsed_args. syntax_node ( ) ) ,
62133 krate,
63134 resolver,
135+ error_sink,
64136 ) ?;
65- let subtree = to_subtree ( & result) ?;
137+ let subtree = error_sink . option ( to_subtree ( & result) , || err ( "failed to parse macro result" ) ) ?;
66138
67139 if let MacroDefKind :: BuiltInEager ( eager) = def. kind {
68- let ( subtree, fragment) = eager. expand ( db, arg_id, & subtree) . value ?;
140+ let res = eager. expand ( db, arg_id, & subtree) ;
141+
142+ let ( subtree, fragment) = error_sink. expand_result_option ( res) ?;
69143 let eager = EagerCallLoc {
70144 def,
71145 fragment,
@@ -74,9 +148,9 @@ pub fn expand_eager_macro(
74148 file_id : macro_call. file_id ,
75149 } ;
76150
77- Some ( db. intern_eager_expansion ( eager) )
151+ Ok ( db. intern_eager_expansion ( eager) )
78152 } else {
79- None
153+ panic ! ( "called `expand_eager_macro` on non-eager macro def {:?}" , def ) ;
80154 }
81155}
82156
@@ -91,29 +165,34 @@ fn lazy_expand(
91165 def : & MacroDefId ,
92166 macro_call : InFile < ast:: MacroCall > ,
93167 krate : CrateId ,
94- ) -> Option < InFile < SyntaxNode > > {
168+ ) -> ExpandResult < Option < InFile < SyntaxNode > > > {
95169 let ast_id = db. ast_id_map ( macro_call. file_id ) . ast_id ( & macro_call. value ) ;
96170
97171 let id: MacroCallId =
98172 def. as_lazy_macro ( db, krate, MacroCallKind :: FnLike ( macro_call. with_value ( ast_id) ) ) . into ( ) ;
99173
100- db. parse_or_expand ( id. as_file ( ) ) . map ( |node| InFile :: new ( id. as_file ( ) , node) )
174+ let err = db. macro_expand_error ( id) ;
175+ let value = db. parse_or_expand ( id. as_file ( ) ) . map ( |node| InFile :: new ( id. as_file ( ) , node) ) ;
176+
177+ ExpandResult { value, err }
101178}
102179
103180fn eager_macro_recur (
104181 db : & dyn AstDatabase ,
105182 curr : InFile < SyntaxNode > ,
106183 krate : CrateId ,
107184 macro_resolver : & dyn Fn ( ast:: Path ) -> Option < MacroDefId > ,
108- ) -> Option < SyntaxNode > {
185+ mut error_sink : & mut dyn FnMut ( mbe:: ExpandError ) ,
186+ ) -> Result < SyntaxNode , ErrorEmitted > {
109187 let original = curr. value . clone ( ) ;
110188
111189 let children = curr. value . descendants ( ) . filter_map ( ast:: MacroCall :: cast) ;
112190 let mut rewriter = SyntaxRewriter :: default ( ) ;
113191
114192 // Collect replacement
115193 for child in children {
116- let def: MacroDefId = macro_resolver ( child. path ( ) ?) ?;
194+ let def = error_sink
195+ . option_with ( || macro_resolver ( child. path ( ) ?) , || err ( "failed to resolve macro" ) ) ?;
117196 let insert = match def. kind {
118197 MacroDefKind :: BuiltInEager ( _) => {
119198 let id: MacroCallId = expand_eager_macro (
@@ -122,23 +201,27 @@ fn eager_macro_recur(
122201 curr. with_value ( child. clone ( ) ) ,
123202 def,
124203 macro_resolver,
204+ error_sink,
125205 ) ?
126206 . into ( ) ;
127- db. parse_or_expand ( id. as_file ( ) ) ?
207+ db. parse_or_expand ( id. as_file ( ) )
208+ . expect ( "successful macro expansion should be parseable" )
128209 }
129210 MacroDefKind :: Declarative
130211 | MacroDefKind :: BuiltIn ( _)
131212 | MacroDefKind :: BuiltInDerive ( _)
132213 | MacroDefKind :: ProcMacro ( _) => {
133- let expanded = lazy_expand ( db, & def, curr. with_value ( child. clone ( ) ) , krate) ?;
214+ let res = lazy_expand ( db, & def, curr. with_value ( child. clone ( ) ) , krate) ;
215+ let val = error_sink. expand_result_option ( res) ?;
216+
134217 // replace macro inside
135- eager_macro_recur ( db, expanded , krate, macro_resolver) ?
218+ eager_macro_recur ( db, val , krate, macro_resolver, error_sink ) ?
136219 }
137220 } ;
138221
139222 rewriter. replace ( child. syntax ( ) , & insert) ;
140223 }
141224
142225 let res = rewriter. rewrite ( & original) ;
143- Some ( res)
226+ Ok ( res)
144227}
0 commit comments