Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Атрибуты генерации кода

Следующие атрибуты используются для управления генерацией кода.

Атрибут inline

Атрибут inline предлагает, следует ли разместить копию кода функции в месте вызова вместо генерации вызова функции.

Example

#![allow(unused)]
fn main() {
#[inline]
pub fn example1() {}

#[inline(always)]
pub fn example2() {}

#[inline(never)]
pub fn example3() {}
}

Note

rustc автоматически встраивает функции, когда это кажется целесообразным. Используйте этот атрибут осторожно, так как неправильные решения о том, что встраивать, могут замедлить программы.

Синтаксис атрибута inline:

Syntax
InlineAttribute
      inline ( always )
    | inline ( never )
    | inline

InlineAttribute inline ( always ) inline ( never ) inline

Атрибут inline может применяться только к функциям с теламизамыканиям, async блокам, свободным функциям, ассоциированным функциям в неявной реализации или реализации трейта, и ассоциированным функциям в определении трейта, когда эти функции имеют определение по умолчанию.

Note

rustc игнорирует использование в других позициях, но выдает предупреждение. В будущем это может стать ошибкой.

Note

Хотя атрибут может применяться к замыканиям и async блокам, полезность этого ограничена, так как мы ещё не поддерживаем атрибуты на выражениях.

#![allow(unused)]
fn main() {
// Мы разрешаем атрибуты на операторах.
#[inline] || (); // OK
#[inline] async {}; // OK
}
#![allow(unused)]
fn main() {
// Мы ещё не разрешаем атрибуты на выражениях.
let f = #[inline] || (); // ERROR
}

Только первое использование inline на функции имеет эффект.

Note

rustc выдает предупреждение на любое использование после первого. В будущем это может стать ошибкой.

Атрибут inline поддерживает следующие режимы:

  • #[inline] предлагает выполнить встраивание (inline expansion).
  • #[inline(always)] предлагает, что встраивание должно выполняться всегда.
  • #[inline(never)] предлагает, что встраивание никогда не должно выполняться.

Note

В каждой форме атрибут является подсказкой. Компилятор может проигнорировать её.

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

Когда inline применяется к async функции или async замыканию, он применяется только к коду сгенерированной функции poll.

Note

Для более подробной информации см. Rust issue #129347.

Атрибут inline игнорируется, если функция экспортируется внешне с no_mangle или export_name.

Атрибут cold

Атрибут cold предполагает, что функция вряд ли будет вызвана, что может помочь компилятору генерировать лучший код.

Example

#![allow(unused)]
fn main() {
#[cold]
pub fn example() {}
}

Атрибут cold использует синтаксис MetaWord.

Атрибут cold может применяться только к функциям с теламизамыканиям, async блокам, свободным функциям, ассоциированным функциям в неявной реализации или реализации трейта, и ассоциированным функциям в определении трейта, когда эти функции имеют определение по умолчанию.

Note

rustc игнорирует использование в других позициях, но выдает предупреждение. В будущем это может стать ошибкой.

Note

Хотя атрибут может применяться к замыканиям и async блокам, полезность этого ограничена, так как мы ещё не поддерживаем атрибуты на выражениях.

Только первое использование cold на функции имеет эффект.

Note

rustc выдает предупреждение на любое использование после первого. В будущем это может стать ошибкой.

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

Атрибут naked

Атрибут naked предотвращает генерацию компилятором пролога и эпилога функции.

Тело функции должно состоять ровно из одного вызова макроса naked_asm!.

Для функции с атрибутом не генерируется пролог или эпилог. Ассемблерный код в блоке naked_asm! составляет полное тело naked-функции.

Атрибут naked является небезопасным атрибутом. Аннотирование функции с #[unsafe(naked)] накладывает обязательство безопасности, что тело должно учитывать соглашение о вызовах функции, соблюдать её сигнатуру и либо возвращаться, либо расходиться (т.е. не проходить через конец ассемблерного кода).

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

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

Note

Гарантирование того, когда ассемблерный код может или не может быть дублирован, важно для naked-функций, которые определяют символы.

Линт unused_variables подавляется внутри naked-функций.

Атрибут inline не может быть применён к naked-функции.

Атрибут track_caller не может быть применён к naked-функции.

Атрибуты тестирования не могут быть применены к naked-функции.

Атрибут no_builtins

