Skip to content

Commit

Permalink
Rollup merge of rust-lang#74203 - nnethercote:enforce-static-symbol-o…
Browse files Browse the repository at this point in the history
…rder, r=petrochenkov

Enforce the static symbol order.

By making the proc macro abort if any symbols are out of order.

The commit also changes the proc macro collect multiple errors (of order
or duplicated symbols) and prints them at the end, which is useful if
you have multiple errors.

r? @petrochenkov
  • Loading branch information
Manishearth authored Jul 11, 2020
2 parents 5ef9245 + 714b6ec commit f5ee28f
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 138 deletions.
29 changes: 24 additions & 5 deletions src/librustc_macros/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,29 @@ pub fn symbols(input: TokenStream) -> TokenStream {
let mut prefill_stream = quote! {};
let mut counter = 0u32;
let mut keys = HashSet::<String>::new();
let mut prev_key: Option<String> = None;
let mut errors = Vec::<String>::new();

let mut check_dup = |str: &str| {
let mut check_dup = |str: &str, errors: &mut Vec<String>| {
if !keys.insert(str.to_string()) {
panic!("Symbol `{}` is duplicated", str);
errors.push(format!("Symbol `{}` is duplicated", str));
}
};

let mut check_order = |str: &str, errors: &mut Vec<String>| {
if let Some(ref prev_str) = prev_key {
if str < prev_str {
errors.push(format!("Symbol `{}` must precede `{}`", str, prev_str));
}
}
prev_key = Some(str.to_string());
};

// Generate the listed keywords.
for keyword in &input.keywords.0 {
let name = &keyword.name;
let value = &keyword.value;
check_dup(&value.value());
check_dup(&value.value(), &mut errors);
prefill_stream.extend(quote! {
#value,
});
Expand All @@ -116,7 +127,8 @@ pub fn symbols(input: TokenStream) -> TokenStream {
Some(value) => value.value(),
None => name.to_string(),
};
check_dup(&value);
check_dup(&value, &mut errors);
check_order(&name.to_string(), &mut errors);
prefill_stream.extend(quote! {
#value,
});
Expand All @@ -131,7 +143,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
// Generate symbols for the strings "0", "1", ..., "9".
for n in 0..10 {
let n = n.to_string();
check_dup(&n);
check_dup(&n, &mut errors);
prefill_stream.extend(quote! {
#n,
});
Expand All @@ -141,6 +153,13 @@ pub fn symbols(input: TokenStream) -> TokenStream {
counter += 1;
}

if !errors.is_empty() {
for error in errors.into_iter() {
eprintln!("error: {}", error)
}
panic!("errors in `Keywords` and/or `Symbols`");
}

let tt = TokenStream::from(quote! {
macro_rules! keywords {
() => {
Expand Down
Loading

0 comments on commit f5ee28f

Please sign in to comment.