Почему гигиена макросов не предотвращает коллизии между множественными определениями const?

Я думал, что "гигиена" предотвратит столкновения между Xопределены в моем макросе m! но оказалось, что это не так. Что я недопонимаю?

macro_rules! m {
    ($e:expr) => {
        const X: i32 = $e;
    }
}

m!(0);
m!(1);

fn main() {
    m!(2);
    m!(3);
}

Детский манеж

Сообщение об ошибке:

<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428]
<anon>:3         const X: i32 = $e;
                 ^~~~~~~~~~~~~~~~~~
<anon>:8:1: 8:7 note: in this expansion of m! (defined in <anon>)
<anon>:3:9: 3:27 help: see the detailed explanation for E0428
<anon>:3:9: 3:27 note: first definition of value `X` here
<anon>:3         const X: i32 = $e;
                 ^~~~~~~~~~~~~~~~~~
<anon>:7:1: 7:7 note: in this expansion of m! (defined in <anon>)
<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428]
<anon>:3         const X: i32 = $e;
...snip...

1 ответ

Решение

С https://doc.rust-lang.org/book/macros.html:

Это [то есть переименование] верно для привязок let и меток цикла, но не для элементов

https://doc.rust-lang.org/reference.html:

Предмет является компонентом ящика. Элементы организованы внутри ящика с помощью вложенного набора модулей. Каждый ящик имеет один "самый внешний" анонимный модуль; все остальные элементы внутри ящика имеют пути в дереве модулей ящика.

Элементы полностью определяются во время компиляции, обычно остаются фиксированными во время выполнения и могут находиться в постоянной памяти.

Есть несколько видов предметов:

  • внешние объявления
  • использовать объявления
  • модули
  • функции
  • определения типов
  • Структуры
  • перечисления
  • постоянные предметы
  • статические предметы
  • черты
  • реализации

Это имеет смысл: если вы вводите элемент в макрос, вы, вероятно, хотите фактически использовать его из других элементов / модулей / ящиков (и, следовательно, вне макроса), но не сможете, если не знаете его имени, поэтому компилятор не может переименовать его.

Другие вопросы по тегам