Атрибут no_builtins отключает оптимизацию определённых шаблонов кода, связанных с вызовами библиотечных функций, которые предполагаются существующими.

Example

#![allow(unused)]
#![no_builtins]
fn main() {
}

Атрибут no_builtins использует синтаксис MetaWord.

Атрибут no_builtins может применяться только к корню крейта.

Только первое использование атрибута no_builtins имеет эффект.

Note

rustc выдает предупреждение на любое использование после первого.

Атрибут target_feature

Атрибут target_feature может применяться к функции для включения генерации кода этой функции для определённых функций архитектуры платформы. Он использует синтаксис MetaListNameValueStr с единственным ключом enable, значение которого — строка с разделёнными запятыми именами функций для включения.

#![allow(unused)]
fn main() {
#[cfg(target_feature = "avx2")]
#[target_feature(enable = "avx2")]
fn foo_avx2() {}
}

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

Замыкания, определённые внутри функции с аннотацией target_feature, наследуют атрибут от включающей функции.

Неопределённое поведение — вызывать функцию, которая скомпилирована с функцией, не поддерживаемой на текущей платформе, на которой выполняется код, за исключением случаев, когда платформа явно документирует, что это безопасно.

Следующие ограничения применяются, если иное не указано в правилах платформы ниже:

  • Безопасные функции #[target_feature] (и замыкания, которые наследуют атрибут) могут быть безопасно вызваны только внутри вызывающего, который включает все target_feature, которые включает вызываемый. Это ограничение не применяется в небезопасном контексте.
  • Безопасные функции #[target_feature] (и замыкания, которые наследуют атрибут) могут быть приведены к безопасным указателям на функции только в контекстах, которые включают все target_feature, которые включает приводимый. Это ограничение не применяется к небезопасным указателям на функции.

Неявно включённые функции включаются в это правило. Например, функция sse2 может вызывать функции, помеченные sse.

#![allow(unused)]
fn main() {
#[cfg(target_feature = "sse2")] {
#[target_feature(enable = "sse")]
fn foo_sse() {}

fn bar() {
    // Вызов `foo_sse` здесь небезопасен, так как мы должны сначала убедиться, что SSE
    // доступен, даже если `sse` включен по умолчанию на целевой
    // платформе или вручную включен как флаги компилятора.
    unsafe {
        foo_sse();
    }
}

#[target_feature(enable = "sse")]
fn bar_sse() {
    // Вызов `foo_sse` здесь безопасен.
    foo_sse();
    || foo_sse();
}

#[target_feature(enable = "sse2")]
fn bar_sse2() {
    // Вызов `foo_sse` здесь безопасен, потому что `sse2` подразумевает `sse`.
    foo_sse();
}
}
}

Функция с атрибутом #[target_feature] никогда не реализует семейство трейтов Fn, хотя замыкания, наследущие функции от включающей функции, делают это.

Атрибут #[target_feature] не разрешён в следующих местах:

  • функция main
  • функция panic_handler
  • безопасные методы трейтов
  • безопасные функции по умолчанию в трейтах

Функции, помеченные target_feature, не встраиваются в контекст, который не поддерживает данные функции. Атрибут #[inline(always)] не может использоваться с атрибутом target_feature.

Доступные функции

Ниже приведён список доступных имён функций.

x86 или x86_64

Выполнение кода с неподдерживаемыми функциями является неопределённым поведением на этой платформе. Следовательно, на этой платформе использование функций #[target_feature] следует вышеуказанным ограничениям.

