rust/compiler/rustc_feature/src/builtin_attrs.rs

1203 lines
48 KiB
Rust
Raw Normal View History

2019-08-22 16:32:31 +00:00
//! Built-in attributes and `cfg` flag gating.
use std::sync::LazyLock;
2021-09-05 23:30:37 +00:00
use AttributeDuplicates::*;
2019-08-22 16:32:31 +00:00
use AttributeGate::*;
use AttributeType::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_span::{Symbol, sym};
2019-08-22 16:32:31 +00:00
2019-11-30 01:34:18 +00:00
use crate::{Features, Stability};
2019-08-22 16:37:28 +00:00
type GateFn = fn(&Features) -> bool;
2019-11-30 00:57:53 +00:00
pub type GatedCfg = (Symbol, Symbol, GateFn);
2019-08-22 16:37:28 +00:00
/// `cfg(...)`'s that are feature gated.
2019-11-30 00:57:53 +00:00
const GATED_CFGS: &[GatedCfg] = &[
2019-08-22 16:32:31 +00:00
// (name in cfg, feature, function to check if the feature is enabled)
(sym::overflow_checks, sym::cfg_overflow_checks, Features::cfg_overflow_checks),
(sym::ub_checks, sym::cfg_ub_checks, Features::cfg_ub_checks),
(sym::contract_checks, sym::cfg_contract_checks, Features::cfg_contract_checks),
(sym::target_thread_local, sym::cfg_target_thread_local, Features::cfg_target_thread_local),
(
sym::target_has_atomic_equal_alignment,
sym::cfg_target_has_atomic_equal_alignment,
Features::cfg_target_has_atomic_equal_alignment,
),
(
sym::target_has_atomic_load_store,
sym::cfg_target_has_atomic,
Features::cfg_target_has_atomic,
),
(sym::sanitize, sym::cfg_sanitize, Features::cfg_sanitize),
(sym::version, sym::cfg_version, Features::cfg_version),
(sym::relocation_model, sym::cfg_relocation_model, Features::cfg_relocation_model),
(sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi),
(sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi),
// this is consistent with naming of the compiler flag it's for
(sym::fmt_debug, sym::fmt_debug, Features::fmt_debug),
(sym::emscripten_wasm_eh, sym::cfg_emscripten_wasm_eh, Features::cfg_emscripten_wasm_eh),
2019-08-22 16:32:31 +00:00
];
2019-11-30 00:57:53 +00:00
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg> {
GATED_CFGS.iter().find(|(cfg_sym, ..)| pred(*cfg_sym))
2019-08-22 16:32:31 +00:00
}
// If you change this, please modify `src/doc/unstable-book` as well. You must
// move that documentation into the relevant place in the other docs, and
// remove the chapter on the flag.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum AttributeType {
/// Normal, builtin attribute that is consumed
/// by the compiler before the unused_attribute check
Normal,
/// Builtin attribute that is only allowed at the crate level
CrateLevel,
}
2024-04-21 04:54:50 +00:00
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum AttributeSafety {
/// Normal attribute that does not need `#[unsafe(...)]`
Normal,
/// Unsafe attribute that requires safety obligations
/// to be discharged
Unsafe,
}
#[derive(Clone, Copy)]
2019-08-22 16:32:31 +00:00
pub enum AttributeGate {
/// Is gated by a given feature gate, reason
/// and function to check if enabled
Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
/// Ungated attribute, can be used on all release channels
Ungated,
}
// fn() is not Debug
impl std::fmt::Debug for AttributeGate {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Self::Gated(ref stab, name, expl, _) => {
write!(fmt, "Gated({stab:?}, {name}, {expl})")
}
Self::Ungated => write!(fmt, "Ungated"),
2019-08-22 16:32:31 +00:00
}
}
}
impl AttributeGate {
fn is_deprecated(&self) -> bool {
2020-10-27 01:02:48 +00:00
matches!(*self, Self::Gated(Stability::Deprecated(_, _), ..))
2019-08-22 16:32:31 +00:00
}
}
/// A template that the attribute input must match.
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
2019-12-30 18:38:43 +00:00
#[derive(Clone, Copy, Default)]
pub struct AttributeTemplate {
2021-09-05 23:30:37 +00:00
/// If `true`, the attribute is allowed to be a bare word like `#[test]`.
pub word: bool,
2021-09-05 23:30:37 +00:00
/// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`.
pub list: Option<&'static str>,
/// If non-empty, the attribute is allowed to take a list containing exactly
/// one of the listed words, like `#[coverage(off)]`.
pub one_of: &'static [Symbol],
2021-09-05 23:30:37 +00:00
/// If `Some`, the attribute is allowed to be a name/value pair where the
/// value is a string, like `#[must_use = "reason"]`.
pub name_value_str: Option<&'static str>,
}
2021-09-05 23:30:37 +00:00
/// How to handle multiple duplicate attributes on the same item.
#[derive(Clone, Copy, Default)]
pub enum AttributeDuplicates {
/// Duplicates of this attribute are allowed.
///
/// This should only be used with attributes where duplicates have semantic
/// meaning, or some kind of "additive" behavior. For example, `#[warn(..)]`
/// can be specified multiple times, and it combines all the entries. Or use
/// this if there is validation done elsewhere.
#[default]
DuplicatesOk,
/// Duplicates after the first attribute will be an unused_attribute warning.
///
/// This is usually used for "word" attributes, where they are used as a
/// boolean marker, like `#[used]`. It is not necessarily wrong that there
/// are duplicates, but the others should probably be removed.
WarnFollowing,
/// Same as `WarnFollowing`, but only issues warnings for word-style attributes.
///
/// This is only for special cases, for example multiple `#[macro_use]` can
/// be warned, but multiple `#[macro_use(...)]` should not because the list
/// form has different meaning from the word form.
WarnFollowingWordOnly,
/// Duplicates after the first attribute will be an error.
///
/// This should be used where duplicates would be ignored, but carry extra
/// meaning that could cause confusion. For example, `#[stable(since="1.0")]
/// #[stable(since="2.0")]`, which version should be used for `stable`?
ErrorFollowing,
/// Duplicates preceding the last instance of the attribute will be an error.
///
/// This is the same as `ErrorFollowing`, except the last attribute is the
/// one that is "used". This is typically used in cases like codegen
/// attributes which usually only honor the last attribute.
ErrorPreceding,
/// Duplicates after the first attribute will be an unused_attribute warning
/// with a note that this will be an error in the future.
///
/// This should be used for attributes that should be `ErrorFollowing`, but
/// because older versions of rustc silently accepted (and ignored) the
/// attributes, this is used to transition.
FutureWarnFollowing,
/// Duplicates preceding the last instance of the attribute will be a
/// warning, with a note that this will be an error in the future.
///
/// This is the same as `FutureWarnFollowing`, except the last attribute is
/// the one that is "used". Ideally these can eventually migrate to
/// `ErrorPreceding`.
FutureWarnPreceding,
}
2019-08-22 16:32:31 +00:00
/// A convenience macro for constructing attribute templates.
/// E.g., `template!(Word, List: "description")` means that the attribute
/// supports forms `#[attr]` and `#[attr(description)]`.
macro_rules! template {
(Word) => { template!(@ true, None, &[], None) };
(List: $descr: expr) => { template!(@ false, Some($descr), &[], None) };
(OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) };
(NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) };
(Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) };
(Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) };
2019-08-22 16:32:31 +00:00
(List: $descr1: expr, NameValueStr: $descr2: expr) => {
template!(@ false, Some($descr1), &[], Some($descr2))
2019-08-22 16:32:31 +00:00
};
(Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
template!(@ true, Some($descr1), &[], Some($descr2))
2019-08-22 16:32:31 +00:00
};
(@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate {
word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str
2019-08-22 16:32:31 +00:00
} };
}
macro_rules! ungated {
2024-04-25 16:12:02 +00:00
(unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
2021-09-05 23:30:37 +00:00
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
2021-09-05 23:30:37 +00:00
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Unsafe,
2024-04-21 04:54:50 +00:00
template: $tpl,
gate: Ungated,
duplicates: $duplicates,
}
};
2024-04-25 16:12:02 +00:00
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
2024-04-21 04:54:50 +00:00
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Normal,
2021-09-05 23:30:37 +00:00
template: $tpl,
gate: Ungated,
duplicates: $duplicates,
}
};
}
macro_rules! gated {
2024-04-25 16:12:02 +00:00
(unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => {
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Unsafe,
template: $tpl,
2021-09-05 23:30:37 +00:00
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$gate, $msg, Features::$gate),
}
};
2024-04-25 16:12:02 +00:00
(unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => {
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Unsafe,
2024-04-21 04:54:50 +00:00
template: $tpl,
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$attr, $msg, Features::$attr),
2024-04-21 04:54:50 +00:00
}
};
2024-04-25 16:12:02 +00:00
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => {
2024-04-21 04:54:50 +00:00
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Normal,
2024-04-21 04:54:50 +00:00
template: $tpl,
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$gate, $msg, Features::$gate),
2024-04-21 04:54:50 +00:00
}
};
2024-04-25 16:12:02 +00:00
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => {
2024-04-21 04:54:50 +00:00
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-25 16:12:02 +00:00
safety: AttributeSafety::Normal,
template: $tpl,
2021-09-05 23:30:37 +00:00
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$attr, $msg, Features::$attr),
}
};
}
macro_rules! rustc_attr {
(TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => {
rustc_attr!(
$attr,
$typ,
$tpl,
2021-09-05 23:30:37 +00:00
$duplicate,
$encode_cross_crate,
concat!(
"the `#[",
stringify!($attr),
"]` attribute is just used for rustc unit tests \
and will never be stable",
),
)
};
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => {
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
2024-04-21 04:54:50 +00:00
safety: AttributeSafety::Normal,
template: $tpl,
2021-09-05 23:30:37 +00:00
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, Features::rustc_attrs),
}
};
}
2019-08-22 21:30:59 +00:00
macro_rules! experimental {
($attr:ident) => {
concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature")
};
2019-08-22 21:30:59 +00:00
}
const IMPL_DETAIL: &str = "internal implementation detail";
const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
2019-08-22 21:30:59 +00:00
#[derive(PartialEq)]
pub enum EncodeCrossCrate {
Yes,
No,
}
pub struct BuiltinAttribute {
pub name: Symbol,
/// Whether this attribute is encode cross crate.
2022-04-01 13:04:47 +00:00
///
/// If so, it is encoded in the crate metadata.
/// Otherwise, it can only be used in the local crate.
pub encode_cross_crate: EncodeCrossCrate,
pub type_: AttributeType,
2024-04-21 04:54:50 +00:00
pub safety: AttributeSafety,
pub template: AttributeTemplate,
2021-09-05 23:30:37 +00:00
pub duplicates: AttributeDuplicates,
pub gate: AttributeGate,
}
2019-08-22 16:32:31 +00:00
/// Attributes that have a special meaning to rustc or rustdoc.
#[rustfmt::skip]
pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Stable attributes:
// ==========================================================================
2020-03-06 11:13:55 +00:00
// Conditional compilation:
ungated!(cfg, Normal, template!(List: "predicate"), DuplicatesOk, EncodeCrossCrate::Yes),
ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), DuplicatesOk, EncodeCrossCrate::Yes),
2019-08-22 16:32:31 +00:00
2019-08-22 21:30:59 +00:00
// Testing:
ungated!(
ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
EncodeCrossCrate::No,
),
2019-08-22 21:30:59 +00:00
ungated!(
should_panic, Normal,
template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing,
EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
),
// FIXME(Centril): This can be used on stable but shouldn't.
ungated!(
reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing,
EncodeCrossCrate::No,
),
2019-08-22 21:30:59 +00:00
// Macros:
ungated!(automatically_derived, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
ungated!(
macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly,
EncodeCrossCrate::No,
),
ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`.
ungated!(
macro_export, Normal, template!(Word, List: "local_inner_macros"),
WarnFollowing, EncodeCrossCrate::Yes
),
ungated!(proc_macro, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No),
2019-08-22 21:30:59 +00:00
ungated!(
proc_macro_derive, Normal, template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
ErrorFollowing, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
),
ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No),
2019-08-22 21:30:59 +00:00
// Lints:
2021-09-05 23:30:37 +00:00
ungated!(
2022-09-13 13:23:54 +00:00
warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
DuplicatesOk, EncodeCrossCrate::No,
2021-09-05 23:30:37 +00:00
),
ungated!(
2022-09-13 13:23:54 +00:00
allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
DuplicatesOk, EncodeCrossCrate::No,
2021-09-05 23:30:37 +00:00
),
ungated!(
expect, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
DuplicatesOk, EncodeCrossCrate::No,
),
2021-09-05 23:30:37 +00:00
ungated!(
2022-09-13 13:23:54 +00:00
forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
DuplicatesOk, EncodeCrossCrate::No
2021-09-05 23:30:37 +00:00
),
ungated!(
2022-09-13 13:23:54 +00:00
deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
DuplicatesOk, EncodeCrossCrate::No
),
ungated!(
must_use, Normal, template!(Word, NameValueStr: "reason"),
FutureWarnFollowing, EncodeCrossCrate::Yes
2021-09-05 23:30:37 +00:00
),
2021-09-05 02:36:51 +00:00
gated!(
2021-09-05 23:30:37 +00:00
must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
EncodeCrossCrate::Yes, experimental!(must_not_suspend)
2021-09-05 02:36:51 +00:00
),
2019-08-22 21:30:59 +00:00
ungated!(
deprecated, Normal,
template!(
Word,
List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
NameValueStr: "reason"
),
ErrorFollowing, EncodeCrossCrate::Yes
2019-08-22 21:30:59 +00:00
),
2019-08-22 21:30:59 +00:00
// Crate properties:
ungated!(
crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing,
EncodeCrossCrate::No,
),
ungated!(
crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk,
EncodeCrossCrate::No,
),
2019-08-22 21:30:59 +00:00
// ABI, linking, symbols, and FFI
ungated!(
link, Normal,
2022-07-12 20:52:35 +00:00
template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#),
2021-09-05 23:30:37 +00:00
DuplicatesOk,
EncodeCrossCrate::No,
),
ungated!(
link_name, Normal, template!(NameValueStr: "name"),
FutureWarnPreceding, EncodeCrossCrate::Yes
2019-08-22 21:30:59 +00:00
),
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
2024-04-21 04:54:50 +00:00
ungated!(unsafe export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No),
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes),
2019-08-22 21:30:59 +00:00
// Limits:
ungated!(
recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
EncodeCrossCrate::No
),
ungated!(
type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
EncodeCrossCrate::No
),
gated!(
2021-09-05 23:30:37 +00:00
move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
EncodeCrossCrate::No, large_assignments, experimental!(move_size_limit)
),
2019-08-22 21:30:59 +00:00
// Entry point:
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
2019-08-22 21:30:59 +00:00
// Modules, prelude, and resolution:
ungated!(path, Normal, template!(NameValueStr: "file"), FutureWarnFollowing, EncodeCrossCrate::No),
ungated!(no_std, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_implicit_prelude, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(non_exhaustive, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
2019-08-22 21:30:59 +00:00
// Runtime
2021-09-05 23:30:37 +00:00
ungated!(
windows_subsystem, CrateLevel,
template!(NameValueStr: "windows|console"), FutureWarnFollowing,
EncodeCrossCrate::No
2021-09-05 23:30:37 +00:00
),
ungated!(panic_handler, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), // RFC 2070
2019-08-22 21:30:59 +00:00
// Code generation:
ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing, EncodeCrossCrate::No),
ungated!(cold, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_builtins, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
2022-09-13 13:23:54 +00:00
ungated!(
target_feature, Normal, template!(List: r#"enable = "name""#),
DuplicatesOk, EncodeCrossCrate::No,
2022-09-13 13:23:54 +00:00
),
ungated!(track_caller, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
ungated!(instruction_set, Normal, template!(List: "set"), ErrorPreceding, EncodeCrossCrate::No),
gated!(
no_sanitize, Normal,
template!(List: "address, kcfi, memory, thread"), DuplicatesOk,
EncodeCrossCrate::No, experimental!(no_sanitize)
),
gated!(
coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
ErrorPreceding, EncodeCrossCrate::No,
coverage_attribute, experimental!(coverage)
),
2019-08-22 21:30:59 +00:00
2021-09-05 23:30:37 +00:00
ungated!(
doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk,
EncodeCrossCrate::Yes
2021-09-05 23:30:37 +00:00
),
2019-08-22 21:30:59 +00:00
// Debugging
ungated!(
2023-03-02 18:41:08 +00:00
debugger_visualizer, Normal,
template!(List: r#"natvis_file = "...", gdb_script_file = "...""#),
DuplicatesOk, EncodeCrossCrate::No
),
ungated!(collapse_debuginfo, Normal, template!(List: "no|external|yes"), ErrorFollowing,
EncodeCrossCrate::Yes
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Unstable attributes:
// ==========================================================================
// Linking:
gated!(
naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
naked_functions, experimental!(naked)
),
2019-09-18 14:40:08 +00:00
2019-08-22 21:30:59 +00:00
// Testing:
gated!(
test_runner, CrateLevel, template!(List: "path"), ErrorFollowing,
EncodeCrossCrate::Yes, custom_test_frameworks,
2019-08-22 21:30:59 +00:00
"custom test frameworks are an unstable feature",
),
2019-08-22 16:32:31 +00:00
// RFC #1268
gated!(
marker, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
marker_trait_attr, experimental!(marker)
2021-09-05 23:30:37 +00:00
),
gated!(
thread_local, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
"`#[thread_local]` is an experimental feature, and does not currently handle destructors",
),
gated!(
no_core, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(no_core)
),
2019-08-22 21:30:59 +00:00
// RFC 2412
gated!(
2024-12-09 19:00:43 +00:00
optimize, Normal, template!(List: "none|size|speed"), ErrorPreceding,
EncodeCrossCrate::No, optimize_attribute, experimental!(optimize)
),
gated!(
unsafe ffi_pure, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(ffi_pure)
),
gated!(
unsafe ffi_const, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(ffi_const)
),
gated!(
2021-09-05 23:30:37 +00:00
register_tool, CrateLevel, template!(List: "tool1, tool2, ..."), DuplicatesOk,
EncodeCrossCrate::No, experimental!(register_tool),
),
2019-08-22 21:30:59 +00:00
2021-07-04 15:50:34 +00:00
// RFC 2632
gated!(
2024-07-01 08:36:28 +00:00
const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, const_trait_impl,
2022-08-28 04:53:36 +00:00
"`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \
`impls` and all default bodies as `const`, which may be removed or renamed in the \
future."
2021-07-04 15:50:34 +00:00
),
// lang-team MCP 147
gated!(
deprecated_safe, Normal, template!(List: r#"since = "version", note = "...""#), ErrorFollowing,
EncodeCrossCrate::Yes, experimental!(deprecated_safe),
),
// `#[cfi_encoding = ""]`
gated!(
cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding,
EncodeCrossCrate::Yes, experimental!(cfi_encoding)
),
// `#[coroutine]` attribute to be applied to closures to make them coroutines instead
gated!(
coroutine, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No, coroutines, experimental!(coroutine)
),
// RFC 3543
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
gated!(
patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding,
EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
),
// Probably temporary component of min_generic_const_args.
// `#[type_const] const ASSOC: usize;`
gated!(
type_const, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const),
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
// ==========================================================================
2022-09-13 13:23:54 +00:00
ungated!(
feature, CrateLevel,
template!(List: "name1, name2, ..."), DuplicatesOk, EncodeCrossCrate::No,
2022-09-13 13:23:54 +00:00
),
2021-09-05 23:30:37 +00:00
// DuplicatesOk since it has its own validation
ungated!(
2022-09-13 13:23:54 +00:00
stable, Normal,
template!(List: r#"feature = "name", since = "version""#), DuplicatesOk, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
),
ungated!(
unstable, Normal,
2021-09-05 23:30:37 +00:00
template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk,
EncodeCrossCrate::Yes
),
ungated!(
rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
DuplicatesOk, EncodeCrossCrate::Yes
),
2022-09-13 13:23:54 +00:00
ungated!(
rustc_const_stable, Normal,
template!(List: r#"feature = "name""#), DuplicatesOk, EncodeCrossCrate::No,
2022-09-13 13:23:54 +00:00
),
ungated!(
rustc_default_body_unstable, Normal,
template!(List: r#"feature = "name", reason = "...", issue = "N""#),
DuplicatesOk, EncodeCrossCrate::No
),
gated!(
allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
DuplicatesOk, EncodeCrossCrate::Yes,
2019-11-30 01:03:32 +00:00
"allow_internal_unstable side-steps feature gating and stability checks",
),
gated!(
2021-09-05 23:30:37 +00:00
allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
),
rustc_attr!(
rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
WarnFollowing, EncodeCrossCrate::No,
"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
through unstable paths"
),
rustc_attr!(
rustc_deprecated_safe_2024, Normal, template!(List: r#"audit_that = "...""#),
ErrorFollowing, EncodeCrossCrate::Yes,
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
),
rustc_attr!(
rustc_pub_transparent, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes,
"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes: Type system related:
// ==========================================================================
gated!(fundamental, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)),
gated!(
may_dangle, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, dropck_eyepatch,
2019-08-22 21:30:59 +00:00
"`may_dangle` has unstable semantics and may be removed in the future",
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
rustc_never_type_options,
Normal,
template!(List: r#"/*opt*/ fallback = "unit|niko|never|no""#),
ErrorFollowing,
EncodeCrossCrate::No,
"`rustc_never_type_options` is used to experiment with never type fallback and work on \
never type stabilization, and will never be stable"
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes: Runtime related:
// ==========================================================================
rustc_attr!(
rustc_allocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
rustc_attr!(
rustc_nounwind, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
rustc_attr!(
rustc_reallocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
rustc_attr!(
rustc_deallocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
rustc_attr!(
rustc_allocator_zeroed, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL
),
gated!(
default_lib_allocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator),
),
gated!(
needs_allocator, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
),
gated!(
panic_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(panic_runtime)
),
gated!(
needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(needs_panic_runtime)
2021-09-05 23:30:37 +00:00
),
gated!(
compiler_builtins, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No,
"the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
which contains compiler-rt intrinsics and will never be stable",
),
gated!(
profiler_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No,
"the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
which contains the profiler runtime and will never be stable",
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Linkage:
// ==========================================================================
gated!(
linkage, Normal, template!(NameValueStr: "external|internal|..."),
ErrorPreceding, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
"the `linkage` attribute is experimental and not portable across platforms",
),
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_std_internal_symbol, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, INTERNAL_UNSTABLE
2021-09-05 23:30:37 +00:00
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Macro related:
// ==========================================================================
rustc_attr!(
rustc_builtin_macro, Normal,
2021-09-05 23:30:37 +00:00
template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"), ErrorFollowing,
EncodeCrossCrate::Yes, IMPL_DETAIL
),
rustc_attr!(
rustc_proc_macro_decls, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, INTERNAL_UNSTABLE
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
rustc_macro_transparency, Normal,
2021-09-05 23:30:37 +00:00
template!(NameValueStr: "transparent|semitransparent|opaque"), ErrorFollowing,
EncodeCrossCrate::Yes, "used internally for testing macro hygiene",
),
rustc_attr!(
rustc_autodiff, Normal,
template!(Word, List: r#""...""#), DuplicatesOk,
EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Diagnostics related:
// ==========================================================================
rustc_attr!(
rustc_on_unimplemented, Normal,
2019-08-22 21:30:59 +00:00
template!(
List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
NameValueStr: "message"
),
ErrorFollowing, EncodeCrossCrate::Yes,
INTERNAL_UNSTABLE
),
rustc_attr!(
rustc_confusables, Normal,
template!(List: r#""name1", "name2", ..."#),
ErrorFollowing, EncodeCrossCrate::Yes,
INTERNAL_UNSTABLE,
),
// Enumerates "identity-like" conversion methods to suggest on type mismatch.
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_conversion_suggestion, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
2021-09-05 23:30:37 +00:00
),
// Prevents field reads in the marked trait or method to be considered
// during dead code analysis.
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_trivial_field_reads, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
2021-09-05 23:30:37 +00:00
),
2022-01-05 12:02:16 +00:00
// Used by the `rustc::potential_query_instability` lint to warn methods which
// might not be stable during incremental compilation.
rustc_attr!(
rustc_lint_query_instability, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
// Used by the `rustc::untracked_query_information` lint to warn methods which
// might not be stable during incremental compilation.
rustc_attr!(
rustc_lint_untracked_query_information, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
// Used by the `rustc::diagnostic_outside_of_impl` lints to assist in changes to diagnostic
// APIs. Any function with this attribute will be checked by that lint.
rustc_attr!(
rustc_lint_diagnostics, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
// Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions`
// types (as well as any others in future).
rustc_attr!(
rustc_lint_opt_ty, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
// Used by the `rustc::bad_opt_access` lint on fields
// types (as well as any others in future).
rustc_attr!(
rustc_lint_opt_deny_field_access, Normal, template!(List: "message"),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Const related:
// ==========================================================================
rustc_attr!(
rustc_promotable, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, IMPL_DETAIL),
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_legacy_const_generics, Normal, template!(List: "N"), ErrorFollowing,
EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
2021-09-05 23:30:37 +00:00
),
2021-10-12 05:06:37 +00:00
// Do not const-check this function's body. It will always get replaced during CTFE.
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_do_not_const_check, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
2021-09-05 23:30:37 +00:00
),
// Ensure the argument to this function is &&str during const-check.
rustc_attr!(
rustc_const_panic_str, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
2024-06-14 12:16:15 +00:00
),
Re-do recursive const stability checks Fundamentally, we have *three* disjoint categories of functions: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, several holes in recursive const stability checking are being closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to *not* be `rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
2024-10-06 17:59:19 +00:00
rustc_attr!(
rustc_const_stable_indirect, Normal,
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
),
rustc_attr!(
rustc_intrinsic_const_stable_indirect, Normal,
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
),
Re-do recursive const stability checks Fundamentally, we have *three* disjoint categories of functions: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, several holes in recursive const stability checking are being closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to *not* be `rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
2024-10-06 17:59:19 +00:00
gated!(
rustc_allow_const_fn_unstable, Normal,
template!(Word, List: "feat1, feat2, ..."), DuplicatesOk, EncodeCrossCrate::No,
"rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
),
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Layout related:
// ==========================================================================
2019-08-22 16:32:31 +00:00
rustc_attr!(
2021-09-05 23:30:37 +00:00
rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing,
EncodeCrossCrate::Yes,
2019-08-22 21:30:59 +00:00
"the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
Generalize `get_nullable_type` to allow types where null is all-ones. Generalize get_nullable_type to accept types that have an all-ones bit pattern as their sentry "null" value. This will allow [`OwnedFd`], [`BorrowedFd`], [`OwnedSocket`], and [`BorrowedSocket`] to be marked with `#[rustc_nonnull_optimization_guaranteed]`, which will allow `Option<OwnedFd>`, `Option<BorrowedFd>`, `Option<OwnedSocket>`, and `Option<BorrowedSocket>` to be used in FFI declarations, as described in the [I/O safety RFC]. For example, it will allow a function like `open` on Unix and `WSASocketW` on Windows to be declared using `Option<OwnedFd>` and `Option<OwnedSocket>` return types, respectively. The actual change to add `#[rustc_nonnull_optimization_guaranteed]` to the abovementioned types will be a separate PR, as it'll depend on having this patch in the stage0 compiler. Also, update the diagnostics to mention that "niche optimizations" are used in libstd as well as libcore, as `rustc_layout_scalar_valid_range_start` and `rustc_layout_scalar_valid_range_end` are already in use in libstd. [`OwnedFd`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/fd/owned.rs#L49 [`BorrowedFd`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/fd/owned.rs#L29 [`OwnedSocket`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/windows/io/socket.rs#L51 [`BorrowedSocket`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/windows/io/socket.rs#L29 [I/O safety RFC]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md#ownedfd-and-borrowedfdfd-1
2022-03-03 22:41:10 +00:00
niche optimizations in libcore and libstd and will never be stable",
),
rustc_attr!(
2021-09-05 23:30:37 +00:00
rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing,
EncodeCrossCrate::Yes,
2019-08-22 21:30:59 +00:00
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
Generalize `get_nullable_type` to allow types where null is all-ones. Generalize get_nullable_type to accept types that have an all-ones bit pattern as their sentry "null" value. This will allow [`OwnedFd`], [`BorrowedFd`], [`OwnedSocket`], and [`BorrowedSocket`] to be marked with `#[rustc_nonnull_optimization_guaranteed]`, which will allow `Option<OwnedFd>`, `Option<BorrowedFd>`, `Option<OwnedSocket>`, and `Option<BorrowedSocket>` to be used in FFI declarations, as described in the [I/O safety RFC]. For example, it will allow a function like `open` on Unix and `WSASocketW` on Windows to be declared using `Option<OwnedFd>` and `Option<OwnedSocket>` return types, respectively. The actual change to add `#[rustc_nonnull_optimization_guaranteed]` to the abovementioned types will be a separate PR, as it'll depend on having this patch in the stage0 compiler. Also, update the diagnostics to mention that "niche optimizations" are used in libstd as well as libcore, as `rustc_layout_scalar_valid_range_start` and `rustc_layout_scalar_valid_range_end` are already in use in libstd. [`OwnedFd`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/fd/owned.rs#L49 [`BorrowedFd`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/fd/owned.rs#L29 [`OwnedSocket`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/windows/io/socket.rs#L51 [`BorrowedSocket`]: https://github.com/rust-lang/rust/blob/c9dc44be24c58ff13ce46416c4b97ab5c1bd8429/library/std/src/os/windows/io/socket.rs#L29 [I/O safety RFC]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md#ownedfd-and-borrowedfdfd-1
2022-03-03 22:41:10 +00:00
niche optimizations in libcore and libstd and will never be stable",
),
rustc_attr!(
2021-09-05 23:30:37 +00:00
rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes,
"the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \
guaranteed niche optimizations in libcore and libstd and will never be stable\n\
(note that the compiler does not even check whether the type indeed is being non-null-optimized; \
it is your responsibility to ensure that the attribute is only used on types that are optimized)",
),
2019-08-22 16:32:31 +00:00
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Misc:
// ==========================================================================
gated!(
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
"lang items are subject to change",
),
2024-11-02 17:39:29 +00:00
rustc_attr!(
rustc_as_ptr, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes,
"#[rustc_as_ptr] is used to mark functions returning pointers to their inner allocations."
),
rustc_attr!(
2023-02-14 09:17:19 +00:00
rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes,
"#[rustc_pass_by_value] is used to mark types that must be passed by value instead of reference."
),
rustc_attr!(
rustc_never_returns_null_ptr, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::Yes,
"#[rustc_never_returns_null_ptr] is used to mark functions returning non-null pointers."
),
rustc_attr!(
rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
"#![rustc_coherence_is_core] allows inherent methods on builtin types, only intended to be used in `core`."
),
2023-02-14 09:17:19 +00:00
rustc_attr!(
rustc_coinductive, AttributeType::Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
2023-02-14 09:17:19 +00:00
"#![rustc_coinductive] changes a trait to be coinductive, allowing cycles in the trait solver."
),
rustc_attr!(
rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
"#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl."
),
rustc_attr!(
rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
"`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",
),
2022-11-12 23:37:52 +00:00
rustc_attr!(
2023-06-16 23:45:01 +00:00
rustc_deny_explicit_impl,
AttributeType::Normal,
template!(Word),
2023-06-16 23:45:01 +00:00
ErrorFollowing,
EncodeCrossCrate::No,
2022-11-12 23:37:52 +00:00
"#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
),
rustc_attr!(
rustc_do_not_implement_via_object,
AttributeType::Normal,
template!(Word),
ErrorFollowing,
EncodeCrossCrate::No,
"#[rustc_do_not_implement_via_object] opts out of the automatic trait impl for trait objects \
(`impl Trait for dyn Trait`)"
),
rustc_attr!(
rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word),
ErrorFollowing, EncodeCrossCrate::Yes,
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
the given type by annotating all impl items with #[rustc_allow_incoherent_impl]."
),
BuiltinAttribute {
name: sym::rustc_diagnostic_item,
2022-04-01 13:04:47 +00:00
// FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`.
encode_cross_crate: EncodeCrossCrate::Yes,
type_: Normal,
2024-04-21 04:54:50 +00:00
safety: AttributeSafety::Normal,
template: template!(NameValueStr: "name"),
2021-09-05 23:30:37 +00:00
duplicates: ErrorFollowing,
gate: Gated(
Stability::Unstable,
sym::rustc_attrs,
"diagnostic items compiler internal support for linting",
Features::rustc_attrs,
),
},
gated!(
2019-08-22 21:30:59 +00:00
// Used in resolve:
2021-09-05 23:30:37 +00:00
prelude_import, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, "`#[prelude_import]` is for use by rustc only",
),
gated!(
rustc_paren_sugar, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
unboxed_closures, "unboxed_closures are still evolving",
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
overflow checking behavior of several libcore functions that are inlined \
across crates and will never be stable",
),
2021-09-05 23:30:37 +00:00
rustc_attr!(
rustc_reservation_impl, Normal,
template!(NameValueStr: "reservation message"), ErrorFollowing, EncodeCrossCrate::Yes,
2021-09-05 23:30:37 +00:00
"the `#[rustc_reservation_impl]` attribute is internally used \
for reserving for `for<T> From<!> for T` impl"
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
rustc_test_marker, Normal, template!(NameValueStr: "name"), WarnFollowing,
EncodeCrossCrate::No, "the `#[rustc_test_marker]` attribute is used internally to track tests",
2019-08-22 21:30:59 +00:00
),
rustc_attr!(
rustc_unsafe_specialization_marker, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No,
"the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations"
),
rustc_attr!(
rustc_specialization_trait, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No,
"the `#[rustc_specialization_trait]` attribute is used to check specializations"
),
2021-04-08 13:37:38 +00:00
rustc_attr!(
rustc_main, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
2021-04-08 13:37:38 +00:00
"the `#[rustc_main]` attribute is used internally to specify test entry point function",
),
rustc_attr!(
2024-04-17 20:32:17 +00:00
rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), WarnFollowing,
EncodeCrossCrate::No,
"the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
from method dispatch when the receiver is of the following type, for compatibility in \
editions < 2021 (array) or editions < 2024 (boxed_slice)."
),
rustc_attr!(
rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."),
ErrorFollowing, EncodeCrossCrate::No,
"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
definition of a trait, it's currently in experimental form and should be changed before \
being exposed outside of the std"
),
rustc_attr!(
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
EncodeCrossCrate::Yes, r#"`rustc_doc_primitive` is a rustc internal attribute"#,
),
gated!(
rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
),
rustc_attr!(
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
"#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
),
rustc_attr!(
rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
"#[rustc_force_inline] forces a free function to be inlined"
),
2019-08-22 16:32:31 +00:00
2019-08-22 21:30:59 +00:00
// ==========================================================================
// Internal attributes, Testing:
// ==========================================================================
2019-08-22 16:32:31 +00:00
rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
rustc_attr!(
TEST, rustc_outlives, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_capture_analysis, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_insignificant_dtor, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes
),
rustc_attr!(
TEST, rustc_strict_coherence, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes
),
rustc_attr!(
TEST, rustc_variance, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
2024-03-14 09:12:39 +00:00
rustc_attr!(
TEST, rustc_variance_of_opaques, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2024-03-14 09:12:39 +00:00
),
rustc_attr!(
TEST, rustc_hidden_type_of_opaques, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."),
WarnFollowing, EncodeCrossCrate::Yes
),
2024-03-14 09:12:39 +00:00
rustc_attr!(
TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."),
WarnFollowing, EncodeCrossCrate::No
2024-03-14 09:12:39 +00:00
),
rustc_attr!(
TEST, rustc_regions, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2024-03-14 09:12:39 +00:00
),
rustc_attr!(
TEST, rustc_error, Normal,
template!(Word, List: "delayed_bug_from_inside_query"),
WarnFollowingWordOnly, EncodeCrossCrate::Yes
),
rustc_attr!(
TEST, rustc_dump_user_args, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2021-09-05 23:30:37 +00:00
),
2024-03-14 09:12:39 +00:00
rustc_attr!(
TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes
2024-03-14 09:12:39 +00:00
),
2021-09-05 23:30:37 +00:00
rustc_attr!(
TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode"), DuplicatesOk,
EncodeCrossCrate::No
2021-09-05 23:30:37 +00:00
),
rustc_attr!(
TEST, rustc_then_this_would_need, Normal, template!(List: "DepNode"), DuplicatesOk,
EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_clean, Normal,
2019-08-22 21:30:59 +00:00
template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
DuplicatesOk, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_partition_reused, Normal,
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, EncodeCrossCrate::No
2019-08-22 16:32:31 +00:00
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
TEST, rustc_partition_codegened, Normal,
template!(List: r#"cfg = "...", module = "...""#), DuplicatesOk, EncodeCrossCrate::No
),
2019-08-22 21:30:59 +00:00
rustc_attr!(
TEST, rustc_expected_cgu_reuse, Normal,
2021-09-05 23:30:37 +00:00
template!(List: r#"cfg = "...", module = "...", kind = "...""#), DuplicatesOk,
EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_symbol_name, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2024-03-14 09:12:39 +00:00
),
rustc_attr!(
TEST, rustc_def_path, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ..."),
DuplicatesOk, EncodeCrossCrate::Yes
2024-03-14 09:12:39 +00:00
),
2022-08-03 11:30:13 +00:00
gated!(
custom_mir, Normal, template!(List: r#"dialect = "...", phase = "...""#),
ErrorFollowing, EncodeCrossCrate::No,
2024-03-14 09:12:39 +00:00
"the `#[custom_mir]` attribute is just used for the Rust test suite",
),
rustc_attr!(
TEST, rustc_dump_item_bounds, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_dump_predicates, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2024-06-30 18:31:15 +00:00
),
rustc_attr!(
TEST, rustc_dump_def_parents, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
),
2024-03-14 09:12:39 +00:00
rustc_attr!(
TEST, rustc_object_lifetime_default, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No
2022-08-03 11:30:13 +00:00
),
2024-03-14 09:12:39 +00:00
rustc_attr!(
TEST, rustc_dump_vtable, Normal, template!(Word),
2025-01-10 20:09:10 +00:00
WarnFollowing, EncodeCrossCrate::No
),
rustc_attr!(
TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),
DuplicatesOk, EncodeCrossCrate::No
2024-03-14 09:12:39 +00:00
),
gated!(
omit_gdb_pretty_printer_section, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No,
2019-08-22 21:30:59 +00:00
"the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
),
rustc_attr!(
TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"),
ErrorFollowing, EncodeCrossCrate::No,
),
2019-08-22 16:32:31 +00:00
];
pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> {
BUILTIN_ATTRIBUTES.iter().filter(|attr| attr.gate.is_deprecated()).collect()
2019-08-22 16:32:31 +00:00
}
2019-11-30 01:20:07 +00:00
pub fn is_builtin_attr_name(name: Symbol) -> bool {
2019-08-22 16:32:31 +00:00
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
}
/// Whether this builtin attribute is encoded cross crate.
/// This means it can be used cross crate.
pub fn encode_cross_crate(name: Symbol) -> bool {
if let Some(attr) = BUILTIN_ATTRIBUTE_MAP.get(&name) {
attr.encode_cross_crate == EncodeCrossCrate::Yes
} else {
true
}
2022-04-01 13:04:47 +00:00
}
pub fn is_valid_for_get_attr(name: Symbol) -> bool {
BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates {
WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
| FutureWarnPreceding => true,
DuplicatesOk | WarnFollowingWordOnly => false,
})
}
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
LazyLock::new(|| {
let mut map = FxHashMap::default();
for attr in BUILTIN_ATTRIBUTES.iter() {
if map.insert(attr.name, attr).is_some() {
panic!("duplicate builtin attribute `{}`", attr.name);
}
2019-08-22 16:32:31 +00:00
}
map
});
Stabilize `#[diagnostic::do_not_recommend]` This commit seeks to stabilize the `#[diagnostic::do_not_recommend]` attribute. This attribute was first proposed as `#[do_not_recommend`] attribute in RFC 2397 (https://github.com/rust-lang/rfcs/pull/2397). It gives the crate authors the ability to not suggest to the compiler to not show certain traits in it's error messages. With the presence of the `#[diagnostic]` tool attribute namespace it was decided to move the attribute there, as that lowers the amount of guarantees the compiler needs to give about the exact way this influences error messages. It turns the attribute into a hint which can be ignored. In addition to the original proposed functionality this attribute now also hides the marked trait in help messages ("This trait is implemented by: "). The attribute does not accept any argument and can only be placed on trait implementations. If it is placed somewhere else a lint warning is emitted and the attribute is otherwise ignored. If an argument is detected a lint warning is emitted and the argument is ignored. This follows the rules outlined by the diagnostic namespace. This attribute allows crates like diesel to improve their error messages drastically. The most common example here is the following error message: ``` error[E0277]: the trait bound `&str: Expression` is not satisfied --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:53:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `Expression` is not implemented for `&str`, which is required by `&str: AsExpression<Integer>` | = help: the following other types implement trait `Expression`: Bound<T> SelectInt note: required for `&str` to implement `AsExpression<Integer>` --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:26:13 | LL | impl<T, ST> AsExpression<ST> for T | ^^^^^^^^^^^^^^^^ ^ LL | where LL | T: Expression<SqlType = ST>, | ------------------------ unsatisfied trait bound introduced here ``` By applying the new attribute to the wild card trait implementation of `AsExpression` for `T: Expression` the error message becomes: ``` error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied --> $DIR/as_expression.rs:55:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str` | = help: the trait `AsExpression<Text>` is implemented for `&str` = help: for that trait implementation, expected `Text`, found `Integer` ``` which makes it much easier for users to understand that they are facing a type mismatch. Other explored example usages included * This standard library error message: https://github.com/rust-lang/rust/pull/128008 * That bevy derived example: https://github.com/rust-lang/rust/blob/e1f306899514ea80abc1d1c9f6a57762afb304a3/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs (No more tuple pyramids) Fixes #51992
2024-10-23 06:09:15 +00:00
pub fn is_stable_diagnostic_attribute(sym: Symbol, _features: &Features) -> bool {
match sym {
Stabilize `#[diagnostic::do_not_recommend]` This commit seeks to stabilize the `#[diagnostic::do_not_recommend]` attribute. This attribute was first proposed as `#[do_not_recommend`] attribute in RFC 2397 (https://github.com/rust-lang/rfcs/pull/2397). It gives the crate authors the ability to not suggest to the compiler to not show certain traits in it's error messages. With the presence of the `#[diagnostic]` tool attribute namespace it was decided to move the attribute there, as that lowers the amount of guarantees the compiler needs to give about the exact way this influences error messages. It turns the attribute into a hint which can be ignored. In addition to the original proposed functionality this attribute now also hides the marked trait in help messages ("This trait is implemented by: "). The attribute does not accept any argument and can only be placed on trait implementations. If it is placed somewhere else a lint warning is emitted and the attribute is otherwise ignored. If an argument is detected a lint warning is emitted and the argument is ignored. This follows the rules outlined by the diagnostic namespace. This attribute allows crates like diesel to improve their error messages drastically. The most common example here is the following error message: ``` error[E0277]: the trait bound `&str: Expression` is not satisfied --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:53:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `Expression` is not implemented for `&str`, which is required by `&str: AsExpression<Integer>` | = help: the following other types implement trait `Expression`: Bound<T> SelectInt note: required for `&str` to implement `AsExpression<Integer>` --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:26:13 | LL | impl<T, ST> AsExpression<ST> for T | ^^^^^^^^^^^^^^^^ ^ LL | where LL | T: Expression<SqlType = ST>, | ------------------------ unsatisfied trait bound introduced here ``` By applying the new attribute to the wild card trait implementation of `AsExpression` for `T: Expression` the error message becomes: ``` error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied --> $DIR/as_expression.rs:55:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str` | = help: the trait `AsExpression<Text>` is implemented for `&str` = help: for that trait implementation, expected `Text`, found `Integer` ``` which makes it much easier for users to understand that they are facing a type mismatch. Other explored example usages included * This standard library error message: https://github.com/rust-lang/rust/pull/128008 * That bevy derived example: https://github.com/rust-lang/rust/blob/e1f306899514ea80abc1d1c9f6a57762afb304a3/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs (No more tuple pyramids) Fixes #51992
2024-10-23 06:09:15 +00:00
sym::on_unimplemented | sym::do_not_recommend => true,
_ => false,
}
}