Так вот немного больше информации о том, что происходит в компиляторе. Для начала, как уже упоминалось, фактические операции, выполняемые с помощью логических элементов, полностью обрабатываются LLVM и непосредственно передаются в соответствующие инструкции ЦП. Хотя есть некоторые случаи, когда код просто волшебным образом появляется из-за начальной загрузки, это не один из них. Компилятор специально написан для обработки этих типов и испускает правильные инструкции LLVM.
Для самых ранних частей компиляции (например, при макрорасширении) тип bool
не является особым. Это всего лишь некоторый путь с идентификатором bool
. В конце концов around here он преобразуется в примитивный тип. Фактическое определение типа: here.
Итак, давайте посмотрим, как работает оператор !
. Как я упоминал ранее, код в libcore, который делает impl Not for bool
, никогда не используется. Код в форме !expr
преобразуется в <T as Not>::not(expr)
here.Однако вы заметите, что он проверяет, действительно ли это конкретное выражение является вызовом метода или нет, и просто оставляет его как !expr
, если он не предназначен для вызова метода. Как это знать? Вызов в MIR - это просто поиск в кеше. Кэш заселен во время проверки проверки типа. Here - это место, где происходит вставка кеша - в основном проверка того, реализуется ли признак Not
для данного типа в любое время, когда он видит !
. И вы заметите, что this line специально исключает логические и интегральные типы, которые в конечном итоге сводятся к инструкциям LLVM напрямую.
Это грубая картина того, как она определена. Вы найдете аналогичный код в тех же файлах для других примитивов. Теоретически может быть какая-то строка где-то, которая была enum bool { true, false }
, но в конечном итоге этот же код все равно должен был бы переопределить его и испустить соответствующие LLVM-функции, и целые числа не могли быть представлены таким образом.
Что именно вы ищете? В какой-то момент «логическое» - это всего лишь один бит на процессоре (или полный байт по соображениям производительности). До этого это 'i1' (' i8') в биткоде LLVM, и до этого это, вероятно, 'enum' в некотором Rust IR. Двигаясь ниже, вы попадаете в логические ворота, транзисторы и электроны. Какая из них является «фактической реализацией»? – Shepmaster
Я ищу место, где язык Rust (не бит Lode LLVM или CPU) начал распознавать, например. оператор '==' (т. е. логическая логика). Я не слишком разбираюсь в написании компиляторов, поэтому моя формулировка может быть не идеальной, но я думаю, что, должно быть, был этап, когда примитивы были сначала «встроены» в компилятор rustc, чтобы он смог скомпилировать их в LLVM. – ljedrz