ФункцияНеявно включаетОписание
adxADX — Многоточные расширения инструкций сложения с переносом
aessse2AES — Стандарт шифрования Advanced Encryption Standard
avxsse4.2AVX — Расширения Advanced Vector Extensions
avx2avxAVX2 — Расширения Advanced Vector Extensions 2
avx512bf16avx512bwAVX512-BF16 — Расширения Advanced Vector Extensions 512-bit - Bfloat16 Extensions
avx512bitalgavx512bwAVX512-BITALG — Расширения Advanced Vector Extensions 512-bit - Bit Algorithms
avx512bwavx512fAVX512-BW — Расширения Advanced Vector Extensions 512-bit - Byte and Word Instructions
avx512cdavx512fAVX512-CD — Расширения Advanced Vector Extensions 512-bit - Conflict Detection Instructions
avx512dqavx512fAVX512-DQ — Расширения Advanced Vector Extensions 512-bit - Doubleword and Quadword Instructions
avx512favx2, fma, f16cAVX512-F — Расширения Advanced Vector Extensions 512-bit - Foundation
avx512fp16avx512bwAVX512-FP16 — Расширения Advanced Vector Extensions 512-bit - Float16 Extensions
avx512ifmaavx512fAVX512-IFMA — Расширения Advanced Vector Extensions 512-bit - Integer Fused Multiply Add
avx512vbmiavx512bwAVX512-VBMI — Расширения Advanced Vector Extensions 512-bit - Vector Byte Manipulation Instructions
avx512vbmi2avx512bwAVX512-VBMI2 — Расширения Advanced Vector Extensions 512-bit - Vector Byte Manipulation Instructions 2
avx512vlavx512fAVX512-VL — Расширения Advanced Vector Extensions 512-bit - Vector Length Extensions
avx512vnniavx512fAVX512-VNNI — Расширения Advanced Vector Extensions 512-bit - Vector Neural Network Instructions
avx512vp2intersectavx512fAVX512-VP2INTERSECT — Расширения Advanced Vector Extensions 512-bit - Vector Pair Intersection to a Pair of Mask Registers
avx512vpopcntdqavx512fAVX512-VPOPCNTDQ — Расширения Advanced Vector Extensions 512-bit - Vector Population Count Instruction
avxifmaavx2AVX-IFMA — Расширения Advanced Vector Extensions - Integer Fused Multiply Add
avxneconvertavx2AVX-NE-CONVERT — Расширения Advanced Vector Extensions - No-Exception Floating-Point conversion Instructions
avxvnniavx2AVX-VNNI — Расширения Advanced Vector Extensions - Vector Neural Network Instructions
avxvnniint16avx2AVX-VNNI-INT16 — Расширения Advanced Vector Extensions - Vector Neural Network Instructions with 16-bit Integers
avxvnniint8avx2AVX-VNNI-INT8 — Расширения Advanced Vector Extensions - Vector Neural Network Instructions with 8-bit Integers
bmi1BMI1 — Наборы инструкций манипуляции битами
bmi2BMI2 — Наборы инструкций манипуляции битами 2
cmpxchg16bcmpxchg16b — Сравнивает и обменивает 16 байт (128 бит) данных атомарно
f16cavxF16C — Инструкции преобразования 16-битных чисел с плавающей запятой
fmaavxFMA3 — Трёхоперандное fused multiply-add
fxsrfxsave и fxrstor — Сохранить и восстановить состояние x87 FPU, MMX Technology и SSE
gfnisse2GFNI — Новые инструкции поля Галуа
klsse2KEYLOCKER — Инструкции Intel Key Locker
lzcntlzcnt — Подсчёт ведущих нулей
movbemovbe — Перемещение данных после обмена байтов
pclmulqdqsse2pclmulqdq — Упакованное умножение без переноса quadword
popcntpopcnt — Подсчёт битов, установленных в 1
rdrandrdrand — Чтение случайного числа
rdseedrdseed — Чтение случайного сида
shasse2SHA — Алгоритм безопасного хеширования
sha512avx2SHA512 — Алгоритм безопасного хеширования с дайджестом 512 бит
sm3avxSM3 — Алгоритм хеширования ShangMi 3
sm4avx2SM4 — Алгоритм шифрования ShangMi 4
sseSSE — Расширения Streaming SIMD
sse2sseSSE2 — Расширения Streaming SIMD 2
sse3sse2SSE3 — Расширения Streaming SIMD 3
sse4.1ssse3SSE4.1 — Расширения Streaming SIMD 4.1
sse4.2sse4.1SSE4.2 — Расширения Streaming SIMD 4.2
sse4asse3SSE4a — Расширения Streaming SIMD 4a
ssse3sse3SSSE3 — Дополнительные расширения Streaming SIMD 3
tbmTBM — Манипуляция trailing битами
vaesavx2, aesVAES — Векторные инструкции AES
vpclmulqdqavx, pclmulqdqVPCLMULQDQ — Векторное умножение без переноса Quadwords
wideklklKEYLOCKER_WIDE — Инструкции Intel Wide Keylocker
xsavexsave — Сохранение расширенных состояний процессора
xsavecxsavec — Сохранение расширенных состояний процессора с уплотнением
xsaveoptxsaveopt — Оптимизированное сохранение расширенных состояний процессора
xsavesxsaves — Сохранение расширенных состояний процессора supervisor

