diff options
| author | bors <bors@rust-lang.org> | 2015-11-27 18:41:53 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-11-27 18:41:53 +0000 |
| commit | 5dc91a74b1428cf3d09a868727bf20b347664137 (patch) | |
| tree | 1c9f0209f7ec74bc6ecbdc83ded5fda46a29c397 /src/libsyntax/ext | |
| parent | ca6365037f2af12d7692672c17788be7e0af98cb (diff) | |
| parent | 4bb7cf11dcb7b4d106456b9c34c2e30638615f47 (diff) | |
| download | rust-5dc91a74b1428cf3d09a868727bf20b347664137.tar.gz rust-5dc91a74b1428cf3d09a868727bf20b347664137.zip | |
Auto merge of #30064 - fhartwig:macro-suggestions, r=sanxiyn
Fixes #13677
This does the same sort of suggestion for misspelt macros that we already do for misspelt identifiers.
Example. Compiling this program:
```rust
macro_rules! foo {
($e:expr) => ( $e )
}
fn main() {
fob!("hello!");
}
```
gives the following error message:
```
/Users/mcp/temp/test.rs:7:5: 7:8 error: macro undefined: 'fob!'
/Users/mcp/temp/test.rs:7 fob!("hello!");
^~~
/Users/mcp/temp/test.rs:7:5: 7:8 help: did you mean `foo`?
/Users/mcp/temp/test.rs:7 fob!("hello!");
```
I had to move the levenshtein distance function into libsyntax for this. Maybe this should live somewhere else (some utility crate?), but I couldn't find a crate to put it in that is imported by libsyntax and the other rustc crates.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 1 |
2 files changed, 16 insertions, 0 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 55f0fa5675a..cf6881ab650 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -24,6 +24,7 @@ use parse::token; use parse::token::{InternedString, intern, str_to_ident}; use ptr::P; use util::small_vector::SmallVector; +use util::lev_distance::{lev_distance, max_suggestion_distance}; use ext::mtwt; use fold::Folder; @@ -776,6 +777,20 @@ impl<'a> ExtCtxt<'a> { pub fn name_of(&self, st: &str) -> ast::Name { token::intern(st) } + + pub fn suggest_macro_name(&mut self, name: &str, span: Span) { + let mut min: Option<(Name, usize)> = None; + let max_dist = max_suggestion_distance(name); + for macro_name in self.syntax_env.names.iter() { + let dist = lev_distance(name, ¯o_name.as_str()); + if dist <= max_dist && (min.is_none() || min.unwrap().1 > dist) { + min = Some((*macro_name, dist)); + } + } + if let Some((suggestion, _)) = min { + self.fileline_help(span, &format!("did you mean `{}!`?", suggestion)); + } + } } /// Extract a string literal from the macro expanded version of `expr`, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9b1a7a50201..01e72cf2a8d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -191,6 +191,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, pth.span, &format!("macro undefined: '{}!'", &extname)); + fld.cx.suggest_macro_name(&extname.as_str(), pth.span); // let compilation continue None |
