diff options
Diffstat (limited to 'crates/hir_expand')
-rw-r--r-- | crates/hir_expand/src/db.rs | 138 | ||||
-rw-r--r-- | crates/hir_expand/src/diagnostics.rs | 9 | ||||
-rw-r--r-- | crates/hir_expand/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/hir_expand/src/proc_macro.rs | 2 |
4 files changed, 90 insertions, 65 deletions
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index ade57ac1b..ff50bfd82 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use base_db::{salsa, SourceDatabase}; | 5 | use base_db::{salsa, SourceDatabase}; |
6 | use mbe::{ExpandResult, MacroRules}; | 6 | use mbe::{ExpandError, ExpandResult, MacroRules}; |
7 | use parser::FragmentKind; | 7 | use parser::FragmentKind; |
8 | use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; | 8 | use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; |
9 | 9 | ||
@@ -75,9 +75,14 @@ pub trait AstDatabase: SourceDatabase { | |||
75 | #[salsa::transparent] | 75 | #[salsa::transparent] |
76 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; | 76 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; |
77 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; | 77 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; |
78 | fn parse_macro(&self, macro_file: MacroFile) | 78 | fn parse_macro_expansion( |
79 | -> Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>; | 79 | &self, |
80 | fn macro_expand(&self, macro_call: MacroCallId) -> (Option<Arc<tt::Subtree>>, Option<String>); | 80 | macro_file: MacroFile, |
81 | ) -> ExpandResult<Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>>; | ||
82 | fn macro_expand(&self, macro_call: MacroCallId) -> ExpandResult<Option<Arc<tt::Subtree>>>; | ||
83 | |||
84 | /// Firewall query that returns the error from the `macro_expand` query. | ||
85 | fn macro_expand_error(&self, macro_call: MacroCallId) -> Option<ExpandError>; | ||
81 | 86 | ||
82 | #[salsa::interned] | 87 | #[salsa::interned] |
83 | fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; | 88 | fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; |
@@ -102,23 +107,20 @@ pub fn expand_hypothetical( | |||
102 | let token_id = tmap_1.token_by_range(range)?; | 107 | let token_id = tmap_1.token_by_range(range)?; |
103 | let macro_def = expander(db, actual_macro_call)?; | 108 | let macro_def = expander(db, actual_macro_call)?; |
104 | let (node, tmap_2) = | 109 | let (node, tmap_2) = |
105 | parse_macro_with_arg(db, macro_file, Some(std::sync::Arc::new((tt, tmap_1))))?; | 110 | parse_macro_with_arg(db, macro_file, Some(std::sync::Arc::new((tt, tmap_1)))).value?; |
106 | let token_id = macro_def.0.map_id_down(token_id); | 111 | let token_id = macro_def.0.map_id_down(token_id); |
107 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; | 112 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; |
108 | let token = syntax::algo::find_covering_element(&node.syntax_node(), range).into_token()?; | 113 | let token = syntax::algo::find_covering_element(&node.syntax_node(), range).into_token()?; |
109 | Some((node.syntax_node(), token)) | 114 | Some((node.syntax_node(), token)) |
110 | } | 115 | } |
111 | 116 | ||
112 | pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { | 117 | fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { |
113 | let map = | 118 | let map = |
114 | db.parse_or_expand(file_id).map_or_else(AstIdMap::default, |it| AstIdMap::from_source(&it)); | 119 | db.parse_or_expand(file_id).map_or_else(AstIdMap::default, |it| AstIdMap::from_source(&it)); |
115 | Arc::new(map) | 120 | Arc::new(map) |
116 | } | 121 | } |
117 | 122 | ||
118 | pub(crate) fn macro_def( | 123 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { |
119 | db: &dyn AstDatabase, | ||
120 | id: MacroDefId, | ||
121 | ) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | ||
122 | match id.kind { | 124 | match id.kind { |
123 | MacroDefKind::Declarative => { | 125 | MacroDefKind::Declarative => { |
124 | let macro_call = id.ast_id?.to_node(db); | 126 | let macro_call = id.ast_id?.to_node(db); |
@@ -149,7 +151,7 @@ pub(crate) fn macro_def( | |||
149 | } | 151 | } |
150 | } | 152 | } |
151 | 153 | ||
152 | pub(crate) fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> { | 154 | fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> { |
153 | let id = match id { | 155 | let id = match id { |
154 | MacroCallId::LazyMacro(id) => id, | 156 | MacroCallId::LazyMacro(id) => id, |
155 | MacroCallId::EagerMacro(_id) => { | 157 | MacroCallId::EagerMacro(_id) => { |
@@ -162,22 +164,20 @@ pub(crate) fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<Gr | |||
162 | Some(arg.green().clone()) | 164 | Some(arg.green().clone()) |
163 | } | 165 | } |
164 | 166 | ||
165 | pub(crate) fn macro_arg( | 167 | fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { |
166 | db: &dyn AstDatabase, | ||
167 | id: MacroCallId, | ||
168 | ) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { | ||
169 | let arg = db.macro_arg_text(id)?; | 168 | let arg = db.macro_arg_text(id)?; |
170 | let (tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg))?; | 169 | let (tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg))?; |
171 | Some(Arc::new((tt, tmap))) | 170 | Some(Arc::new((tt, tmap))) |
172 | } | 171 | } |
173 | 172 | ||
174 | pub(crate) fn macro_expand( | 173 | fn macro_expand(db: &dyn AstDatabase, id: MacroCallId) -> ExpandResult<Option<Arc<tt::Subtree>>> { |
175 | db: &dyn AstDatabase, | ||
176 | id: MacroCallId, | ||
177 | ) -> (Option<Arc<tt::Subtree>>, Option<String>) { | ||
178 | macro_expand_with_arg(db, id, None) | 174 | macro_expand_with_arg(db, id, None) |
179 | } | 175 | } |
180 | 176 | ||
177 | fn macro_expand_error(db: &dyn AstDatabase, macro_call: MacroCallId) -> Option<ExpandError> { | ||
178 | db.macro_expand(macro_call).err | ||
179 | } | ||
180 | |||
181 | fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 181 | fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { |
182 | let lazy_id = match id { | 182 | let lazy_id = match id { |
183 | MacroCallId::LazyMacro(id) => id, | 183 | MacroCallId::LazyMacro(id) => id, |
@@ -195,17 +195,20 @@ fn macro_expand_with_arg( | |||
195 | db: &dyn AstDatabase, | 195 | db: &dyn AstDatabase, |
196 | id: MacroCallId, | 196 | id: MacroCallId, |
197 | arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, | 197 | arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, |
198 | ) -> (Option<Arc<tt::Subtree>>, Option<String>) { | 198 | ) -> ExpandResult<Option<Arc<tt::Subtree>>> { |
199 | let _p = profile::span("macro_expand"); | ||
199 | let lazy_id = match id { | 200 | let lazy_id = match id { |
200 | MacroCallId::LazyMacro(id) => id, | 201 | MacroCallId::LazyMacro(id) => id, |
201 | MacroCallId::EagerMacro(id) => { | 202 | MacroCallId::EagerMacro(id) => { |
202 | if arg.is_some() { | 203 | if arg.is_some() { |
203 | return ( | 204 | return ExpandResult::str_err( |
204 | None, | 205 | "hypothetical macro expansion not implemented for eager macro".to_owned(), |
205 | Some("hypothetical macro expansion not implemented for eager macro".to_owned()), | ||
206 | ); | 206 | ); |
207 | } else { | 207 | } else { |
208 | return (Some(db.lookup_intern_eager_expansion(id).subtree), None); | 208 | return ExpandResult { |
209 | value: Some(db.lookup_intern_eager_expansion(id).subtree), | ||
210 | err: None, | ||
211 | }; | ||
209 | } | 212 | } |
210 | } | 213 | } |
211 | }; | 214 | }; |
@@ -213,23 +216,27 @@ fn macro_expand_with_arg( | |||
213 | let loc = db.lookup_intern_macro(lazy_id); | 216 | let loc = db.lookup_intern_macro(lazy_id); |
214 | let macro_arg = match arg.or_else(|| db.macro_arg(id)) { | 217 | let macro_arg = match arg.or_else(|| db.macro_arg(id)) { |
215 | Some(it) => it, | 218 | Some(it) => it, |
216 | None => return (None, Some("Fail to args in to tt::TokenTree".into())), | 219 | None => return ExpandResult::str_err("Fail to args in to tt::TokenTree".into()), |
217 | }; | 220 | }; |
218 | 221 | ||
219 | let macro_rules = match db.macro_def(loc.def) { | 222 | let macro_rules = match db.macro_def(loc.def) { |
220 | Some(it) => it, | 223 | Some(it) => it, |
221 | None => return (None, Some("Fail to find macro definition".into())), | 224 | None => return ExpandResult::str_err("Fail to find macro definition".into()), |
222 | }; | 225 | }; |
223 | let ExpandResult(tt, err) = macro_rules.0.expand(db, lazy_id, ¯o_arg.0); | 226 | let ExpandResult { value: tt, err } = macro_rules.0.expand(db, lazy_id, ¯o_arg.0); |
224 | // Set a hard limit for the expanded tt | 227 | // Set a hard limit for the expanded tt |
225 | let count = tt.count(); | 228 | let count = tt.count(); |
226 | if count > 262144 { | 229 | if count > 262144 { |
227 | return (None, Some(format!("Total tokens count exceed limit : count = {}", count))); | 230 | return ExpandResult::str_err(format!( |
231 | "Total tokens count exceed limit : count = {}", | ||
232 | count | ||
233 | )); | ||
228 | } | 234 | } |
229 | (Some(Arc::new(tt)), err.map(|e| format!("{:?}", e))) | 235 | |
236 | ExpandResult { value: Some(Arc::new(tt)), err } | ||
230 | } | 237 | } |
231 | 238 | ||
232 | pub(crate) fn expand_proc_macro( | 239 | fn expand_proc_macro( |
233 | db: &dyn AstDatabase, | 240 | db: &dyn AstDatabase, |
234 | id: MacroCallId, | 241 | id: MacroCallId, |
235 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 242 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
@@ -256,36 +263,37 @@ pub(crate) fn expand_proc_macro( | |||
256 | expander.expand(db, lazy_id, ¯o_arg.0) | 263 | expander.expand(db, lazy_id, ¯o_arg.0) |
257 | } | 264 | } |
258 | 265 | ||
259 | pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> { | 266 | fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> { |
260 | match file_id.0 { | 267 | match file_id.0 { |
261 | HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()), | 268 | HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()), |
262 | HirFileIdRepr::MacroFile(macro_file) => { | 269 | HirFileIdRepr::MacroFile(macro_file) => { |
263 | db.parse_macro(macro_file).map(|(it, _)| it.syntax_node()) | 270 | db.parse_macro_expansion(macro_file).value.map(|(it, _)| it.syntax_node()) |
264 | } | 271 | } |
265 | } | 272 | } |
266 | } | 273 | } |
267 | 274 | ||
268 | pub(crate) fn parse_macro( | 275 | fn parse_macro_expansion( |
269 | db: &dyn AstDatabase, | 276 | db: &dyn AstDatabase, |
270 | macro_file: MacroFile, | 277 | macro_file: MacroFile, |
271 | ) -> Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)> { | 278 | ) -> ExpandResult<Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>> { |
272 | parse_macro_with_arg(db, macro_file, None) | 279 | parse_macro_with_arg(db, macro_file, None) |
273 | } | 280 | } |
274 | 281 | ||
275 | pub fn parse_macro_with_arg( | 282 | fn parse_macro_with_arg( |
276 | db: &dyn AstDatabase, | 283 | db: &dyn AstDatabase, |
277 | macro_file: MacroFile, | 284 | macro_file: MacroFile, |
278 | arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, | 285 | arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, |
279 | ) -> Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)> { | 286 | ) -> ExpandResult<Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>> { |
280 | let _p = profile::span("parse_macro_query"); | ||
281 | |||
282 | let macro_call_id = macro_file.macro_call_id; | 287 | let macro_call_id = macro_file.macro_call_id; |
283 | let (tt, err) = if let Some(arg) = arg { | 288 | let result = if let Some(arg) = arg { |
284 | macro_expand_with_arg(db, macro_call_id, Some(arg)) | 289 | macro_expand_with_arg(db, macro_call_id, Some(arg)) |
285 | } else { | 290 | } else { |
286 | db.macro_expand(macro_call_id) | 291 | db.macro_expand(macro_call_id) |
287 | }; | 292 | }; |
288 | if let Some(err) = &err { | 293 | |
294 | let _p = profile::span("parse_macro_expansion"); | ||
295 | |||
296 | if let Some(err) = &result.err { | ||
289 | // Note: | 297 | // Note: |
290 | // The final goal we would like to make all parse_macro success, | 298 | // The final goal we would like to make all parse_macro success, |
291 | // such that the following log will not call anyway. | 299 | // such that the following log will not call anyway. |
@@ -303,40 +311,50 @@ pub fn parse_macro_with_arg( | |||
303 | .join("\n"); | 311 | .join("\n"); |
304 | 312 | ||
305 | log::warn!( | 313 | log::warn!( |
306 | "fail on macro_parse: (reason: {} macro_call: {:#}) parents: {}", | 314 | "fail on macro_parse: (reason: {:?} macro_call: {:#}) parents: {}", |
307 | err, | 315 | err, |
308 | node.value, | 316 | node.value, |
309 | parents | 317 | parents |
310 | ); | 318 | ); |
311 | } | 319 | } |
312 | _ => { | 320 | _ => { |
313 | log::warn!("fail on macro_parse: (reason: {})", err); | 321 | log::warn!("fail on macro_parse: (reason: {:?})", err); |
314 | } | 322 | } |
315 | } | 323 | } |
324 | } | ||
325 | let tt = match result.value { | ||
326 | Some(tt) => tt, | ||
327 | None => return ExpandResult { value: None, err: result.err }, | ||
316 | }; | 328 | }; |
317 | let tt = tt?; | ||
318 | 329 | ||
319 | let fragment_kind = to_fragment_kind(db, macro_call_id); | 330 | let fragment_kind = to_fragment_kind(db, macro_call_id); |
320 | 331 | ||
321 | let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; | 332 | let (parse, rev_token_map) = match mbe::token_tree_to_syntax_node(&tt, fragment_kind) { |
333 | Ok(it) => it, | ||
334 | Err(err) => { | ||
335 | return ExpandResult::only_err(err); | ||
336 | } | ||
337 | }; | ||
322 | 338 | ||
323 | if err.is_none() { | 339 | match result.err { |
324 | Some((parse, Arc::new(rev_token_map))) | 340 | Some(err) => { |
325 | } else { | 341 | // Safety check for recursive identity macro. |
326 | // FIXME: | 342 | let node = parse.syntax_node(); |
327 | // In future, we should propagate the actual error with recovery information | 343 | let file: HirFileId = macro_file.into(); |
328 | // instead of ignore the error here. | 344 | let call_node = match file.call_node(db) { |
329 | 345 | Some(it) => it, | |
330 | // Safe check for recurisve identity macro | 346 | None => { |
331 | let node = parse.syntax_node(); | 347 | return ExpandResult::only_err(err); |
332 | let file: HirFileId = macro_file.into(); | 348 | } |
333 | let call_node = file.call_node(db)?; | 349 | }; |
334 | 350 | ||
335 | if !diff(&node, &call_node.value).is_empty() { | 351 | if !diff(&node, &call_node.value).is_empty() { |
336 | Some((parse, Arc::new(rev_token_map))) | 352 | ExpandResult { value: Some((parse, Arc::new(rev_token_map))), err: Some(err) } |
337 | } else { | 353 | } else { |
338 | None | 354 | return ExpandResult::only_err(err); |
355 | } | ||
339 | } | 356 | } |
357 | None => ExpandResult { value: Some((parse, Arc::new(rev_token_map))), err: None }, | ||
340 | } | 358 | } |
341 | } | 359 | } |
342 | 360 | ||
diff --git a/crates/hir_expand/src/diagnostics.rs b/crates/hir_expand/src/diagnostics.rs index 1043c6aeb..bf0b85ce9 100644 --- a/crates/hir_expand/src/diagnostics.rs +++ b/crates/hir_expand/src/diagnostics.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | //! | 5 | //! |
6 | //! `DiagnosticSink` struct is used as an emitter for diagnostic. When creating | 6 | //! `DiagnosticSink` struct is used as an emitter for diagnostic. When creating |
7 | //! a `DiagnosticSink`, you supply a callback which can react to a `dyn | 7 | //! a `DiagnosticSink`, you supply a callback which can react to a `dyn |
8 | //! Diagnostic` or to any concrete diagnostic (downcasting is sued internally). | 8 | //! Diagnostic` or to any concrete diagnostic (downcasting is used internally). |
9 | //! | 9 | //! |
10 | //! Because diagnostics store file offsets, it's a bad idea to store them | 10 | //! Because diagnostics store file offsets, it's a bad idea to store them |
11 | //! directly in salsa. For this reason, every hir subsytem defines it's own | 11 | //! directly in salsa. For this reason, every hir subsytem defines it's own |
@@ -32,7 +32,12 @@ impl DiagnosticCode { | |||
32 | pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { | 32 | pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { |
33 | fn code(&self) -> DiagnosticCode; | 33 | fn code(&self) -> DiagnosticCode; |
34 | fn message(&self) -> String; | 34 | fn message(&self) -> String; |
35 | /// Used in highlighting and related purposes | 35 | /// Source element that triggered the diagnostics. |
36 | /// | ||
37 | /// Note that this should reflect "semantics", rather than specific span we | ||
38 | /// want to highlight. When rendering the diagnostics into an error message, | ||
39 | /// the IDE will fetch the `SyntaxNode` and will narrow the span | ||
40 | /// appropriately. | ||
36 | fn display_source(&self) -> InFile<SyntaxNodePtr>; | 41 | fn display_source(&self) -> InFile<SyntaxNodePtr>; |
37 | fn as_any(&self) -> &(dyn Any + Send + 'static); | 42 | fn as_any(&self) -> &(dyn Any + Send + 'static); |
38 | fn is_experimental(&self) -> bool { | 43 | fn is_experimental(&self) -> bool { |
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 17f1178ed..6dad2507b 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -15,6 +15,8 @@ pub mod proc_macro; | |||
15 | pub mod quote; | 15 | pub mod quote; |
16 | pub mod eager; | 16 | pub mod eager; |
17 | 17 | ||
18 | pub use mbe::{ExpandError, ExpandResult}; | ||
19 | |||
18 | use std::hash::Hash; | 20 | use std::hash::Hash; |
19 | use std::sync::Arc; | 21 | use std::sync::Arc; |
20 | 22 | ||
@@ -144,7 +146,7 @@ impl HirFileId { | |||
144 | let def_tt = loc.def.ast_id?.to_node(db).token_tree()?; | 146 | let def_tt = loc.def.ast_id?.to_node(db).token_tree()?; |
145 | 147 | ||
146 | let macro_def = db.macro_def(loc.def)?; | 148 | let macro_def = db.macro_def(loc.def)?; |
147 | let (parse, exp_map) = db.parse_macro(macro_file)?; | 149 | let (parse, exp_map) = db.parse_macro_expansion(macro_file).value?; |
148 | let macro_arg = db.macro_arg(macro_file.macro_call_id)?; | 150 | let macro_arg = db.macro_arg(macro_file.macro_call_id)?; |
149 | 151 | ||
150 | Some(ExpansionInfo { | 152 | Some(ExpansionInfo { |
@@ -253,7 +255,7 @@ pub enum MacroDefKind { | |||
253 | pub struct MacroCallLoc { | 255 | pub struct MacroCallLoc { |
254 | pub(crate) def: MacroDefId, | 256 | pub(crate) def: MacroDefId, |
255 | pub(crate) krate: CrateId, | 257 | pub(crate) krate: CrateId, |
256 | pub(crate) kind: MacroCallKind, | 258 | pub kind: MacroCallKind, |
257 | } | 259 | } |
258 | 260 | ||
259 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 261 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs index 7505cb061..97edf0fb6 100644 --- a/crates/hir_expand/src/proc_macro.rs +++ b/crates/hir_expand/src/proc_macro.rs | |||
@@ -50,7 +50,7 @@ impl ProcMacroExpander { | |||
50 | 50 | ||
51 | proc_macro.expander.expand(&tt, None).map_err(mbe::ExpandError::from) | 51 | proc_macro.expander.expand(&tt, None).map_err(mbe::ExpandError::from) |
52 | } | 52 | } |
53 | None => Err(err!("Unresolved proc macro")), | 53 | None => Err(mbe::ExpandError::UnresolvedProcMacro), |
54 | } | 54 | } |
55 | } | 55 | } |
56 | } | 56 | } |