aarch64

На этой платформе использование функций #[target_feature] следует вышеуказанным ограничениям.

Дополнительная документация по этим функциям может быть найдена в ARM Architecture Reference Manual или elsewhere на developer.arm.com.

Note

Следующие пары функций должны быть помечены как включённые или отключённые вместе, если используются:

  • paca и pacg, которые LLVM в настоящее время реализует как одну функцию.
ФункцияНеявно включаетИмя функции
aesneonFEAT_AES & FEAT_PMULL — Расширения Advanced SIMD AES & PMULL instructions
bf16FEAT_BF16 — Инструкции BFloat16
btiFEAT_BTI — Идентификация цели ветвления
crcFEAT_CRC — Инструкции контрольной суммы CRC32
ditFEAT_DIT — Инструкции с независимым от данных временем
dotprodneonFEAT_DotProd — Расширения Advanced SIMD Int8 dot product instructions
dpbFEAT_DPB — Очистка кэша данных до точки сохранения
dpb2dpbFEAT_DPB2 — Очистка кэша данных до точки глубокого сохранения
f32mmsveFEAT_F32MM — Инструкция умножения матриц с плавающей запятой одинарной точности SVE
f64mmsveFEAT_F64MM — Инструкция умножения матриц с плавающей запятой двойной точности SVE
fcmaneonFEAT_FCMA — Поддержка комплексных чисел с плавающей запятой
fhmfp16FEAT_FHM — Инструкции Half-precision FP FMLAL
flagmFEAT_FLAGM — Манипуляция условными флагами
fp16neonFEAT_FP16 — Обработка данных с плавающей запятой половинной точности
frinttsFEAT_FRINTTS — Вспомогательные инструкции преобразования плавающей запятой в int
i8mmFEAT_I8MM — Умножение матриц Int8
jsconvneonFEAT_JSCVT — Инструкция преобразования JavaScript
lorFEAT_LOR — Расширение ограниченных регионов упорядочения
lseFEAT_LSE — Расширения больших систем
mteFEAT_MTE & FEAT_MTE2 — Расширение тегирования памяти
neonFEAT_AdvSimd & FEAT_FP — Расширения Floating Point и Advanced SIMD
pacaFEAT_PAUTH — Аутентификация указателей (аутентификация адреса)
pacgFEAT_PAUTH — Аутентификация указателей (общая аутентификация)
panFEAT_PAN — Расширение Privileged Access-Never
pmuv3FEAT_PMUv3 — Расширения мониторов производительности (v3)
randFEAT_RNG — Генератор случайных чисел
rasFEAT_RAS & FEAT_RASv1p1 — Расширение надёжности, доступности и обслуживаемости
rcpcFEAT_LRCPC — Release consistent Processor Consistent
rcpc2rcpcFEAT_LRCPC2 — RcPc с непосредственными смещениями
rdmneonFEAT_RDM — Округление двойного умножения с накоплением
sbFEAT_SB — Барьер спекуляции
sha2neonFEAT_SHA1 & FEAT_SHA256 — Расширения Advanced SIMD SHA instructions
sha3sha2FEAT_SHA512 & FEAT_SHA3 — Расширения Advanced SIMD SHA instructions
sm4neonFEAT_SM3 & FEAT_SM4 — Расширения Advanced SIMD SM3/4 instructions
speFEAT_SPE — Расширение статистического профилирования
ssbsFEAT_SSBS & FEAT_SSBS2 — Speculative Store Bypass Safe
sveneonFEAT_SVE — Масштабируемое векторное расширение
sve2sveFEAT_SVE2 — Масштабируемое векторное расширение 2
sve2-aessve2, aesFEAT_SVE_AES & FEAT_SVE_PMULL128 — Инструкции SVE AES
sve2-bitpermsve2FEAT_SVE2_BitPerm — SVE Bit Permute
sve2-sha3sve2, sha3FEAT_SVE2_SHA3 — Инструкции SVE SHA3
sve2-sm4sve2, sm4FEAT_SVE2_SM4 — Инструкции SVE SM4
tmeFEAT_TME — Расширение транзакционной памяти
vhFEAT_VHE — Расширения виртуализации хоста

