mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 14:23:45 +00:00
Auto merge of #133160 - jhpratt:rollup-wzj9q15, r=jhpratt
Rollup of 4 pull requests Successful merges: - #132934 (Overhaul the `-l` option parser (for linking to native libs)) - #133142 (rename rustc_const_stable_intrinsic -> rustc_intrinsic_const_stable_indirect) - #133145 (Document alternatives to `static mut`) - #133158 (Subtree update of `rust-analyzer`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c602e9aeaa
@ -403,7 +403,7 @@ const_eval_uninhabited_enum_variant_written =
|
||||
const_eval_unmarked_const_fn_exposed = `{$def_path}` cannot be (indirectly) exposed to stable
|
||||
.help = either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
|
||||
const_eval_unmarked_intrinsic_exposed = intrinsic `{$def_path}` cannot be (indirectly) exposed to stable
|
||||
.help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
|
||||
.help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)
|
||||
|
||||
const_eval_unreachable = entering unreachable code
|
||||
const_eval_unreachable_unwind =
|
||||
|
@ -760,7 +760,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
|
||||
// All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
|
||||
// can be *directly* invoked from stable const code) does not always
|
||||
// have the `#[rustc_const_stable_intrinsic]` attribute (which controls
|
||||
// have the `#[rustc_intrinsic_const_stable_indirect]` attribute (which controls
|
||||
// exposing an intrinsic indirectly); we accept this call anyway.
|
||||
}
|
||||
}
|
||||
|
@ -838,7 +838,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_const_stable_intrinsic, Normal,
|
||||
rustc_intrinsic_const_stable_indirect, Normal,
|
||||
template!(Word), WarnFollowing, EncodeCrossCrate::No, IMPL_DETAIL,
|
||||
),
|
||||
gated!(
|
||||
|
@ -1793,7 +1793,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
|
||||
Some(ty::IntrinsicDef {
|
||||
name: tcx.item_name(def_id.into()),
|
||||
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
|
||||
const_stable: tcx.has_attr(def_id, sym::rustc_const_stable_intrinsic),
|
||||
const_stable: tcx.has_attr(def_id, sym::rustc_intrinsic_const_stable_indirect),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
@ -30,17 +30,18 @@ use rustc_target::spec::{
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
|
||||
use crate::config::native_libs::parse_native_libs;
|
||||
use crate::errors::FileWriteFail;
|
||||
pub use crate::options::*;
|
||||
use crate::search_paths::SearchPath;
|
||||
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
|
||||
use crate::utils::CanonicalizedPath;
|
||||
use crate::{EarlyDiagCtxt, HashStableContext, Session, filesearch, lint};
|
||||
|
||||
mod cfg;
|
||||
mod native_libs;
|
||||
pub mod sigpipe;
|
||||
|
||||
pub use cfg::{Cfg, CheckCfg, ExpectedValues};
|
||||
|
||||
/// The different settings that the `-C strip` flag can have.
|
||||
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
|
||||
pub enum Strip {
|
||||
@ -2134,143 +2135,6 @@ fn parse_assert_incr_state(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_native_lib_kind(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
matches: &getopts::Matches,
|
||||
kind: &str,
|
||||
) -> (NativeLibKind, Option<bool>) {
|
||||
let (kind, modifiers) = match kind.split_once(':') {
|
||||
None => (kind, None),
|
||||
Some((kind, modifiers)) => (kind, Some(modifiers)),
|
||||
};
|
||||
|
||||
let kind = match kind {
|
||||
"static" => NativeLibKind::Static { bundle: None, whole_archive: None },
|
||||
"dylib" => NativeLibKind::Dylib { as_needed: None },
|
||||
"framework" => NativeLibKind::Framework { as_needed: None },
|
||||
"link-arg" => {
|
||||
if !nightly_options::is_unstable_enabled(matches) {
|
||||
let why = if nightly_options::match_is_nightly_build(matches) {
|
||||
" and only accepted on the nightly compiler"
|
||||
} else {
|
||||
", the `-Z unstable-options` flag must also be passed to use it"
|
||||
};
|
||||
early_dcx.early_fatal(format!("library kind `link-arg` is unstable{why}"))
|
||||
}
|
||||
NativeLibKind::LinkArg
|
||||
}
|
||||
_ => early_dcx.early_fatal(format!(
|
||||
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
|
||||
)),
|
||||
};
|
||||
match modifiers {
|
||||
None => (kind, None),
|
||||
Some(modifiers) => parse_native_lib_modifiers(early_dcx, kind, modifiers, matches),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_native_lib_modifiers(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
mut kind: NativeLibKind,
|
||||
modifiers: &str,
|
||||
matches: &getopts::Matches,
|
||||
) -> (NativeLibKind, Option<bool>) {
|
||||
let mut verbatim = None;
|
||||
for modifier in modifiers.split(',') {
|
||||
let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
|
||||
Some(m) => (m, modifier.starts_with('+')),
|
||||
None => early_dcx.early_fatal(
|
||||
"invalid linking modifier syntax, expected '+' or '-' prefix \
|
||||
before one of: bundle, verbatim, whole-archive, as-needed",
|
||||
),
|
||||
};
|
||||
|
||||
let report_unstable_modifier = || {
|
||||
if !nightly_options::is_unstable_enabled(matches) {
|
||||
let why = if nightly_options::match_is_nightly_build(matches) {
|
||||
" and only accepted on the nightly compiler"
|
||||
} else {
|
||||
", the `-Z unstable-options` flag must also be passed to use it"
|
||||
};
|
||||
early_dcx.early_fatal(format!("linking modifier `{modifier}` is unstable{why}"))
|
||||
}
|
||||
};
|
||||
let assign_modifier = |dst: &mut Option<bool>| {
|
||||
if dst.is_some() {
|
||||
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
|
||||
early_dcx.early_fatal(msg)
|
||||
} else {
|
||||
*dst = Some(value);
|
||||
}
|
||||
};
|
||||
match (modifier, &mut kind) {
|
||||
("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
|
||||
("bundle", _) => early_dcx.early_fatal(
|
||||
"linking modifier `bundle` is only compatible with `static` linking kind",
|
||||
),
|
||||
|
||||
("verbatim", _) => assign_modifier(&mut verbatim),
|
||||
|
||||
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
|
||||
assign_modifier(whole_archive)
|
||||
}
|
||||
("whole-archive", _) => early_dcx.early_fatal(
|
||||
"linking modifier `whole-archive` is only compatible with `static` linking kind",
|
||||
),
|
||||
|
||||
("as-needed", NativeLibKind::Dylib { as_needed })
|
||||
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
|
||||
report_unstable_modifier();
|
||||
assign_modifier(as_needed)
|
||||
}
|
||||
("as-needed", _) => early_dcx.early_fatal(
|
||||
"linking modifier `as-needed` is only compatible with \
|
||||
`dylib` and `framework` linking kinds",
|
||||
),
|
||||
|
||||
// Note: this error also excludes the case with empty modifier
|
||||
// string, like `modifiers = ""`.
|
||||
_ => early_dcx.early_fatal(format!(
|
||||
"unknown linking modifier `{modifier}`, expected one \
|
||||
of: bundle, verbatim, whole-archive, as-needed"
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
(kind, verbatim)
|
||||
}
|
||||
|
||||
fn parse_libs(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Vec<NativeLib> {
|
||||
matches
|
||||
.opt_strs("l")
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
// Parse string of the form "[KIND[:MODIFIERS]=]lib[:new_name]",
|
||||
// where KIND is one of "dylib", "framework", "static", "link-arg" and
|
||||
// where MODIFIERS are a comma separated list of supported modifiers
|
||||
// (bundle, verbatim, whole-archive, as-needed). Each modifier is prefixed
|
||||
// with either + or - to indicate whether it is enabled or disabled.
|
||||
// The last value specified for a given modifier wins.
|
||||
let (name, kind, verbatim) = match s.split_once('=') {
|
||||
None => (s, NativeLibKind::Unspecified, None),
|
||||
Some((kind, name)) => {
|
||||
let (kind, verbatim) = parse_native_lib_kind(early_dcx, matches, kind);
|
||||
(name.to_string(), kind, verbatim)
|
||||
}
|
||||
};
|
||||
|
||||
let (name, new_name) = match name.split_once(':') {
|
||||
None => (name, None),
|
||||
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
|
||||
};
|
||||
if name.is_empty() {
|
||||
early_dcx.early_fatal("library name must not be empty");
|
||||
}
|
||||
NativeLib { name, new_name, kind, verbatim }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn parse_externs(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
matches: &getopts::Matches,
|
||||
@ -2644,7 +2508,10 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||
let debuginfo = select_debuginfo(matches, &cg);
|
||||
let debuginfo_compression = unstable_opts.debuginfo_compression;
|
||||
|
||||
let libs = parse_libs(early_dcx, matches);
|
||||
let crate_name = matches.opt_str("crate-name");
|
||||
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
|
||||
// Parse any `-l` flags, which link to native libraries.
|
||||
let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
|
||||
|
||||
let test = matches.opt_present("test");
|
||||
|
||||
@ -2659,8 +2526,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||
|
||||
let externs = parse_externs(early_dcx, matches, &unstable_opts);
|
||||
|
||||
let crate_name = matches.opt_str("crate-name");
|
||||
|
||||
let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
|
||||
|
||||
let pretty = parse_pretty(early_dcx, &unstable_opts);
|
||||
@ -2734,7 +2599,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
||||
error_format,
|
||||
diagnostic_width,
|
||||
externs,
|
||||
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
|
||||
unstable_features,
|
||||
crate_name,
|
||||
libs,
|
||||
debug_assertions,
|
||||
|
192
compiler/rustc_session/src/config/native_libs.rs
Normal file
192
compiler/rustc_session/src/config/native_libs.rs
Normal file
@ -0,0 +1,192 @@
|
||||
//! Parser for the `-l` command-line option, which links the generated crate to
|
||||
//! a native library.
|
||||
//!
|
||||
//! (There is also a similar but separate syntax for `#[link]` attributes,
|
||||
//! which have their own parser in `rustc_metadata`.)
|
||||
|
||||
use rustc_feature::UnstableFeatures;
|
||||
|
||||
use crate::EarlyDiagCtxt;
|
||||
use crate::config::UnstableOptions;
|
||||
use crate::utils::{NativeLib, NativeLibKind};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// Parses all `-l` options.
|
||||
pub(crate) fn parse_native_libs(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
unstable_opts: &UnstableOptions,
|
||||
unstable_features: UnstableFeatures,
|
||||
matches: &getopts::Matches,
|
||||
) -> Vec<NativeLib> {
|
||||
let cx = ParseNativeLibCx {
|
||||
early_dcx,
|
||||
unstable_options_enabled: unstable_opts.unstable_options,
|
||||
is_nightly: unstable_features.is_nightly_build(),
|
||||
};
|
||||
matches.opt_strs("l").into_iter().map(|value| parse_native_lib(&cx, &value)).collect()
|
||||
}
|
||||
|
||||
struct ParseNativeLibCx<'a> {
|
||||
early_dcx: &'a EarlyDiagCtxt,
|
||||
unstable_options_enabled: bool,
|
||||
is_nightly: bool,
|
||||
}
|
||||
|
||||
impl ParseNativeLibCx<'_> {
|
||||
/// If unstable values are not permitted, exits with a fatal error made by
|
||||
/// combining the given strings.
|
||||
fn on_unstable_value(&self, message: &str, if_nightly: &str, if_stable: &str) {
|
||||
if self.unstable_options_enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let suffix = if self.is_nightly { if_nightly } else { if_stable };
|
||||
self.early_dcx.early_fatal(format!("{message}{suffix}"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the value of a single `-l` option.
|
||||
fn parse_native_lib(cx: &ParseNativeLibCx<'_>, value: &str) -> NativeLib {
|
||||
let NativeLibParts { kind, modifiers, name, new_name } = split_native_lib_value(value);
|
||||
|
||||
let kind = kind.map_or(NativeLibKind::Unspecified, |kind| match kind {
|
||||
"static" => NativeLibKind::Static { bundle: None, whole_archive: None },
|
||||
"dylib" => NativeLibKind::Dylib { as_needed: None },
|
||||
"framework" => NativeLibKind::Framework { as_needed: None },
|
||||
"link-arg" => {
|
||||
cx.on_unstable_value(
|
||||
"library kind `link-arg` is unstable",
|
||||
", the `-Z unstable-options` flag must also be passed to use it",
|
||||
" and only accepted on the nightly compiler",
|
||||
);
|
||||
NativeLibKind::LinkArg
|
||||
}
|
||||
_ => cx.early_dcx.early_fatal(format!(
|
||||
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
|
||||
)),
|
||||
});
|
||||
|
||||
// Provisionally create the result, so that modifiers can modify it.
|
||||
let mut native_lib = NativeLib {
|
||||
name: name.to_owned(),
|
||||
new_name: new_name.map(str::to_owned),
|
||||
kind,
|
||||
verbatim: None,
|
||||
};
|
||||
|
||||
if let Some(modifiers) = modifiers {
|
||||
// If multiple modifiers are present, they are separated by commas.
|
||||
for modifier in modifiers.split(',') {
|
||||
parse_and_apply_modifier(cx, modifier, &mut native_lib);
|
||||
}
|
||||
}
|
||||
|
||||
if native_lib.name.is_empty() {
|
||||
cx.early_dcx.early_fatal("library name must not be empty");
|
||||
}
|
||||
|
||||
native_lib
|
||||
}
|
||||
|
||||
/// Parses one of the comma-separated modifiers (prefixed by `+` or `-`), and
|
||||
/// modifies `native_lib` appropriately.
|
||||
///
|
||||
/// Exits with a fatal error if a malformed/unknown/inappropriate modifier is
|
||||
/// found.
|
||||
fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_lib: &mut NativeLib) {
|
||||
let early_dcx = cx.early_dcx;
|
||||
|
||||
// Split off the leading `+` or `-` into a boolean value.
|
||||
let (modifier, value) = match modifier.split_at_checked(1) {
|
||||
Some(("+", m)) => (m, true),
|
||||
Some(("-", m)) => (m, false),
|
||||
_ => cx.early_dcx.early_fatal(
|
||||
"invalid linking modifier syntax, expected '+' or '-' prefix \
|
||||
before one of: bundle, verbatim, whole-archive, as-needed",
|
||||
),
|
||||
};
|
||||
|
||||
// Assigns the value (from `+` or `-`) to an empty `Option<bool>`, or emits
|
||||
// a fatal error if the option has already been set.
|
||||
let assign_modifier = |opt_bool: &mut Option<bool>| {
|
||||
if opt_bool.is_some() {
|
||||
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
|
||||
early_dcx.early_fatal(msg)
|
||||
}
|
||||
*opt_bool = Some(value);
|
||||
};
|
||||
|
||||
// Check that the modifier is applicable to the native lib kind, and apply it.
|
||||
match (modifier, &mut native_lib.kind) {
|
||||
("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
|
||||
("bundle", _) => early_dcx
|
||||
.early_fatal("linking modifier `bundle` is only compatible with `static` linking kind"),
|
||||
|
||||
("verbatim", _) => assign_modifier(&mut native_lib.verbatim),
|
||||
|
||||
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
|
||||
assign_modifier(whole_archive)
|
||||
}
|
||||
("whole-archive", _) => early_dcx.early_fatal(
|
||||
"linking modifier `whole-archive` is only compatible with `static` linking kind",
|
||||
),
|
||||
|
||||
("as-needed", NativeLibKind::Dylib { as_needed })
|
||||
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
|
||||
cx.on_unstable_value(
|
||||
"linking modifier `as-needed` is unstable",
|
||||
", the `-Z unstable-options` flag must also be passed to use it",
|
||||
" and only accepted on the nightly compiler",
|
||||
);
|
||||
assign_modifier(as_needed)
|
||||
}
|
||||
("as-needed", _) => early_dcx.early_fatal(
|
||||
"linking modifier `as-needed` is only compatible with \
|
||||
`dylib` and `framework` linking kinds",
|
||||
),
|
||||
|
||||
_ => early_dcx.early_fatal(format!(
|
||||
"unknown linking modifier `{modifier}`, expected one \
|
||||
of: bundle, verbatim, whole-archive, as-needed"
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct NativeLibParts<'a> {
|
||||
kind: Option<&'a str>,
|
||||
modifiers: Option<&'a str>,
|
||||
name: &'a str,
|
||||
new_name: Option<&'a str>,
|
||||
}
|
||||
|
||||
/// Splits a string of the form `[KIND[:MODIFIERS]=]NAME[:NEW_NAME]` into those
|
||||
/// individual parts. This cannot fail, but the resulting strings require
|
||||
/// further validation.
|
||||
fn split_native_lib_value(value: &str) -> NativeLibParts<'_> {
|
||||
// Split the initial value into `[KIND=]NAME`.
|
||||
let name = value;
|
||||
let (kind, name) = match name.split_once('=') {
|
||||
Some((prefix, name)) => (Some(prefix), name),
|
||||
None => (None, name),
|
||||
};
|
||||
|
||||
// Split the kind part, if present, into `KIND[:MODIFIERS]`.
|
||||
let (kind, modifiers) = match kind {
|
||||
Some(kind) => match kind.split_once(':') {
|
||||
Some((kind, modifiers)) => (Some(kind), Some(modifiers)),
|
||||
None => (Some(kind), None),
|
||||
},
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
// Split the name part into `NAME[:NEW_NAME]`.
|
||||
let (name, new_name) = match name.split_once(':') {
|
||||
Some((name, new_name)) => (name, Some(new_name)),
|
||||
None => (name, None),
|
||||
};
|
||||
|
||||
NativeLibParts { kind, modifiers, name, new_name }
|
||||
}
|
50
compiler/rustc_session/src/config/native_libs/tests.rs
Normal file
50
compiler/rustc_session/src/config/native_libs/tests.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use crate::config::native_libs::{NativeLibParts, split_native_lib_value};
|
||||
|
||||
#[test]
|
||||
fn split() {
|
||||
// This is a unit test for some implementation details, so consider deleting
|
||||
// it if it gets in the way.
|
||||
use NativeLibParts as P;
|
||||
|
||||
let examples = &[
|
||||
("", P { kind: None, modifiers: None, name: "", new_name: None }),
|
||||
("foo", P { kind: None, modifiers: None, name: "foo", new_name: None }),
|
||||
("foo:", P { kind: None, modifiers: None, name: "foo", new_name: Some("") }),
|
||||
("foo:bar", P { kind: None, modifiers: None, name: "foo", new_name: Some("bar") }),
|
||||
(":bar", P { kind: None, modifiers: None, name: "", new_name: Some("bar") }),
|
||||
("kind=foo", P { kind: Some("kind"), modifiers: None, name: "foo", new_name: None }),
|
||||
(":mods=foo", P { kind: Some(""), modifiers: Some("mods"), name: "foo", new_name: None }),
|
||||
(":mods=:bar", P {
|
||||
kind: Some(""),
|
||||
modifiers: Some("mods"),
|
||||
name: "",
|
||||
new_name: Some("bar"),
|
||||
}),
|
||||
("kind=foo:bar", P {
|
||||
kind: Some("kind"),
|
||||
modifiers: None,
|
||||
name: "foo",
|
||||
new_name: Some("bar"),
|
||||
}),
|
||||
("kind:mods=foo", P {
|
||||
kind: Some("kind"),
|
||||
modifiers: Some("mods"),
|
||||
name: "foo",
|
||||
new_name: None,
|
||||
}),
|
||||
("kind:mods=foo:bar", P {
|
||||
kind: Some("kind"),
|
||||
modifiers: Some("mods"),
|
||||
name: "foo",
|
||||
new_name: Some("bar"),
|
||||
}),
|
||||
("::==::", P { kind: Some(""), modifiers: Some(":"), name: "=", new_name: Some(":") }),
|
||||
("==::==", P { kind: Some(""), modifiers: None, name: "=", new_name: Some(":==") }),
|
||||
];
|
||||
|
||||
for &(value, ref expected) in examples {
|
||||
println!("{value:?}");
|
||||
let actual = split_native_lib_value(value);
|
||||
assert_eq!(&actual, expected);
|
||||
}
|
||||
}
|
@ -1666,7 +1666,6 @@ symbols! {
|
||||
rustc_const_panic_str,
|
||||
rustc_const_stable,
|
||||
rustc_const_stable_indirect,
|
||||
rustc_const_stable_intrinsic,
|
||||
rustc_const_unstable,
|
||||
rustc_conversion_suggestion,
|
||||
rustc_deallocator,
|
||||
@ -1696,6 +1695,7 @@ symbols! {
|
||||
rustc_inherit_overflow_checks,
|
||||
rustc_insignificant_dtor,
|
||||
rustc_intrinsic,
|
||||
rustc_intrinsic_const_stable_indirect,
|
||||
rustc_intrinsic_must_be_overridden,
|
||||
rustc_layout,
|
||||
rustc_layout_scalar_valid_range_end,
|
||||
|
@ -15,7 +15,7 @@
|
||||
//! and make the intrinsic declaration a `const fn`.
|
||||
//!
|
||||
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
|
||||
//! `#[rustc_const_stable_intrinsic]` needs to be added to the intrinsic. Such a change requires
|
||||
//! `#[rustc_intrinsic_const_stable_indirect]` needs to be added to the intrinsic. Such a change requires
|
||||
//! T-lang approval, because it may bake a feature into the language that cannot be replicated in
|
||||
//! user code without compiler support.
|
||||
//!
|
||||
@ -1435,7 +1435,7 @@ pub fn abort() -> ! {
|
||||
bootstrap,
|
||||
rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")
|
||||
)]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1454,7 +1454,7 @@ pub const unsafe fn unreachable() -> ! {
|
||||
///
|
||||
/// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`].
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assume", since = "1.77.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[rustc_intrinsic]
|
||||
@ -1571,7 +1571,7 @@ pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type", since = "1.59.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1584,7 +1584,7 @@ pub const fn assert_inhabited<T>() {
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1596,7 +1596,7 @@ pub const fn assert_zero_valid<T>() {
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_assert_type2", since = "1.75.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1613,7 +1613,7 @@ pub const fn assert_mem_uninitialized_valid<T>() {
|
||||
///
|
||||
/// Consider using [`core::panic::Location::caller`] instead.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_caller_location", since = "1.79.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1631,7 +1631,7 @@ pub const fn caller_location() -> &'static crate::panic::Location<'static> {
|
||||
/// Therefore, implementations must not require the user to uphold
|
||||
/// any safety invariants.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1945,7 +1945,7 @@ pub const unsafe fn transmute<Src, Dst>(_src: Src) -> Dst {
|
||||
/// This is not expected to ever be exposed directly to users, rather it
|
||||
/// may eventually be exposed through some more-constrained API.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_transmute", since = "1.56.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1967,7 +1967,7 @@ pub const unsafe fn transmute_unchecked<Src, Dst>(_src: Src) -> Dst {
|
||||
///
|
||||
/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_needs_drop", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -1993,7 +1993,7 @@ pub const fn needs_drop<T: ?Sized>() -> bool {
|
||||
/// The stabilized version of this intrinsic is [`pointer::offset`].
|
||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2016,7 +2016,7 @@ pub const unsafe fn offset<Ptr, Delta>(_dst: Ptr, _offset: Delta) -> Ptr {
|
||||
/// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
|
||||
#[must_use = "returns a new pointer rather than modifying its argument"]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2724,7 +2724,7 @@ pub fn frem_algebraic<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// primitives via the `count_ones` method. For example,
|
||||
/// [`u32::count_ones`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctpop", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2769,7 +2769,7 @@ pub const fn ctpop<T: Copy>(_x: T) -> u32 {
|
||||
/// assert_eq!(num_leading, 16);
|
||||
/// ```
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ctlz", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2795,7 +2795,7 @@ pub const fn ctlz<T: Copy>(_x: T) -> u32 {
|
||||
/// assert_eq!(num_leading, 3);
|
||||
/// ```
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "constctlz", since = "1.50.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2840,7 +2840,7 @@ pub const unsafe fn ctlz_nonzero<T: Copy>(_x: T) -> u32 {
|
||||
/// assert_eq!(num_trailing, 16);
|
||||
/// ```
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2866,7 +2866,7 @@ pub const fn cttz<T: Copy>(_x: T) -> u32 {
|
||||
/// assert_eq!(num_trailing, 3);
|
||||
/// ```
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2885,7 +2885,7 @@ pub const unsafe fn cttz_nonzero<T: Copy>(_x: T) -> u32 {
|
||||
/// primitives via the `swap_bytes` method. For example,
|
||||
/// [`u32::swap_bytes`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bswap", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2904,7 +2904,7 @@ pub const fn bswap<T: Copy>(_x: T) -> T {
|
||||
/// primitives via the `reverse_bits` method. For example,
|
||||
/// [`u32::reverse_bits`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_bitreverse", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2937,7 +2937,7 @@ pub const fn three_way_compare<T: Copy>(_lhs: T, _rhss: T) -> crate::cmp::Orderi
|
||||
/// primitives via the `overflowing_add` method. For example,
|
||||
/// [`u32::overflowing_add`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2956,7 +2956,7 @@ pub const fn add_with_overflow<T: Copy>(_x: T, _y: T) -> (T, bool) {
|
||||
/// primitives via the `overflowing_sub` method. For example,
|
||||
/// [`u32::overflowing_sub`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -2975,7 +2975,7 @@ pub const fn sub_with_overflow<T: Copy>(_x: T, _y: T) -> (T, bool) {
|
||||
/// primitives via the `overflowing_mul` method. For example,
|
||||
/// [`u32::overflowing_mul`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_overflow", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3002,7 +3002,7 @@ pub const unsafe fn exact_div<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// primitives via the `checked_div` method. For example,
|
||||
/// [`u32::checked_div`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3016,7 +3016,7 @@ pub const unsafe fn unchecked_div<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// primitives via the `checked_rem` method. For example,
|
||||
/// [`u32::checked_rem`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3031,7 +3031,7 @@ pub const unsafe fn unchecked_rem<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// primitives via the `checked_shl` method. For example,
|
||||
/// [`u32::checked_shl`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3045,7 +3045,7 @@ pub const unsafe fn unchecked_shl<T: Copy, U: Copy>(_x: T, _y: U) -> T {
|
||||
/// primitives via the `checked_shr` method. For example,
|
||||
/// [`u32::checked_shr`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3059,7 +3059,7 @@ pub const unsafe fn unchecked_shr<T: Copy, U: Copy>(_x: T, _y: U) -> T {
|
||||
/// The stable counterpart of this intrinsic is `unchecked_add` on the various
|
||||
/// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`].
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3073,7 +3073,7 @@ pub const unsafe fn unchecked_add<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// The stable counterpart of this intrinsic is `unchecked_sub` on the various
|
||||
/// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`].
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3087,7 +3087,7 @@ pub const unsafe fn unchecked_sub<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// The stable counterpart of this intrinsic is `unchecked_mul` on the various
|
||||
/// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`].
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "unchecked_math", since = "1.79.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3106,7 +3106,7 @@ pub const unsafe fn unchecked_mul<T: Copy>(_x: T, _y: T) -> T {
|
||||
/// primitives via the `rotate_left` method. For example,
|
||||
/// [`u32::rotate_left`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3125,7 +3125,7 @@ pub const fn rotate_left<T: Copy>(_x: T, _shift: u32) -> T {
|
||||
/// primitives via the `rotate_right` method. For example,
|
||||
/// [`u32::rotate_right`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_rotate", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3144,7 +3144,7 @@ pub const fn rotate_right<T: Copy>(_x: T, _shift: u32) -> T {
|
||||
/// primitives via the `wrapping_add` method. For example,
|
||||
/// [`u32::wrapping_add`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3162,7 +3162,7 @@ pub const fn wrapping_add<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// primitives via the `wrapping_sub` method. For example,
|
||||
/// [`u32::wrapping_sub`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3180,7 +3180,7 @@ pub const fn wrapping_sub<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// primitives via the `wrapping_mul` method. For example,
|
||||
/// [`u32::wrapping_mul`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3199,7 +3199,7 @@ pub const fn wrapping_mul<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// primitives via the `saturating_add` method. For example,
|
||||
/// [`u32::saturating_add`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3217,7 +3217,7 @@ pub const fn saturating_add<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// primitives via the `saturating_sub` method. For example,
|
||||
/// [`u32::saturating_sub`]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_int_saturating", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3232,7 +3232,7 @@ pub const fn saturating_sub<T: Copy>(_a: T, _b: T) -> T {
|
||||
/// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
|
||||
/// trivially obeys runtime-MIR rules about derefs in operands.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_read", since = "1.71.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3247,7 +3247,7 @@ pub const unsafe fn read_via_copy<T>(_ptr: *const T) -> T {
|
||||
/// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
|
||||
/// that it trivially obeys runtime-MIR rules about derefs in operands.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3265,7 +3265,7 @@ pub const unsafe fn write_via_move<T>(_ptr: *mut T, _value: T) {
|
||||
///
|
||||
/// The stabilized version of this intrinsic is [`core::mem::discriminant`].
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_discriminant", since = "1.75.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3305,7 +3305,7 @@ extern "rust-intrinsic" {
|
||||
|
||||
/// See documentation of `<*const T>::offset_from` for details.
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -3674,7 +3674,7 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
|
||||
/// user has UB checks disabled, the checks will still get optimized out. This intrinsic is
|
||||
/// primarily used by [`ub_checks::assert_unsafe_precondition`].
|
||||
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)] // just for UB checks
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)] // just for UB checks
|
||||
#[inline(always)]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn ub_checks() -> bool {
|
||||
@ -3758,7 +3758,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
|
||||
#[rustc_nounwind]
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_size_of", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub const fn size_of<T>() -> usize {
|
||||
@ -3776,7 +3776,7 @@ pub const fn size_of<T>() -> usize {
|
||||
#[rustc_nounwind]
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_min_align_of", since = "1.40.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub const fn min_align_of<T>() -> usize {
|
||||
@ -3890,7 +3890,7 @@ pub const fn type_id<T: ?Sized + 'static>() -> u128 {
|
||||
#[rustc_nounwind]
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
|
||||
@ -3919,7 +3919,7 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
|
||||
bootstrap,
|
||||
cfg_attr(bootstrap, rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0"))
|
||||
)]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *const P) -> M {
|
||||
@ -4026,7 +4026,7 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *cons
|
||||
#[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
|
||||
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -4133,7 +4133,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
|
||||
#[rustc_diagnostic_item = "ptr_copy"]
|
||||
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
@ -4217,7 +4217,7 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
#[rustc_diagnostic_item = "ptr_write_bytes"]
|
||||
pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_ptr_write", since = "1.83.0"))]
|
||||
#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
|
||||
#[cfg_attr(not(bootstrap), rustc_intrinsic_const_stable_indirect)]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
|
@ -1448,6 +1448,9 @@ mod self_upper_keyword {}
|
||||
/// in a multithreaded context. As such, all accesses to mutable `static`s
|
||||
/// require an [`unsafe`] block.
|
||||
///
|
||||
/// When possible, it's often better to use a non-mutable `static` with an
|
||||
/// interior mutable type such as [`Mutex`], [`OnceLock`], or an [atomic].
|
||||
///
|
||||
/// Despite their unsafety, mutable `static`s are necessary in many contexts:
|
||||
/// they can be used to represent global state shared by the whole program or in
|
||||
/// [`extern`] blocks to bind to variables from C libraries.
|
||||
@ -1468,7 +1471,10 @@ mod self_upper_keyword {}
|
||||
/// [`extern`]: keyword.extern.html
|
||||
/// [`mut`]: keyword.mut.html
|
||||
/// [`unsafe`]: keyword.unsafe.html
|
||||
/// [`Mutex`]: sync::Mutex
|
||||
/// [`OnceLock`]: sync::OnceLock
|
||||
/// [`RefCell`]: cell::RefCell
|
||||
/// [atomic]: sync::atomic
|
||||
/// [Reference]: ../reference/items/static-items.html
|
||||
mod static_keyword {}
|
||||
|
||||
|
@ -2625,18 +2625,18 @@ checksum = "672423d4fea7ffa2f6c25ba60031ea13dc6258070556f125cc4d790007d4a155"
|
||||
|
||||
[[package]]
|
||||
name = "xshell"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db0ab86eae739efd1b054a8d3d16041914030ac4e01cd1dca0cf252fd8b6437"
|
||||
checksum = "9e7290c623014758632efe00737145b6867b66292c42167f2ec381eb566a373d"
|
||||
dependencies = [
|
||||
"xshell-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xshell-macros"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d422e8e38ec76e2f06ee439ccc765e9c6a9638b9e7c9f2e8255e4d41e8bd852"
|
||||
checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547"
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
|
@ -1,7 +1,7 @@
|
||||
use either::Either;
|
||||
use ide_db::FxHashMap;
|
||||
use itertools::Itertools;
|
||||
use syntax::{ast, ted, AstNode, SmolStr, ToSmolStr};
|
||||
use syntax::{ast, syntax_editor::SyntaxEditor, AstNode, SmolStr, SyntaxElement, ToSmolStr};
|
||||
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
@ -24,6 +24,11 @@ pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
let record =
|
||||
path.syntax().parent().and_then(<Either<ast::RecordExpr, ast::RecordPat>>::cast)?;
|
||||
|
||||
let parent_node = match ctx.covering_element() {
|
||||
SyntaxElement::Node(n) => n,
|
||||
SyntaxElement::Token(t) => t.parent()?,
|
||||
};
|
||||
|
||||
let ranks = compute_fields_ranks(&path, ctx)?;
|
||||
let get_rank_of_field = |of: Option<SmolStr>| {
|
||||
*ranks.get(of.unwrap_or_default().trim_start_matches("r#")).unwrap_or(&usize::MAX)
|
||||
@ -65,23 +70,31 @@ pub(crate) fn reorder_fields(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
AssistId("reorder_fields", AssistKind::RefactorRewrite),
|
||||
"Reorder record fields",
|
||||
target,
|
||||
|builder| match fields {
|
||||
Either::Left((sorted, field_list)) => {
|
||||
replace(builder.make_mut(field_list).fields(), sorted)
|
||||
}
|
||||
Either::Right((sorted, field_list)) => {
|
||||
replace(builder.make_mut(field_list).fields(), sorted)
|
||||
|builder| {
|
||||
let mut editor = builder.make_editor(&parent_node);
|
||||
|
||||
match fields {
|
||||
Either::Left((sorted, field_list)) => {
|
||||
replace(&mut editor, field_list.fields(), sorted)
|
||||
}
|
||||
Either::Right((sorted, field_list)) => {
|
||||
replace(&mut editor, field_list.fields(), sorted)
|
||||
}
|
||||
}
|
||||
|
||||
builder.add_file_edits(ctx.file_id(), editor);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn replace<T: AstNode + PartialEq>(
|
||||
editor: &mut SyntaxEditor,
|
||||
fields: impl Iterator<Item = T>,
|
||||
sorted_fields: impl IntoIterator<Item = T>,
|
||||
) {
|
||||
fields.zip(sorted_fields).for_each(|(field, sorted_field)| {
|
||||
ted::replace(field.syntax(), sorted_field.syntax().clone_for_update())
|
||||
// FIXME: remove `clone_for_update` when `SyntaxEditor` handles it for us
|
||||
editor.replace(field.syntax(), sorted_field.syntax().clone_for_update())
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -511,12 +511,16 @@ pub(crate) fn handle_document_diagnostics(
|
||||
.into_iter()
|
||||
.filter_map(|d| {
|
||||
let file = d.range.file_id;
|
||||
let diagnostic = convert_diagnostic(&line_index, d);
|
||||
if file == file_id {
|
||||
let diagnostic = convert_diagnostic(&line_index, d);
|
||||
return Some(diagnostic);
|
||||
}
|
||||
if supports_related {
|
||||
related_documents.entry(file).or_insert_with(Vec::new).push(diagnostic);
|
||||
let (diagnostics, line_index) = related_documents
|
||||
.entry(file)
|
||||
.or_insert_with(|| (Vec::new(), snap.file_line_index(file).ok()));
|
||||
let diagnostic = convert_diagnostic(line_index.as_mut()?, d);
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
None
|
||||
});
|
||||
@ -529,7 +533,7 @@ pub(crate) fn handle_document_diagnostics(
|
||||
related_documents: related_documents.is_empty().not().then(|| {
|
||||
related_documents
|
||||
.into_iter()
|
||||
.map(|(id, items)| {
|
||||
.map(|(id, (items, _))| {
|
||||
(
|
||||
to_proto::url(&snap, id),
|
||||
lsp_types::DocumentDiagnosticReportKind::Full(
|
||||
|
@ -74,7 +74,7 @@ error: intrinsic `copy::copy` cannot be (indirectly) exposed to stable
|
||||
LL | unsafe { copy(src, dst, count) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
|
||||
= help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)
|
||||
|
||||
error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
|
||||
--> $DIR/const-unstable-intrinsic.rs:61:9
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: link kind `link-arg` is unstable
|
||||
--> $DIR/feature-gate-link-arg-attribute.rs:1:15
|
||||
--> $DIR/feature-gate-link-arg-attribute.rs:5:15
|
||||
|
|
||||
LL | #[link(kind = "link-arg", name = "foo")]
|
||||
| ^^^^^^^^^^
|
@ -0,0 +1,2 @@
|
||||
error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed
|
||||
|
@ -1,5 +1,9 @@
|
||||
//@ revisions: in_attr in_flag
|
||||
//@[in_flag] compile-flags: -l dylib:+link-arg=foo
|
||||
|
||||
#[cfg(in_attr)]
|
||||
#[link(kind = "link-arg", name = "foo")]
|
||||
//~^ ERROR link kind `link-arg` is unstable
|
||||
//[in_attr]~^ ERROR link kind `link-arg` is unstable
|
||||
extern "C" {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: linking modifier `as-needed` is unstable
|
||||
--> $DIR/feature-gate-native_link_modifiers_as_needed.rs:1:50
|
||||
--> $DIR/feature-gate-native_link_modifiers_as_needed.rs:5:50
|
||||
|
|
||||
LL | #[link(name = "foo", kind = "dylib", modifiers = "+as-needed")]
|
||||
| ^^^^^^^^^^^^
|
@ -0,0 +1,2 @@
|
||||
error: linking modifier `as-needed` is unstable, the `-Z unstable-options` flag must also be passed to use it
|
||||
|
@ -1,5 +1,9 @@
|
||||
//@ revisions: in_attr in_flag
|
||||
//@[in_flag] compile-flags: -l dylib:+as-needed=foo
|
||||
|
||||
#[cfg(in_attr)]
|
||||
#[link(name = "foo", kind = "dylib", modifiers = "+as-needed")]
|
||||
//~^ ERROR: linking modifier `as-needed` is unstable
|
||||
//[in_attr]~^ ERROR: linking modifier `as-needed` is unstable
|
||||
extern "C" {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -0,0 +1,2 @@
|
||||
error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
|
||||
|
@ -0,0 +1,2 @@
|
||||
error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
|
||||
|
@ -0,0 +1,2 @@
|
||||
error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed
|
||||
|
11
tests/ui/native-library-link-flags/modifiers-bad.rs
Normal file
11
tests/ui/native-library-link-flags/modifiers-bad.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//@ edition: 2021
|
||||
//@ revisions: blank no-prefix prefix-only unknown
|
||||
|
||||
//@[blank] compile-flags: -l static:=foo
|
||||
//@[no-prefix] compile-flags: -l static:bundle=foo
|
||||
//@[prefix-only] compile-flags: -l static:+=foo
|
||||
//@[unknown] compile-flags: -l static:+ferris=foo
|
||||
|
||||
// Tests various illegal values for the "modifier" part of an `-l` flag.
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,2 @@
|
||||
error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed
|
||||
|
Loading…
Reference in New Issue
Block a user