1919//!
2020//! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
2121use base_db:: CrateId ;
22- use rustc_hash:: FxHashMap ;
22+ use rustc_hash:: { FxHashMap , FxHashSet } ;
2323use syntax:: { ted, Parse , SyntaxNode , TextRange , TextSize , WalkEvent } ;
2424use triomphe:: Arc ;
2525
@@ -29,7 +29,7 @@ use crate::{
2929 hygiene:: Hygiene ,
3030 mod_path:: ModPath ,
3131 EagerCallInfo , ExpandError , ExpandResult , ExpandTo , InFile , MacroCallId , MacroCallKind ,
32- MacroCallLoc , MacroDefId , MacroDefKind , UnresolvedMacro ,
32+ MacroCallLoc , MacroDefId , MacroDefKind ,
3333} ;
3434
3535pub fn expand_eager_macro_input (
@@ -38,7 +38,7 @@ pub fn expand_eager_macro_input(
3838 macro_call : InFile < ast:: MacroCall > ,
3939 def : MacroDefId ,
4040 resolver : & dyn Fn ( ModPath ) -> Option < MacroDefId > ,
41- ) -> Result < ExpandResult < Option < MacroCallId > > , UnresolvedMacro > {
41+ ) -> ExpandResult < Option < MacroCallId > > {
4242 let ast_map = db. ast_id_map ( macro_call. file_id ) ;
4343 // the expansion which the ast id map is built upon has no whitespace, so the offsets are wrong as macro_call is from the token tree that has whitespace!
4444 let call_id = InFile :: new ( macro_call. file_id , ast_map. ast_id ( & macro_call. value ) ) ;
@@ -71,22 +71,23 @@ pub fn expand_eager_macro_input(
7171 InFile :: new ( arg_id. as_file ( ) , arg_exp. syntax_node ( ) ) ,
7272 krate,
7373 resolver,
74- ) ?
74+ )
7575 } ;
7676 let err = parse_err. or ( err) ;
7777
7878 let Some ( ( expanded_eager_input, mapping) ) = expanded_eager_input else {
79- return Ok ( ExpandResult { value : None , err } ) ;
79+ return ExpandResult { value : None , err } ;
8080 } ;
8181
8282 let ( mut subtree, expanded_eager_input_token_map) =
8383 mbe:: syntax_node_to_token_tree ( & expanded_eager_input) ;
8484
8585 let og_tmap = if let Some ( tt) = macro_call. value . token_tree ( ) {
86- let og_tmap = mbe:: syntax_node_to_token_map ( tt. syntax ( ) ) ;
86+ let mut ids_used = FxHashSet :: default ( ) ;
87+ let mut og_tmap = mbe:: syntax_node_to_token_map ( tt. syntax ( ) ) ;
8788 // The tokenmap and ids of subtree point into the expanded syntax node, but that is inaccessible from the outside
8889 // so we need to remap them to the original input of the eager macro.
89- subtree. visit_ids ( & |id| {
90+ subtree. visit_ids ( & mut |id| {
9091 // Note: we discard all token ids of braces and the like here, but that's not too bad and only a temporary fix
9192
9293 if let Some ( range) = expanded_eager_input_token_map
@@ -97,13 +98,15 @@ pub fn expand_eager_macro_input(
9798 // remap from eager input expansion to original eager input
9899 if let Some ( & og_range) = ws_mapping. get ( og_range) {
99100 if let Some ( og_token) = og_tmap. token_by_range ( og_range) {
101+ ids_used. insert ( og_token) ;
100102 return og_token;
101103 }
102104 }
103105 }
104106 }
105107 tt:: TokenId :: UNSPECIFIED
106108 } ) ;
109+ og_tmap. filter ( |id| ids_used. contains ( & id) ) ;
107110 og_tmap
108111 } else {
109112 Default :: default ( )
@@ -121,7 +124,7 @@ pub fn expand_eager_macro_input(
121124 kind : MacroCallKind :: FnLike { ast_id : call_id, expand_to } ,
122125 } ;
123126
124- Ok ( ExpandResult { value : Some ( db. intern_macro_call ( loc) ) , err } )
127+ ExpandResult { value : Some ( db. intern_macro_call ( loc) ) , err }
125128}
126129
127130fn lazy_expand (
@@ -147,13 +150,13 @@ fn eager_macro_recur(
147150 curr : InFile < SyntaxNode > ,
148151 krate : CrateId ,
149152 macro_resolver : & dyn Fn ( ModPath ) -> Option < MacroDefId > ,
150- ) -> Result < ExpandResult < Option < ( SyntaxNode , FxHashMap < TextRange , TextRange > ) > > , UnresolvedMacro > {
153+ ) -> ExpandResult < Option < ( SyntaxNode , FxHashMap < TextRange , TextRange > ) > > {
151154 let original = curr. value . clone_for_update ( ) ;
152155 let mut mapping = FxHashMap :: default ( ) ;
153156
154157 let mut replacements = Vec :: new ( ) ;
155158
156- // Note : We only report a single error inside of eager expansions
159+ // FIXME : We only report a single error inside of eager expansions
157160 let mut error = None ;
158161 let mut offset = 0i32 ;
159162 let apply_offset = |it : TextSize , offset : i32 | {
@@ -184,24 +187,28 @@ fn eager_macro_recur(
184187 }
185188 } ;
186189 let def = match call. path ( ) . and_then ( |path| ModPath :: from_src ( db, path, hygiene) ) {
187- Some ( path) => macro_resolver ( path. clone ( ) ) . ok_or ( UnresolvedMacro { path } ) ?,
190+ Some ( path) => match macro_resolver ( path. clone ( ) ) {
191+ Some ( def) => def,
192+ None => {
193+ error =
194+ Some ( ExpandError :: other ( format ! ( "unresolved macro {}" , path. display( db) ) ) ) ;
195+ continue ;
196+ }
197+ } ,
188198 None => {
189199 error = Some ( ExpandError :: other ( "malformed macro invocation" ) ) ;
190200 continue ;
191201 }
192202 } ;
193203 let ExpandResult { value, err } = match def. kind {
194204 MacroDefKind :: BuiltInEager ( ..) => {
195- let ExpandResult { value, err } = match expand_eager_macro_input (
205+ let ExpandResult { value, err } = expand_eager_macro_input (
196206 db,
197207 krate,
198208 curr. with_value ( call. clone ( ) ) ,
199209 def,
200210 macro_resolver,
201- ) {
202- Ok ( it) => it,
203- Err ( err) => return Err ( err) ,
204- } ;
211+ ) ;
205212 match value {
206213 Some ( call_id) => {
207214 let ExpandResult { value, err : err2 } =
@@ -251,7 +258,7 @@ fn eager_macro_recur(
251258 parse. as_ref ( ) . map ( |it| it. syntax_node ( ) ) ,
252259 krate,
253260 macro_resolver,
254- ) ? ;
261+ ) ;
255262 let err = err. or ( error) ;
256263
257264 if let Some ( tt) = call. token_tree ( ) {
@@ -281,7 +288,7 @@ fn eager_macro_recur(
281288 }
282289 // check if the whole original syntax is replaced
283290 if call. syntax ( ) == & original {
284- return Ok ( ExpandResult { value : value. zip ( Some ( mapping) ) , err : error } ) ;
291+ return ExpandResult { value : value. zip ( Some ( mapping) ) , err : error } ;
285292 }
286293
287294 if let Some ( insert) = value {
@@ -292,5 +299,5 @@ fn eager_macro_recur(
292299 }
293300
294301 replacements. into_iter ( ) . rev ( ) . for_each ( |( old, new) | ted:: replace ( old. syntax ( ) , new) ) ;
295- Ok ( ExpandResult { value : Some ( ( original, mapping) ) , err : error } )
302+ ExpandResult { value : Some ( ( original, mapping) ) , err : error }
296303}
0 commit comments