loongarch

На этой платформе использование функций #[target_feature] следует вышеуказанным ограничениям.

ФункцияНеявно включаетОписание
fF — Инструкции чисел с плавающей запятой одинарной точности
dfD — Инструкции чисел с плавающей запятой двойной точности
frecipeFRECIPE — Инструкции аппроксимации обратной величины
lasxlsxLASX — 256-битные векторные инструкции
lbtLBT — Инструкции бинарной трансляции
lsxdLSX — 128-битные векторные инструкции
lvzLVZ — Инструкции виртуализации

riscv32 или riscv64

На этой платформе использование функций #[target_feature] следует вышеуказанным ограничениям.

Дополнительная документация по этим функциям может быть найдена в их соответствующих спецификациях. Многие спецификации описаны в RISC-V ISA Manual, version 20250508, или в другом руководстве, размещённом на RISC-V GitHub Account.

ФункцияНеявно включаетОписание
aA — Атомарные инструкции
cC — Сжатые инструкции
mM — Инструкции целочисленного умножения и деления
zbaZba — Инструкции генерации адресов
zbbZbb — Базовая манипуляция битами
zbczbkcZbc — Умножение без переноса
zbkbZbkb — Инструкции манипуляции битами для криптографии
zbkcZbkc — Умножение без переноса для криптографии
zbkxZbkx — Перестановки crossbar
zbsZbs — Инструкции работы с одним битом
zkzkn, zkr, zks, zkt, zbkb, zbkc, zkbxZk — Скалярная криптография
zknzknd, zkne, zknh, zbkb, zbkc, zkbxZkn — Расширение набора алгоритмов NIST
zkndZknd — Набор NIST: Дешифрование AES
zkneZkne — Набор NIST: Шифрование AES
zknhZknh — Набор NIST: Инструкции хеш-функций
zkrZkr — Расширение источника энтропии
zkszksed, zksh, zbkb, zbkc, zkbxZks — Набор алгоритмов ShangMi
zksedZksed — Набор ShangMi: Инструкции блочного шифра SM4
zkshZksh — Набор ShangMi: Инструкции хеш-функции SM3
zktZkt — Подмножество с независимой от данных задержкой выполнения

wasm32 или wasm64

Безопасные функции #[target_feature] могут всегда использоваться в безопасных контекстах на платформах Wasm. Невозможно вызвать неопределённое поведение через атрибут #[target_feature], потому что попытка использовать инструкции, не поддерживаемые движком Wasm, завершится ошибкой во время загрузки без риска быть интерпретированной способом, отличным от ожидаемого компилятором.

Дополнительная информация

См. опцию условной компиляции [target_feature] для выборочного включения или отключения компиляции кода на основе настроек времени компиляции. Обратите внимание, что эта опция не зависит от атрибута target_feature и управляется только функциями, включёнными для всего крейта.

См. макросы is_x86_feature_detected или is_aarch64_feature_detected в стандартной библиотеке для обнаружения функций во время выполнения на этих платформах.

Note

rustc имеет набор функций, включённых по умолчанию для каждой цели и CPU. CPU может быть выбран с помощью флага -C target-cpu. Отдельные функции могут быть включены или отключены для всего крейта с помощью флага -C target-feature.

Атрибут track_caller

Атрибут track_caller может применяться к любой функции с ABI "Rust" за исключением точки входа fn main.

При применении к функциям и методам в объявлениях трейтов атрибут применяется ко всем реализациям. Если трейт предоставляет реализацию по умолчанию с атрибутом, то атрибут также применяется к переопределяющим реализациям.

При применении к функции в блоке extern атрибут также должен быть применён к любым связанным реализациям, иначе результат — неопределённое поведение. При применении к функции, которая становится доступной для блока extern, объявление в блоке extern также должно иметь атрибут, иначе результат — неопределённое поведение.

Поведение

Применение атрибута к функции f позволяет коду внутри f получить подсказку о Location “самого верхнего” отслеживаемого вызова, который привёл к вызову f. В момент наблюдения реализация ведёт себя так, как если бы она поднималась по стеку от фрейма f, чтобы найти ближайший фрейм без атрибута функции outer, и возвращает Location отслеживаемого вызова в outer.

#![allow(unused)]
fn main() {
#[track_caller]
fn f() {
    println!("{}", std::panic::Location::caller());
}
}

Note

core предоставляет core::panic::Location::caller для наблюдения за местоположениями вызывающих. Он оборачивает внутреннюю функцию core::intrinsics::caller_location, реализованную rustc.

Note

Поскольку результирующий Location является подсказкой, реализация может остановить подъём по стеку раньше. См. Ограничения для важных предостережений.

Примеры

Когда f вызывается напрямую calls_f, код в f наблюдает место вызова внутри calls_f:

#![allow(unused)]
fn main() {
#[track_caller]
fn f() {
    println!("{}", std::panic::Location::caller());
}
fn calls_f() {
    f(); // <-- f() печатает это местоположение
}
}

Когда f вызывается другой атрибутированной функцией g, которая в свою очередь вызывается calls_g, код в обоих f и g наблюдает место вызова g внутри calls_g:

#![allow(unused)]
fn main() {
#[track_caller]
fn f() {
    println!("{}", std::panic::Location::caller());
}
#[track_caller]
fn g() {
    println!("{}", std::panic::Location::caller());
    f();
}

fn calls_g() {
    g(); // <-- g() печатает это местоположение дважды, один раз сама и один раз из f()
}
}

Когда g вызывается другой атрибутированной функцией h, которая в свою очередь вызывается calls_h, весь код в f, g и h наблюдает место вызова h внутри calls_h:

#![allow(unused)]
fn main() {
#[track_caller]
fn f() {
    println!("{}", std::panic::Location::caller());
}
#[track_caller]
fn g() {
    println!("{}", std::panic::Location::caller());
    f();
}
#[track_caller]
fn h() {
    println!("{}", std::panic::Location::caller());
    g();
}

fn calls_h() {
    h(); // <-- печатает это местоположение трижды, один раз сама, один раз из g(), один раз из f()
}
}

И так далее.

Ограничения

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

В частности, приведение функции с #[track_caller] к указателю на функцию создаёт обёртку (shim), которая для наблюдателей появляется так, как если бы она была вызвана в месте определения атрибутированной функции, теряя фактическую информацию о вызывающем при виртуальных вызовах. Распространённым примером этого приведения является создание объекта трейта, методы которого атрибутированы.

Note

Упомянутая выше обёртка для указателей на функции необходима, потому что rustc реализует track_caller в контексте кодогенерации, добавляя неявный параметр к ABI функции, но это было бы небезопасно для косвенного вызова, потому что параметр не является частью типа функции, и данный тип указателя на функцию может ссылаться или не ссылаться на функцию с атрибутом. Создание обёртки скрывает неявный параметр от вызывающих указатель на функцию, сохраняя безопасность.

Атрибут instruction_set

Атрибут instruction_set указывает набор инструкций, который функция будет использовать во время генерации кода. Это позволяет смешивать более одного набора инструкций в одной программе.

Example

#[instruction_set(arm::a32)]
fn arm_code() {}

#[instruction_set(arm::t32)]
fn thumb_code() {}

Атрибут instruction_set использует синтаксис MetaListPaths для указания единственного пути, состоящего из имени семейства архитектуры и имени набора инструкций.

Атрибут instruction_set может применяться только к функциям с теламизамыканиям, async блокам, свободным функциям, ассоциированным функциям в неявной реализации или реализации трейта, и ассоциированным функциям в определении трейта, когда эти функции имеют определение по умолчанию.

Note

rustc игнорирует использование в других позициях, но выдает предупреждение. В будущем это может стать ошибкой.

Note

Хотя атрибут может применяться к замыканиям и async блокам, полезность этого ограничена, так как мы ещё не поддерживаем атрибуты на выражениях.

Атрибут instruction_set может использоваться только один раз на функции.

Атрибут instruction_set может использоваться только с целью, которая поддерживает данное значение.

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

instruction_set на ARM

При нацеливании на архитектуры ARMv4T и ARMv5te поддерживаемые значения для instruction_set:

  • arm::a32 — Генерировать функцию как код A32 “ARM”.
  • arm::t32 — Генерировать функцию как код T32 “Thumb”.

Если адрес функции берётся как указатель на функцию, младший бит адреса будет зависеть от выбранного набора инструкций:

  • Для arm::a32 (“ARM”) он будет 0.
  • Для arm::t32 (“Thumb”) он будет 1.