Merge from rustc
This commit is contained in:
commit
f7da0212af
213 changed files with 1816 additions and 1339 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
|
@ -25,7 +25,7 @@
|
|||
[submodule "src/llvm-project"]
|
||||
path = src/llvm-project
|
||||
url = https://github.com/rust-lang/llvm-project.git
|
||||
branch = rustc/20.1-2025-02-13
|
||||
branch = rustc/20.1-2025-07-13
|
||||
shallow = true
|
||||
[submodule "src/doc/embedded-book"]
|
||||
path = src/doc/embedded-book
|
||||
|
|
|
|||
220
Cargo.lock
220
Cargo.lock
|
|
@ -351,12 +351,6 @@ version = "0.6.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.10"
|
||||
|
|
@ -636,21 +630,6 @@ dependencies = [
|
|||
"rustc-semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_test_deps"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"if_chain",
|
||||
"itertools",
|
||||
"parking_lot",
|
||||
"quote",
|
||||
"regex",
|
||||
"serde",
|
||||
"syn 2.0.104",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_utils"
|
||||
version = "0.1.90"
|
||||
|
|
@ -1331,95 +1310,6 @@ dependencies = [
|
|||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generate-copyright"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1857,12 +1747,6 @@ dependencies = [
|
|||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "if_chain"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.23"
|
||||
|
|
@ -1956,17 +1840,6 @@ dependencies = [
|
|||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipc-channel"
|
||||
version = "0.19.0"
|
||||
|
|
@ -2877,12 +2750,6 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
|
|
@ -3280,8 +3147,8 @@ dependencies = [
|
|||
"rustc_codegen_ssa",
|
||||
"rustc_driver",
|
||||
"rustc_driver_impl",
|
||||
"rustc_smir",
|
||||
"stable_mir",
|
||||
"rustc_public",
|
||||
"rustc_public_bridge",
|
||||
"tikv-jemalloc-sys",
|
||||
]
|
||||
|
||||
|
|
@ -3718,6 +3585,7 @@ dependencies = [
|
|||
"rustc_passes",
|
||||
"rustc_pattern_analysis",
|
||||
"rustc_privacy",
|
||||
"rustc_public",
|
||||
"rustc_query_system",
|
||||
"rustc_resolve",
|
||||
"rustc_session",
|
||||
|
|
@ -3727,7 +3595,6 @@ dependencies = [
|
|||
"rustc_ty_utils",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
"stable_mir",
|
||||
"tracing",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
|
@ -4424,6 +4291,36 @@ dependencies = [
|
|||
"rustc-literal-escaper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_public"
|
||||
version = "0.1.0-preview"
|
||||
dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_hir",
|
||||
"rustc_middle",
|
||||
"rustc_public_bridge",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_public_bridge"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_hir",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_query_impl"
|
||||
version = "0.0.0"
|
||||
|
|
@ -4551,20 +4448,6 @@ dependencies = [
|
|||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_smir"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_hir",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_span"
|
||||
version = "0.0.0"
|
||||
|
|
@ -5045,12 +4928,6 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
|
|
@ -5123,22 +5000,6 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "stable_mir"
|
||||
version = "0.1.0-preview"
|
||||
dependencies = [
|
||||
"rustc_abi",
|
||||
"rustc_hir",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_smir",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stacker"
|
||||
version = "0.1.21"
|
||||
|
|
@ -5491,21 +5352,6 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.46.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ members = [
|
|||
"src/tools/cargotest",
|
||||
"src/tools/clippy",
|
||||
"src/tools/clippy/clippy_dev",
|
||||
"src/tools/clippy/clippy_test_deps",
|
||||
"src/tools/collect-license-metadata",
|
||||
"src/tools/compiletest",
|
||||
"src/tools/coverage-dump",
|
||||
|
|
|
|||
|
|
@ -392,7 +392,8 @@
|
|||
# For example, to build Miri with tracing support, use `tool.miri.features = ["tracing"]`
|
||||
#
|
||||
# The default value for the `features` array is `[]`. However, please note that other flags in
|
||||
# `bootstrap.toml` might influence the features enabled for some tools.
|
||||
# `bootstrap.toml` might influence the features enabled for some tools. Also, enabling features
|
||||
# in tools which are not part of the internal "extra-features" preset might not always work.
|
||||
#build.tool.TOOL_NAME.features = [FEATURE1, FEATURE2]
|
||||
|
||||
# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose, 3 == print environment variables on each rustc invocation
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
|
|||
rustc_driver = { path = "../rustc_driver" }
|
||||
rustc_driver_impl = { path = "../rustc_driver_impl" }
|
||||
|
||||
# Make sure rustc_smir ends up in the sysroot, because this
|
||||
# crate is intended to be used by stable MIR consumers, which are not in-tree.
|
||||
rustc_smir = { path = "../rustc_smir" }
|
||||
rustc_public = { path = "../rustc_public" }
|
||||
|
||||
stable_mir = { path = "../stable_mir" }
|
||||
# Make sure rustc_public_bridge ends up in the sysroot, because this
|
||||
# crate is intended to be used by stable MIR consumers, which are not in-tree.
|
||||
rustc_public_bridge = { path = "../rustc_public_bridge" }
|
||||
# tidy-alphabetical-end
|
||||
|
||||
[dependencies.tikv-jemalloc-sys]
|
||||
|
|
|
|||
|
|
@ -217,6 +217,10 @@ impl AttributeExt for Attribute {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_automatically_derived_attr(&self) -> bool {
|
||||
self.has_name(sym::automatically_derived)
|
||||
}
|
||||
}
|
||||
|
||||
impl Attribute {
|
||||
|
|
@ -810,6 +814,7 @@ pub trait AttributeExt: Debug {
|
|||
.iter()
|
||||
.any(|kind| self.has_name(*kind))
|
||||
}
|
||||
fn is_automatically_derived_attr(&self) -> bool;
|
||||
|
||||
/// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
|
||||
/// * `///doc` returns `Some(("doc", CommentKind::Line))`.
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
||||
AsPtr(Span),
|
||||
|
||||
/// Represents `#[automatically_derived]`
|
||||
AutomaticallyDerived(Span),
|
||||
|
||||
/// Represents `#[rustc_default_body_unstable]`.
|
||||
BodyStability {
|
||||
stability: DefaultBodyStability,
|
||||
|
|
@ -294,6 +297,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[link_name]`.
|
||||
LinkName { name: Symbol, span: Span },
|
||||
|
||||
/// Represents `#[link_ordinal]`.
|
||||
LinkOrdinal { ordinal: u16, span: Span },
|
||||
|
||||
/// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
|
||||
LinkSection { name: Symbol, span: Span },
|
||||
|
||||
|
|
@ -328,6 +334,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[non_exhaustive]`
|
||||
NonExhaustive(Span),
|
||||
|
||||
/// Represents `#[omit_gdb_pretty_printer_section]`
|
||||
OmitGdbPrettyPrinterSection,
|
||||
|
||||
/// Represents `#[optimize(size|speed)]`
|
||||
Optimize(OptimizeAttr, Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ impl AttributeKind {
|
|||
AllowIncoherentImpl(..) => No,
|
||||
AllowInternalUnstable(..) => Yes,
|
||||
AsPtr(..) => Yes,
|
||||
AutomaticallyDerived(..) => Yes,
|
||||
BodyStability { .. } => No,
|
||||
CoherenceIsCore => No,
|
||||
Coinductive(..) => No,
|
||||
|
|
@ -40,6 +41,7 @@ impl AttributeKind {
|
|||
Ignore { .. } => No,
|
||||
Inline(..) => No,
|
||||
LinkName { .. } => Yes,
|
||||
LinkOrdinal { .. } => No,
|
||||
LinkSection { .. } => No,
|
||||
LoopMatch(..) => No,
|
||||
MacroTransparency(..) => Yes,
|
||||
|
|
@ -50,6 +52,7 @@ impl AttributeKind {
|
|||
NoImplicitPrelude(..) => No,
|
||||
NoMangle(..) => No,
|
||||
NonExhaustive(..) => Yes,
|
||||
OmitGdbPrettyPrinterSection => No,
|
||||
Optimize(..) => No,
|
||||
ParenSugar(..) => No,
|
||||
PassByValue(..) => Yes,
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ attr_parsing_invalid_repr_hint_no_value =
|
|||
attr_parsing_invalid_since =
|
||||
'since' must be a Rust version number, such as "1.31.0"
|
||||
|
||||
attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}`
|
||||
.note = the value may not exceed `u16::MAX`
|
||||
|
||||
attr_parsing_missing_feature =
|
||||
missing 'feature'
|
||||
|
||||
|
|
|
|||
|
|
@ -334,3 +334,11 @@ impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
|
|||
features
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct OmitGdbPrettyPrinterSectionParser;
|
||||
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for OmitGdbPrettyPrinterSectionParser {
|
||||
const PATH: &[Symbol] = &[sym::omit_gdb_pretty_printer_section];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::OmitGdbPrettyPrinterSection;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
|
||||
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
||||
use crate::attributes::{
|
||||
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
|
||||
};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::context::{AcceptContext, Stage, parse_single_integer};
|
||||
use crate::parser::ArgParser;
|
||||
use crate::session_diagnostics::NullOnLinkSection;
|
||||
use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection};
|
||||
|
||||
pub(crate) struct LinkNameParser;
|
||||
|
||||
|
|
@ -87,3 +87,36 @@ impl<S: Stage> NoArgsAttributeParser<S> for StdInternalSymbolParser {
|
|||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
|
||||
}
|
||||
|
||||
pub(crate) struct LinkOrdinalParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
|
||||
const PATH: &[Symbol] = &[sym::link_ordinal];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const TEMPLATE: AttributeTemplate = template!(List: "ordinal");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ordinal = parse_single_integer(cx, args)?;
|
||||
|
||||
// According to the table at
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
|
||||
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
||||
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
|
||||
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
|
||||
//
|
||||
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
|
||||
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
|
||||
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
|
||||
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
|
||||
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
|
||||
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
|
||||
// see earlier comment about LINK.EXE failing.)
|
||||
let Ok(ordinal) = ordinal.try_into() else {
|
||||
cx.emit_err(LinkOrdinalOutOfRange { span: cx.attr_span, ordinal });
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(LinkOrdinal { ordinal, span: cx.attr_span })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,3 +24,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for PassByValueParser {
|
|||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue;
|
||||
}
|
||||
|
||||
pub(crate) struct AutomaticallyDerivedParser;
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for AutomaticallyDerivedParser {
|
||||
const PATH: &[Symbol] = &[sym::automatically_derived];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::AutomaticallyDerived;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use rustc_ast::LitKind;
|
||||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::context::{AcceptContext, Stage, parse_single_integer};
|
||||
use crate::parser::ArgParser;
|
||||
|
||||
pub(crate) struct RustcLayoutScalarValidRangeStart;
|
||||
|
|
@ -16,8 +15,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
|
|||
const TEMPLATE: AttributeTemplate = template!(List: "start");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
parse_rustc_layout_scalar_valid_range(cx, args)
|
||||
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(n, cx.attr_span))
|
||||
parse_single_integer(cx, args)
|
||||
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,34 +29,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
|
|||
const TEMPLATE: AttributeTemplate = template!(List: "end");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
parse_rustc_layout_scalar_valid_range(cx, args)
|
||||
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(n, cx.attr_span))
|
||||
parse_single_integer(cx, args)
|
||||
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_rustc_layout_scalar_valid_range<S: Stage>(
|
||||
cx: &mut AcceptContext<'_, '_, S>,
|
||||
args: &ArgParser<'_>,
|
||||
) -> Option<Box<u128>> {
|
||||
let Some(list) = args.list() else {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return None;
|
||||
};
|
||||
let Some(single) = list.single() else {
|
||||
cx.expected_single_argument(list.span);
|
||||
return None;
|
||||
};
|
||||
let Some(lit) = single.lit() else {
|
||||
cx.expected_integer_literal(single.span());
|
||||
return None;
|
||||
};
|
||||
let LitKind::Int(num, _ty) = lit.kind else {
|
||||
cx.expected_integer_literal(single.span());
|
||||
return None;
|
||||
};
|
||||
Some(Box::new(num.0))
|
||||
}
|
||||
|
||||
pub(crate) struct RustcObjectLifetimeDefaultParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::sync::LazyLock;
|
||||
|
||||
use private::Sealed;
|
||||
use rustc_ast::{self as ast, MetaItemLit, NodeId};
|
||||
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
|
||||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_errors::{DiagCtxtHandle, Diagnostic};
|
||||
|
|
@ -16,18 +16,20 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
|||
|
||||
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
|
||||
use crate::attributes::codegen_attrs::{
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser,
|
||||
TrackCallerParser, UsedParser,
|
||||
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OmitGdbPrettyPrinterSectionParser,
|
||||
OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser,
|
||||
};
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::dummy::DummyParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::link_attrs::{
|
||||
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
|
||||
StdInternalSymbolParser,
|
||||
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
|
||||
LinkSectionParser, StdInternalSymbolParser,
|
||||
};
|
||||
use crate::attributes::lint_helpers::{
|
||||
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
|
||||
};
|
||||
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||
|
|
@ -141,6 +143,7 @@ attribute_parsers!(
|
|||
Single<IgnoreParser>,
|
||||
Single<InlineParser>,
|
||||
Single<LinkNameParser>,
|
||||
Single<LinkOrdinalParser>,
|
||||
Single<LinkSectionParser>,
|
||||
Single<MustUseParser>,
|
||||
Single<OptimizeParser>,
|
||||
|
|
@ -153,6 +156,7 @@ attribute_parsers!(
|
|||
Single<TransparencyParser>,
|
||||
Single<WithoutArgs<AllowIncoherentImplParser>>,
|
||||
Single<WithoutArgs<AsPtrParser>>,
|
||||
Single<WithoutArgs<AutomaticallyDerivedParser>>,
|
||||
Single<WithoutArgs<CoherenceIsCoreParser>>,
|
||||
Single<WithoutArgs<CoinductiveParser>>,
|
||||
Single<WithoutArgs<ColdParser>>,
|
||||
|
|
@ -171,6 +175,7 @@ attribute_parsers!(
|
|||
Single<WithoutArgs<NoImplicitPreludeParser>>,
|
||||
Single<WithoutArgs<NoMangleParser>>,
|
||||
Single<WithoutArgs<NonExhaustiveParser>>,
|
||||
Single<WithoutArgs<OmitGdbPrettyPrinterSectionParser>>,
|
||||
Single<WithoutArgs<ParenSugarParser>>,
|
||||
Single<WithoutArgs<PassByValueParser>>,
|
||||
Single<WithoutArgs<PubTransparentParser>>,
|
||||
|
|
@ -772,3 +777,32 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a single integer.
|
||||
///
|
||||
/// Used by attributes that take a single integer as argument, such as
|
||||
/// `#[link_ordinal]` and `#[rustc_layout_scalar_valid_range_start]`.
|
||||
/// `cx` is the context given to the attribute.
|
||||
/// `args` is the parser for the attribute arguments.
|
||||
pub(crate) fn parse_single_integer<S: Stage>(
|
||||
cx: &mut AcceptContext<'_, '_, S>,
|
||||
args: &ArgParser<'_>,
|
||||
) -> Option<u128> {
|
||||
let Some(list) = args.list() else {
|
||||
cx.expected_list(cx.attr_span);
|
||||
return None;
|
||||
};
|
||||
let Some(single) = list.single() else {
|
||||
cx.expected_single_argument(list.span);
|
||||
return None;
|
||||
};
|
||||
let Some(lit) = single.lit() else {
|
||||
cx.expected_integer_literal(single.span());
|
||||
return None;
|
||||
};
|
||||
let LitKind::Int(num, _ty) = lit.kind else {
|
||||
cx.expected_integer_literal(single.span());
|
||||
return None;
|
||||
};
|
||||
Some(num.0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,6 +514,15 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
|
|||
pub attr: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(attr_parsing_link_ordinal_out_of_range)]
|
||||
#[note]
|
||||
pub(crate) struct LinkOrdinalOutOfRange {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ordinal: u128,
|
||||
}
|
||||
|
||||
pub(crate) enum AttributeParseErrorReason {
|
||||
ExpectedNoArgs,
|
||||
ExpectedStringLiteral { byte_string: Option<Span> },
|
||||
|
|
|
|||
|
|
@ -159,6 +159,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
|
|||
}
|
||||
|
||||
GenericArgKind::Type(mut t1) => {
|
||||
// Scraped constraints may have had inference vars.
|
||||
t1 = self.infcx.resolve_vars_if_possible(t1);
|
||||
|
||||
// Normalize the type we receive from a `TypeOutlives` obligation
|
||||
// in the new trait solver.
|
||||
if infcx.next_trait_solver() {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
// .debug_gdb_scripts binary section.
|
||||
|
||||
use rustc_ast::attr;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
|
||||
use rustc_session::config::{CrateType, DebugInfo};
|
||||
use rustc_span::sym;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::common::CodegenCx;
|
||||
|
|
@ -87,7 +86,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
|
|||
|
||||
pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
|
||||
let omit_gdb_pretty_printer_section =
|
||||
attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section);
|
||||
find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection);
|
||||
|
||||
// To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
|
||||
// ODR violations at link time, this section will not be emitted for rlibs since
|
||||
|
|
|
|||
|
|
@ -80,9 +80,6 @@ codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extensio
|
|||
|
||||
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
|
||||
|
||||
codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
|
||||
.note = an unsuffixed integer value, e.g., `1`, is expected
|
||||
|
||||
codegen_ssa_incorrect_cgu_reuse_type =
|
||||
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
|
||||
[one] {"at least "}
|
||||
|
|
@ -93,9 +90,6 @@ codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and i
|
|||
|
||||
codegen_ssa_invalid_instruction_set = invalid instruction set specified
|
||||
|
||||
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
|
||||
.note = the attribute requires exactly one argument
|
||||
|
||||
codegen_ssa_invalid_literal_value = invalid literal value
|
||||
.label = value must be an integer between `0` and `255`
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
|
||||
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
|
||||
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
|
||||
AttributeKind::LinkOrdinal { ordinal, span } => {
|
||||
codegen_fn_attrs.link_ordinal = Some(*ordinal);
|
||||
link_ordinal_span = Some(*span);
|
||||
}
|
||||
AttributeKind::LinkSection { name, .. } => {
|
||||
codegen_fn_attrs.link_section = Some(*name)
|
||||
}
|
||||
|
|
@ -250,12 +254,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
}
|
||||
}
|
||||
sym::link_ordinal => {
|
||||
link_ordinal_span = Some(attr.span());
|
||||
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
|
||||
codegen_fn_attrs.link_ordinal = ordinal;
|
||||
}
|
||||
}
|
||||
sym::no_sanitize => {
|
||||
no_sanitize_span = Some(attr.span());
|
||||
if let Some(list) = attr.meta_item_list() {
|
||||
|
|
@ -568,45 +566,6 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
|
|||
tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment
|
||||
}
|
||||
|
||||
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
|
||||
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
|
||||
let meta_item_list = attr.meta_item_list()?;
|
||||
let [sole_meta_list] = &meta_item_list[..] else {
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span() });
|
||||
return None;
|
||||
};
|
||||
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
|
||||
sole_meta_list.lit()
|
||||
{
|
||||
// According to the table at
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
|
||||
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
|
||||
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
|
||||
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
|
||||
//
|
||||
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
|
||||
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
|
||||
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
|
||||
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
|
||||
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
|
||||
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
|
||||
// see earlier comment about LINK.EXE failing.)
|
||||
if *ordinal <= u16::MAX as u128 {
|
||||
Some(ordinal.get() as u16)
|
||||
} else {
|
||||
let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
|
||||
tcx.dcx()
|
||||
.struct_span_err(attr.span(), msg)
|
||||
.with_note("the value may not exceed `u16::MAX`")
|
||||
.emit();
|
||||
None
|
||||
}
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span() });
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn check_link_name_xor_ordinal(
|
||||
tcx: TyCtxt<'_>,
|
||||
codegen_fn_attrs: &CodegenFnAttrs,
|
||||
|
|
|
|||
|
|
@ -1108,22 +1108,6 @@ pub(crate) struct InvalidNoSanitize {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_invalid_link_ordinal_nargs)]
|
||||
#[note]
|
||||
pub(crate) struct InvalidLinkOrdinalNargs {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_illegal_link_ordinal_format)]
|
||||
#[note]
|
||||
pub(crate) struct InvalidLinkOrdinalFormat {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_target_feature_safe_trait)]
|
||||
pub(crate) struct TargetFeatureSafeTrait {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ rustc_parse = { path = "../rustc_parse" }
|
|||
rustc_passes = { path = "../rustc_passes" }
|
||||
rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
|
||||
rustc_privacy = { path = "../rustc_privacy" }
|
||||
rustc_public = { path = "../rustc_public", features = ["rustc_internal"] }
|
||||
rustc_query_system = { path = "../rustc_query_system" }
|
||||
rustc_resolve = { path = "../rustc_resolve" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
|
|
@ -50,7 +51,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
|
|||
rustc_ty_utils = { path = "../rustc_ty_utils" }
|
||||
serde_json = "1.0.59"
|
||||
shlex = "1.0"
|
||||
stable_mir = { path = "../stable_mir", features = ["rustc_internal"] }
|
||||
tracing = { version = "0.1.35" }
|
||||
# tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ use rustc_middle::bug;
|
|||
use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_mir_build::thir::print::{thir_flat, thir_tree};
|
||||
use rustc_public::rustc_internal::pretty::write_smir_pretty;
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
|
||||
use rustc_span::{FileName, Ident};
|
||||
use stable_mir::rustc_internal::pretty::write_smir_pretty;
|
||||
use tracing::debug;
|
||||
use {rustc_ast as ast, rustc_hir_pretty as pprust_hir};
|
||||
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ declare_features! (
|
|||
/// Be more precise when looking for live drops in a const context.
|
||||
(unstable, const_precise_live_drops, "1.46.0", Some(73255)),
|
||||
/// Allows `impl const Trait for T` syntax.
|
||||
(unstable, const_trait_impl, "1.42.0", Some(67792)),
|
||||
(unstable, const_trait_impl, "1.42.0", Some(143874)),
|
||||
/// Allows the `?` operator in const contexts.
|
||||
(unstable, const_try, "1.56.0", Some(74935)),
|
||||
/// Allows use of contracts attributes.
|
||||
|
|
|
|||
|
|
@ -1304,6 +1304,7 @@ impl AttributeExt for Attribute {
|
|||
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
|
||||
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
|
||||
Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span,
|
||||
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
|
||||
}
|
||||
}
|
||||
|
|
@ -1334,6 +1335,11 @@ impl AttributeExt for Attribute {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_automatically_derived_attr(&self) -> bool {
|
||||
matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
|
||||
match &self {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use std::iter;
|
|||
use rustc_index::{Idx, IndexVec};
|
||||
use rustc_middle::arena::ArenaAllocatable;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt, TypeFoldable};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
@ -23,7 +22,9 @@ use crate::infer::canonical::{
|
|||
QueryRegionConstraints, QueryResponse,
|
||||
};
|
||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin};
|
||||
use crate::infer::{
|
||||
DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin, TypeOutlivesConstraint,
|
||||
};
|
||||
use crate::traits::query::NoSolution;
|
||||
use crate::traits::{ObligationCause, PredicateObligations, ScrubbedTraitError, TraitEngine};
|
||||
|
||||
|
|
@ -117,13 +118,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
let region_obligations = self.take_registered_region_obligations();
|
||||
debug!(?region_obligations);
|
||||
let region_constraints = self.with_region_constraints(|region_constraints| {
|
||||
make_query_region_constraints(
|
||||
tcx,
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
|
||||
region_constraints,
|
||||
)
|
||||
make_query_region_constraints(tcx, region_obligations, region_constraints)
|
||||
});
|
||||
debug!(?region_constraints);
|
||||
|
||||
|
|
@ -570,7 +565,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// creates query region constraints.
|
||||
pub fn make_query_region_constraints<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
|
||||
outlives_obligations: Vec<TypeOutlivesConstraint<'tcx>>,
|
||||
region_constraints: &RegionConstraintData<'tcx>,
|
||||
) -> QueryRegionConstraints<'tcx> {
|
||||
let RegionConstraintData { constraints, verifys } = region_constraints;
|
||||
|
|
@ -599,8 +594,11 @@ pub fn make_query_region_constraints<'tcx>(
|
|||
};
|
||||
(constraint, origin.to_constraint_category())
|
||||
})
|
||||
.chain(outlives_obligations.map(|(ty, r, constraint_category)| {
|
||||
(ty::OutlivesPredicate(ty.into(), r), constraint_category)
|
||||
.chain(outlives_obligations.into_iter().map(|obl| {
|
||||
(
|
||||
ty::OutlivesPredicate(obl.sup_type.into(), obl.sub_region),
|
||||
obl.origin.to_constraint_category(),
|
||||
)
|
||||
}))
|
||||
.collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
/// Trait queries just want to pass back type obligations "as is"
|
||||
pub fn take_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
|
||||
assert!(!self.in_snapshot(), "cannot take registered region obligations in a snapshot");
|
||||
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::assert_matches::assert_matches;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
|
||||
|
|
@ -73,7 +74,8 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
|
|||
}
|
||||
UndoLog::ProjectionCache(undo) => self.projection_cache.reverse(undo),
|
||||
UndoLog::PushTypeOutlivesConstraint => {
|
||||
self.region_obligations.pop();
|
||||
let popped = self.region_obligations.pop();
|
||||
assert_matches!(popped, Some(_), "pushed region constraint but could not pop it");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -62,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
|
|||
let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return };
|
||||
let assoc = cx.tcx.associated_item(impl_item.owner_id);
|
||||
let parent = assoc.container_id(cx.tcx);
|
||||
if cx.tcx.has_attr(parent, sym::automatically_derived) {
|
||||
if find_attr!(cx.tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) {
|
||||
// We don't care about what `#[derive(Default)]` produces in this lint.
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||
) {
|
||||
let sess = self.sess;
|
||||
for (attr_index, attr) in attrs.iter().enumerate() {
|
||||
if attr.has_name(sym::automatically_derived) {
|
||||
if attr.is_automatically_derived_attr() {
|
||||
self.insert(
|
||||
LintId::of(SINGLE_USE_LIFETIMES),
|
||||
LevelAndSource {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::CRATE_NODE_ID;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::query::LocalCrate;
|
||||
|
|
@ -496,14 +497,9 @@ impl<'tcx> Collector<'tcx> {
|
|||
}
|
||||
_ => {
|
||||
for &child_item in foreign_items {
|
||||
if self.tcx.def_kind(child_item).has_codegen_attrs()
|
||||
&& self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some()
|
||||
if let Some(span) = find_attr!(self.tcx.get_all_attrs(child_item), AttributeKind::LinkOrdinal {span, ..} => *span)
|
||||
{
|
||||
let link_ordinal_attr =
|
||||
self.tcx.get_attr(child_item, sym::link_ordinal).unwrap();
|
||||
sess.dcx().emit_err(errors::LinkOrdinalRawDylib {
|
||||
span: link_ordinal_attr.span(),
|
||||
});
|
||||
sess.dcx().emit_err(errors::LinkOrdinalRawDylib { span });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, V
|
|||
use rustc_ast::expand::StrippedCfgItem;
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
|
||||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
|
|
@ -2035,7 +2035,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
/// Check if the given `DefId` is `#\[automatically_derived\]`.
|
||||
pub fn is_automatically_derived(self, def_id: DefId) -> bool {
|
||||
self.has_attr(def_id, sym::automatically_derived)
|
||||
find_attr!(self.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..))
|
||||
}
|
||||
|
||||
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use core::ops::ControlFlow;
|
|||
|
||||
use rustc_abi::{FieldIdx, VariantIdx};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Diag;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -15,7 +16,7 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_middle::{mir, span_bug};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{DUMMY_SP, Span, sym};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
|
@ -495,7 +496,8 @@ fn type_has_partial_eq_impl<'tcx>(
|
|||
let mut structural_peq = false;
|
||||
let mut impl_def_id = None;
|
||||
for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
|
||||
automatically_derived = tcx.has_attr(def_id, sym::automatically_derived);
|
||||
automatically_derived =
|
||||
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..));
|
||||
impl_def_id = Some(def_id);
|
||||
}
|
||||
for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
|
||||
|
|
|
|||
|
|
@ -305,17 +305,20 @@ pub fn check_builtin_meta_item(
|
|||
| sym::naked
|
||||
| sym::no_mangle
|
||||
| sym::non_exhaustive
|
||||
| sym::omit_gdb_pretty_printer_section
|
||||
| sym::path
|
||||
| sym::ignore
|
||||
| sym::must_use
|
||||
| sym::track_caller
|
||||
| sym::link_name
|
||||
| sym::link_ordinal
|
||||
| sym::export_name
|
||||
| sym::rustc_macro_transparency
|
||||
| sym::link_section
|
||||
| sym::rustc_layout_scalar_valid_range_start
|
||||
| sym::rustc_layout_scalar_valid_range_end
|
||||
| sym::no_implicit_prelude
|
||||
| sym::automatically_derived
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ passes_align_attr_application =
|
|||
`#[align(...)]` should be applied to a function item
|
||||
.label = not a function item
|
||||
|
||||
passes_align_on_fields =
|
||||
attribute should be applied to a function or method
|
||||
.warn = {-passes_previously_accepted}
|
||||
|
||||
passes_align_should_be_repr_align =
|
||||
`#[align(...)]` is not supported on {$item} items
|
||||
.suggestion = use `#[repr(align(...))]` instead
|
||||
|
|
@ -700,7 +704,7 @@ passes_trait_impl_const_stability_mismatch_trait_unstable = ...but the trait is
|
|||
|
||||
passes_trait_impl_const_stable =
|
||||
trait implementations cannot be const stable yet
|
||||
.note = see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
.note = see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
|
||||
|
||||
passes_transparent_incompatible =
|
||||
transparent {$target} cannot have other repr hints
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
|
|||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::errors::AlignOnFields;
|
||||
use crate::{errors, fluent_generated as fluent};
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
|
@ -154,6 +155,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
|
||||
self.check_confusables(*first_span, target);
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::AutomaticallyDerived(attr_span)) => self
|
||||
.check_generic_attr(
|
||||
hir_id,
|
||||
sym::automatically_derived,
|
||||
*attr_span,
|
||||
target,
|
||||
Target::Impl,
|
||||
),
|
||||
Attribute::Parsed(
|
||||
AttributeKind::Stability { span, .. }
|
||||
| AttributeKind::ConstStability { span, .. },
|
||||
|
|
@ -199,8 +208,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::ExportName { span: attr_span, .. }) => {
|
||||
self.check_export_name(hir_id, *attr_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => {
|
||||
self.check_align(span, target, *align, *repr_span)
|
||||
Attribute::Parsed(AttributeKind::Align { align, span: attr_span }) => {
|
||||
self.check_align(span, hir_id, target, *align, *attr_span)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::LinkSection { span: attr_span, .. }) => {
|
||||
self.check_link_section(hir_id, *attr_span, span, target)
|
||||
|
|
@ -242,7 +251,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
AttributeKind::BodyStability { .. }
|
||||
| AttributeKind::ConstStabilityIndirect
|
||||
| AttributeKind::MacroTransparency(_)
|
||||
| AttributeKind::Dummy,
|
||||
| AttributeKind::Dummy
|
||||
| AttributeKind::OmitGdbPrettyPrinterSection,
|
||||
) => { /* do nothing */ }
|
||||
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
|
||||
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
|
||||
|
|
@ -250,6 +260,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
Attribute::Parsed(AttributeKind::LinkName { span: attr_span, name }) => {
|
||||
self.check_link_name(hir_id, *attr_span, *name, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::LinkOrdinal { span: attr_span, .. }) => {
|
||||
self.check_link_ordinal(*attr_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
|
||||
self.check_may_dangle(hir_id, *attr_span)
|
||||
}
|
||||
|
|
@ -327,7 +340,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::rustc_has_incoherent_inherent_impls, ..] => {
|
||||
self.check_has_incoherent_inherent_impls(attr, span, target)
|
||||
}
|
||||
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
|
||||
[sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target),
|
||||
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
|
||||
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
||||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
self.check_macro_use(hir_id, attr, target)
|
||||
|
|
@ -337,9 +351,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
[sym::should_panic, ..] => {
|
||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
|
||||
}
|
||||
[sym::automatically_derived, ..] => {
|
||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl)
|
||||
}
|
||||
[sym::proc_macro, ..] => {
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike)
|
||||
}
|
||||
|
|
@ -371,7 +382,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// need to be fixed
|
||||
| sym::cfi_encoding // FIXME(cfi_encoding)
|
||||
| sym::pointee // FIXME(derive_coerce_pointee)
|
||||
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
|
||||
| sym::instruction_set // broken on stable!!!
|
||||
| sym::windows_subsystem // broken on stable!!!
|
||||
| sym::patchable_function_entry // FIXME(patchable_function_entry)
|
||||
|
|
@ -1944,22 +1954,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
|
||||
/// Checks if the `#[align]` attributes on `item` are valid.
|
||||
fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
|
||||
fn check_align(
|
||||
&self,
|
||||
span: Span,
|
||||
hir_id: HirId,
|
||||
target: Target,
|
||||
align: Align,
|
||||
attr_span: Span,
|
||||
) {
|
||||
match target {
|
||||
Target::Fn | Target::Method(_) | Target::ForeignFn => {}
|
||||
Target::Field => {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr_span,
|
||||
AlignOnFields { span },
|
||||
);
|
||||
}
|
||||
Target::Struct | Target::Union | Target::Enum => {
|
||||
self.dcx().emit_err(errors::AlignShouldBeReprAlign {
|
||||
span: repr_span,
|
||||
span: attr_span,
|
||||
item: target.name(),
|
||||
align_bytes: align.bytes(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::AlignAttrApplication { hint_span: repr_span, span });
|
||||
self.dcx().emit_err(errors::AlignAttrApplication { hint_span: attr_span, span });
|
||||
}
|
||||
}
|
||||
|
||||
self.check_align_value(align, repr_span);
|
||||
self.check_align_value(align, attr_span);
|
||||
}
|
||||
|
||||
/// Checks if the `#[repr]` attributes on `item` are valid.
|
||||
|
|
@ -2260,11 +2285,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) {
|
||||
fn check_link_ordinal(&self, attr_span: Span, _span: Span, target: Target) {
|
||||
match target {
|
||||
Target::ForeignFn | Target::ForeignStatic => {}
|
||||
_ => {
|
||||
self.dcx().emit_err(errors::LinkOrdinal { attr_span: attr.span() });
|
||||
self.dcx().emit_err(errors::LinkOrdinal { attr_span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2826,7 +2851,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||
// resolution for the attribute macro error.
|
||||
const ATTRS_TO_CHECK: &[Symbol] = &[
|
||||
sym::macro_export,
|
||||
sym::automatically_derived,
|
||||
sym::rustc_main,
|
||||
sym::derive,
|
||||
sym::test,
|
||||
|
|
@ -2849,6 +2873,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||
(*first_attr_span, sym::repr)
|
||||
} else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
|
||||
(*span, sym::path)
|
||||
} else if let Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) = attr {
|
||||
(*span, sym::automatically_derived)
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -604,6 +604,14 @@ pub(crate) struct NoMangle {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_align_on_fields)]
|
||||
#[warning]
|
||||
pub(crate) struct AlignOnFields {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_repr_conflicting, code = E0566)]
|
||||
pub(crate) struct ReprConflicting {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ use rustc_middle::query::Providers;
|
|||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::{BytePos, Span, Symbol, sym};
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use self::LiveNodeKind::*;
|
||||
|
|
@ -140,7 +140,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
// Don't run unused pass for #[derive()]
|
||||
let parent = tcx.local_parent(def_id);
|
||||
if let DefKind::Impl { .. } = tcx.def_kind(parent)
|
||||
&& tcx.has_attr(parent, sym::automatically_derived)
|
||||
&& find_attr!(tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "stable_mir"
|
||||
name = "rustc_public"
|
||||
version = "0.1.0-preview"
|
||||
edition = "2024"
|
||||
|
||||
|
|
@ -8,8 +8,8 @@ edition = "2024"
|
|||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_public_bridge = { path = "../rustc_public_bridge" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_smir = { path = "../rustc_smir" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
scoped-tls = "1.0"
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
//!
|
||||
//! This module is responsible for constructing stable components.
|
||||
//! All operations requiring rustc queries must be delegated
|
||||
//! to `rustc_smir::alloc` to maintain stability guarantees.
|
||||
//! to `rustc_public_bridge::alloc` to maintain stability guarantees.
|
||||
|
||||
use rustc_abi::Align;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
use rustc_middle::mir::interpret::AllocRange;
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_smir::{Tables, alloc};
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::{Tables, alloc};
|
||||
|
||||
use super::Error;
|
||||
use super::compiler_interface::BridgeTys;
|
||||
|
|
@ -59,7 +59,7 @@ pub(crate) fn try_new_allocation<'tcx>(
|
|||
}
|
||||
ConstValue::Indirect { alloc_id, offset } => {
|
||||
let alloc = alloc::try_new_indirect(alloc_id, cx);
|
||||
use rustc_smir::context::SmirAllocRange;
|
||||
use rustc_public_bridge::context::SmirAllocRange;
|
||||
Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx))
|
||||
}
|
||||
}
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_smir::{Bridge, SmirContainer};
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::{Bridge, SmirContainer};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
|
||||
|
|
@ -68,7 +68,7 @@ impl Bridge for BridgeTys {
|
|||
|
||||
/// Stable public API for querying compiler information.
|
||||
///
|
||||
/// All queries are delegated to [`rustc_smir::context::SmirCtxt`] that provides
|
||||
/// All queries are delegated to [`rustc_public_bridge::context::SmirCtxt`] that provides
|
||||
/// similar APIs but based on internal rustc constructs.
|
||||
///
|
||||
/// Do not use this directly. This is currently used in the macro expansion.
|
||||
|
|
@ -567,7 +567,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
|
|||
DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
|
||||
DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)),
|
||||
DefKind::ForeignTy => {
|
||||
use rustc_smir::context::SmirTy;
|
||||
use rustc_public_bridge::context::SmirTy;
|
||||
ForeignItemKind::Type(tables.intern_ty(cx.new_foreign(def_id)))
|
||||
}
|
||||
def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::{fmt, io};
|
||||
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
|
||||
macro_rules! error {
|
||||
($fmt: literal $(,)?) => { Error(format!($fmt)) };
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
//! The WIP stable interface to rustc internals.
|
||||
//! The WIP public interface to rustc internals.
|
||||
//!
|
||||
//! For more information see <https://github.com/rust-lang/project-stable-mir>
|
||||
//!
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
use std::fmt::Debug;
|
||||
use std::{fmt, io};
|
||||
|
||||
pub(crate) use rustc_smir::IndexedVal;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
pub(crate) use rustc_public_bridge::IndexedVal;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
/// Export the rustc_internal APIs. Note that this module has no stability
|
||||
/// guarantees and it is not taken into account for semver.
|
||||
#[cfg(feature = "rustc_internal")]
|
||||
|
|
@ -244,7 +244,7 @@ pub fn opaque<T: Debug>(value: &T) -> Opaque {
|
|||
|
||||
macro_rules! bridge_impl {
|
||||
($name: ident, $ty: ty) => {
|
||||
impl rustc_smir::bridge::$name<compiler_interface::BridgeTys> for $ty {
|
||||
impl rustc_public_bridge::bridge::$name<compiler_interface::BridgeTys> for $ty {
|
||||
fn new(def: crate::DefId) -> Self {
|
||||
Self(def)
|
||||
}
|
||||
|
|
@ -273,13 +273,15 @@ bridge_impl!(AssocDef, crate::ty::AssocDef);
|
|||
bridge_impl!(OpaqueDef, crate::ty::OpaqueDef);
|
||||
bridge_impl!(StaticDef, crate::mir::mono::StaticDef);
|
||||
|
||||
impl rustc_smir::bridge::Prov<compiler_interface::BridgeTys> for crate::ty::Prov {
|
||||
impl rustc_public_bridge::bridge::Prov<compiler_interface::BridgeTys> for crate::ty::Prov {
|
||||
fn new(aid: crate::mir::alloc::AllocId) -> Self {
|
||||
Self(aid)
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_smir::bridge::Allocation<compiler_interface::BridgeTys> for crate::ty::Allocation {
|
||||
impl rustc_public_bridge::bridge::Allocation<compiler_interface::BridgeTys>
|
||||
for crate::ty::Allocation
|
||||
{
|
||||
fn new<'tcx>(
|
||||
bytes: Vec<Option<u8>>,
|
||||
ptrs: Vec<(usize, rustc_middle::mir::interpret::AllocId)>,
|
||||
|
|
@ -674,7 +674,7 @@ pub enum AggregateKind {
|
|||
Tuple,
|
||||
Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
|
||||
Closure(ClosureDef, GenericArgs),
|
||||
// FIXME(stable_mir): Movability here is redundant
|
||||
// FIXME(rustc_public): Movability here is redundant
|
||||
Coroutine(CoroutineDef, GenericArgs, Movability),
|
||||
CoroutineClosure(CoroutineClosureDef, GenericArgs),
|
||||
RawPtr(Ty, Mutability),
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt::{Debug, Formatter};
|
||||
use std::io;
|
||||
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::abi::FnAbi;
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_smir::{Bridge, SmirContainer, Tables};
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_public_bridge::{Bridge, SmirContainer, Tables};
|
||||
use rustc_span::def_id::CrateNum;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
|
||||
|
|
@ -105,11 +105,11 @@ where
|
|||
/// # extern crate rustc_interface;
|
||||
/// # extern crate rustc_middle;
|
||||
/// # #[macro_use]
|
||||
/// # extern crate stable_mir;
|
||||
/// # extern crate rustc_public;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # use std::ops::ControlFlow;
|
||||
/// # use stable_mir::CompilerError;
|
||||
/// # use rustc_public::CompilerError;
|
||||
/// fn analyze_code() -> ControlFlow<(), ()> {
|
||||
/// // Your code goes in here.
|
||||
/// # ControlFlow::Continue(())
|
||||
|
|
@ -125,11 +125,11 @@ where
|
|||
/// # extern crate rustc_interface;
|
||||
/// # extern crate rustc_middle;
|
||||
/// # #[macro_use]
|
||||
/// # extern crate stable_mir;
|
||||
/// # extern crate rustc_public;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # use std::ops::ControlFlow;
|
||||
/// # use stable_mir::CompilerError;
|
||||
/// # use rustc_public::CompilerError;
|
||||
/// fn analyze_code(extra_args: Vec<String>) -> ControlFlow<(), ()> {
|
||||
/// # let _ = extra_args;
|
||||
/// // Your code goes in here.
|
||||
|
|
@ -187,8 +187,8 @@ macro_rules! run_driver {
|
|||
use rustc_driver::{Callbacks, Compilation, run_compiler};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_interface::interface;
|
||||
use stable_mir::rustc_internal;
|
||||
use stable_mir::CompilerError;
|
||||
use rustc_public::rustc_internal;
|
||||
use rustc_public::CompilerError;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
pub struct StableMir<B = (), C = (), F = fn($(optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C>>
|
||||
|
|
@ -560,7 +560,7 @@ pub enum RigidTy {
|
|||
FnDef(FnDef, GenericArgs),
|
||||
FnPtr(PolyFnSig),
|
||||
Closure(ClosureDef, GenericArgs),
|
||||
// FIXME(stable_mir): Movability here is redundant
|
||||
// FIXME(rustc_public): Movability here is redundant
|
||||
Coroutine(CoroutineDef, GenericArgs, Movability),
|
||||
CoroutineClosure(CoroutineClosureDef, GenericArgs),
|
||||
Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
//! This module will only include a few constructs to allow users to invoke internal rustc APIs
|
||||
//! due to incomplete stable coverage.
|
||||
|
||||
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
|
||||
// Prefer importing rustc_public over internal rustc constructs to make this file more readable.
|
||||
|
||||
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_public_bridge::Tables;
|
||||
|
||||
use crate::abi::Layout;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
//! This module holds the logic to convert rustc internal ADTs into stable mir ADTs.
|
||||
//!
|
||||
//! The conversion from stable to internal is not meant to be complete,
|
||||
//! and it should be added as when needed to be passed as input to rustc_smir functions.
|
||||
//! and it should be added as when needed to be passed as input to rustc_public_bridge functions.
|
||||
//!
|
||||
//! For contributors, please make sure to avoid calling rustc's internal functions and queries.
|
||||
//! These should be done via `rustc_smir` APIs, but it's possible to access ADT fields directly.
|
||||
//! These should be done via `rustc_public_bridge` APIs, but it's possible to access ADT fields directly.
|
||||
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
|
||||
use super::Stable;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
|
||||
use rustc_middle::ty;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
use rustc_target::callconv;
|
||||
|
||||
use crate::abi::{
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::{bug, mir};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::bridge::SmirError;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::bridge::SmirError;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
use crate::mir::alloc::GlobalAlloc;
|
||||
|
|
@ -821,7 +821,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
|
|||
tables: &mut Tables<'cx, BridgeTys>,
|
||||
cx: &SmirCtxt<'cx, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use rustc_smir::context::SmirAllocRange;
|
||||
use rustc_public_bridge::context::SmirAllocRange;
|
||||
alloc::allocation_filter(
|
||||
self,
|
||||
cx.alloc_range(rustc_abi::Size::ZERO, self.size()),
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
//! Conversion of internal Rust compiler items to stable ones.
|
||||
|
||||
use rustc_abi::FieldIdx;
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
|
||||
use super::Stable;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::{bug, mir, ty};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
|
||||
use crate::alloc;
|
||||
use crate::compiler_interface::BridgeTys;
|
||||
|
|
@ -9,8 +9,8 @@ use std::marker::PointeeSized;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::ty::{List, Ty, TyCtxt};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_smir::Tables;
|
||||
use rustc_smir::context::SmirCtxt;
|
||||
use rustc_public_bridge::Tables;
|
||||
use rustc_public_bridge::context::SmirCtxt;
|
||||
|
||||
use super::compiler_interface::BridgeTys;
|
||||
use crate::{CtorKind, ItemKind};
|
||||
|
|
@ -21,7 +21,7 @@ mod internal_cx;
|
|||
/// Trait that defines the methods that are fine to call from [`RustcInternal`].
|
||||
///
|
||||
/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals
|
||||
/// should go through [`rustc_smir::context::SmirCtxt`].
|
||||
/// should go through [`rustc_public_bridge::context::SmirCtxt`].
|
||||
pub trait InternalCx<'tcx>: Copy + Clone {
|
||||
fn tcx(self) -> TyCtxt<'tcx>;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "rustc_smir"
|
||||
name = "rustc_public_bridge"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
//! Internal memory allocator implementation for StableMIR.
|
||||
//!
|
||||
//! This module handles all direct interactions with rustc queries and performs
|
||||
//! the actual memory allocations. The stable interface in `stable_mir::alloc`
|
||||
//! the actual memory allocations. The stable interface in `rustc_public::alloc`
|
||||
//! delegates all query-related operations to this implementation.
|
||||
|
||||
use rustc_abi::{Size, TyAndLayout};
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
//! Defines a set of traits that is used for abstracting
|
||||
//! stable_mir's components that are needed in rustc_smir.
|
||||
//! rustc_public's components that are needed in rustc_public_bridge.
|
||||
//!
|
||||
//! These traits are really useful when programming
|
||||
//! in stable_mir-agnostic settings.
|
||||
//! in rustc_public-agnostic settings.
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
//! This crate is responsible for building Stable MIR components from internal components.
|
||||
//!
|
||||
//! This crate is not intended to be invoked directly by users.
|
||||
//! This crate is the public API of rustc that will be invoked by the `stable_mir` crate.
|
||||
//! This crate is the public API of rustc that will be invoked by the `rustc_public` crate.
|
||||
//!
|
||||
//! For more information see <https://github.com/rust-lang/project-stable-mir>
|
||||
//!
|
||||
|
|
@ -42,7 +42,7 @@ pub mod bridge;
|
|||
mod builder;
|
||||
pub mod context;
|
||||
|
||||
#[deprecated(note = "please use `stable_mir::rustc_internal` instead")]
|
||||
#[deprecated(note = "please use `rustc_public::rustc_internal` instead")]
|
||||
pub mod rustc_internal {}
|
||||
|
||||
/// A container which is used for TLS.
|
||||
|
|
@ -211,7 +211,7 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> {
|
|||
}
|
||||
|
||||
/// A trait defining types that are used to emulate StableMIR components, which is really
|
||||
/// useful when programming in stable_mir-agnostic settings.
|
||||
/// useful when programming in rustc_public-agnostic settings.
|
||||
pub trait Bridge: Sized {
|
||||
type DefId: Copy + Debug + PartialEq + IndexedVal;
|
||||
type AllocId: Copy + Debug + PartialEq + IndexedVal;
|
||||
|
|
@ -213,13 +213,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
// inside of a `probe` whenever we have multiple choices inside of the solver.
|
||||
let region_obligations = self.0.inner.borrow().region_obligations().to_owned();
|
||||
let region_constraints = self.0.with_region_constraints(|region_constraints| {
|
||||
make_query_region_constraints(
|
||||
self.tcx,
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
|
||||
region_constraints,
|
||||
)
|
||||
make_query_region_constraints(self.tcx, region_obligations, region_constraints)
|
||||
});
|
||||
|
||||
let mut seen = FxHashSet::default();
|
||||
|
|
|
|||
|
|
@ -103,10 +103,7 @@ where
|
|||
let region_constraint_data = infcx.take_and_reset_region_constraints();
|
||||
let region_constraints = query_response::make_query_region_constraints(
|
||||
infcx.tcx,
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category()))
|
||||
.map(|(ty, r, cc)| (infcx.resolve_vars_if_possible(ty), r, cc)),
|
||||
region_obligations,
|
||||
®ion_constraint_data,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -2611,7 +2611,7 @@ impl_eq! { Cow<'a, str>, &'b str }
|
|||
impl_eq! { Cow<'a, str>, String }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl const Default for String {
|
||||
/// Creates an empty `String`.
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -3895,7 +3895,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T> const Default for Vec<T> {
|
||||
/// Creates an empty `Vec<T>`.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ impl<T: Copy> Clone for Cell<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T: ~const Default> const Default for Cell<T> {
|
||||
/// Creates a `Cell<T>`, with the `Default` value for T.
|
||||
#[inline]
|
||||
|
|
@ -1324,7 +1324,7 @@ impl<T: Clone> Clone for RefCell<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T: ~const Default> const Default for RefCell<T> {
|
||||
/// Creates a `RefCell<T>`, with the `Default` value for T.
|
||||
#[inline]
|
||||
|
|
@ -2332,7 +2332,7 @@ impl<T: ?Sized> UnsafeCell<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T: ~const Default> const Default for UnsafeCell<T> {
|
||||
/// Creates an `UnsafeCell`, with the `Default` value for T.
|
||||
fn default() -> UnsafeCell<T> {
|
||||
|
|
@ -2437,7 +2437,7 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
|
|||
}
|
||||
|
||||
#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T: ~const Default> const Default for SyncUnsafeCell<T> {
|
||||
/// Creates an `SyncUnsafeCell`, with the `Default` value for T.
|
||||
fn default() -> SyncUnsafeCell<T> {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ use crate::ascii::Char as AsciiChar;
|
|||
#[rustc_diagnostic_item = "Default"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
pub trait Default: Sized {
|
||||
/// Returns the "default value" for a type.
|
||||
///
|
||||
|
|
@ -151,7 +151,7 @@ pub macro Default($item:item) {
|
|||
macro_rules! default_impl {
|
||||
($t:ty, $v:expr, $doc:tt) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl const Default for $t {
|
||||
#[inline(always)]
|
||||
#[doc = $doc]
|
||||
|
|
|
|||
|
|
@ -910,7 +910,7 @@ pub const unsafe fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
|
|||
/// # Safety
|
||||
///
|
||||
/// - `index < PtrMetadata(slice_ptr)`, so the indexing is in-bounds for the slice
|
||||
/// - the resulting offsetting is in-bounds of the allocated object, which is
|
||||
/// - the resulting offsetting is in-bounds of the allocation, which is
|
||||
/// always the case for references, but needs to be upheld manually for pointers
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
|
|
|
|||
|
|
@ -69,6 +69,23 @@ impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new `BorrowedBuf` from a cursor.
|
||||
///
|
||||
/// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative.
|
||||
impl<'data> From<BorrowedCursor<'data>> for BorrowedBuf<'data> {
|
||||
#[inline]
|
||||
fn from(mut buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> {
|
||||
let init = buf.init_mut().len();
|
||||
BorrowedBuf {
|
||||
// SAFETY: no initialized byte is ever uninitialized as per
|
||||
// `BorrowedBuf`'s invariant
|
||||
buf: unsafe { buf.buf.buf.get_unchecked_mut(buf.buf.filled..) },
|
||||
filled: 0,
|
||||
init,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'data> BorrowedBuf<'data> {
|
||||
/// Returns the total capacity of the buffer.
|
||||
#[inline]
|
||||
|
|
@ -353,4 +370,38 @@ impl<'a> BorrowedCursor<'a> {
|
|||
}
|
||||
self.buf.filled += buf.len();
|
||||
}
|
||||
|
||||
/// Runs the given closure with a `BorrowedBuf` containing the unfilled part
|
||||
/// of the cursor.
|
||||
///
|
||||
/// This enables inspecting what was written to the cursor.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `BorrowedBuf` given to the closure is replaced by another
|
||||
/// one.
|
||||
pub fn with_unfilled_buf<T>(&mut self, f: impl FnOnce(&mut BorrowedBuf<'_>) -> T) -> T {
|
||||
let mut buf = BorrowedBuf::from(self.reborrow());
|
||||
let prev_ptr = buf.buf as *const _;
|
||||
let res = f(&mut buf);
|
||||
|
||||
// Check that the caller didn't replace the `BorrowedBuf`.
|
||||
// This is necessary for the safety of the code below: if the check wasn't
|
||||
// there, one could mark some bytes as initialized even though there aren't.
|
||||
assert!(core::ptr::addr_eq(prev_ptr, buf.buf));
|
||||
|
||||
let filled = buf.filled;
|
||||
let init = buf.init;
|
||||
|
||||
// Update `init` and `filled` fields with what was written to the buffer.
|
||||
// `self.buf.filled` was the starting length of the `BorrowedBuf`.
|
||||
//
|
||||
// SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`,
|
||||
// and therefore they are initialized/filled in the cursor too, because the
|
||||
// buffer wasn't replaced.
|
||||
self.buf.init = self.buf.filled + init;
|
||||
self.buf.filled += filled;
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ impl<T> Clone for Empty<T> {
|
|||
// not #[derive] because that adds a Default bound on T,
|
||||
// which isn't necessary.
|
||||
#[stable(feature = "iter_empty", since = "1.2.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T> const Default for Empty<T> {
|
||||
fn default() -> Empty<T> {
|
||||
Empty(marker::PhantomData)
|
||||
|
|
|
|||
|
|
@ -863,7 +863,7 @@ impl<T: PointeeSized> Clone for PhantomData<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T: PointeeSized> const Default for PhantomData<T> {
|
||||
fn default() -> Self {
|
||||
Self
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ use crate::marker::Tuple;
|
|||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
pub trait Fn<Args: Tuple>: FnMut<Args> {
|
||||
/// Performs the call operation.
|
||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||
|
|
@ -161,7 +161,7 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
|
|||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
|
||||
/// Performs the call operation.
|
||||
#[unstable(feature = "fn_traits", issue = "29625")]
|
||||
|
|
@ -241,7 +241,7 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
|
|||
#[fundamental] // so that regex can rely that `&str: !FnMut`
|
||||
#[must_use = "closures are lazy and do nothing unless called"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
pub trait FnOnce<Args: Tuple> {
|
||||
/// The returned type after the call operator is used.
|
||||
#[lang = "fn_once_output"]
|
||||
|
|
@ -257,7 +257,7 @@ mod impls {
|
|||
use crate::marker::Tuple;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
impl<A: Tuple, F: ?Sized> const Fn<A> for &F
|
||||
where
|
||||
F: ~const Fn<A>,
|
||||
|
|
@ -268,7 +268,7 @@ mod impls {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
|
||||
where
|
||||
F: ~const Fn<A>,
|
||||
|
|
@ -279,7 +279,7 @@ mod impls {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
|
||||
where
|
||||
F: ~const Fn<A>,
|
||||
|
|
@ -292,7 +292,7 @@ mod impls {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
|
||||
where
|
||||
F: ~const FnMut<A>,
|
||||
|
|
@ -303,7 +303,7 @@ mod impls {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
|
||||
impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
|
||||
where
|
||||
F: ~const FnMut<A>,
|
||||
|
|
|
|||
|
|
@ -2112,7 +2112,7 @@ where
|
|||
impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T> const Default for Option<T> {
|
||||
/// Returns [`None`][Option::None].
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1081,13 +1081,11 @@ mod prim_str {}
|
|||
/// * [`Debug`]
|
||||
/// * [`Default`]
|
||||
/// * [`Hash`]
|
||||
/// * [`Random`]
|
||||
/// * [`From<[T; N]>`][from]
|
||||
///
|
||||
/// [from]: convert::From
|
||||
/// [`Debug`]: fmt::Debug
|
||||
/// [`Hash`]: hash::Hash
|
||||
/// [`Random`]: random::Random
|
||||
///
|
||||
/// The following traits are implemented for tuples of any length. These traits have
|
||||
/// implementations that are automatically generated by the compiler, so are not limited by
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ impl hash::Hash for Alignment {
|
|||
|
||||
/// Returns [`Alignment::MIN`], which is valid for any type.
|
||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl const Default for Alignment {
|
||||
fn default() -> Alignment {
|
||||
Alignment::MIN
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ If any of the following conditions are violated, the result is Undefined Behavio
|
|||
bounds of that allocation. In particular, this range must not "wrap around" the edge
|
||||
of the address space.
|
||||
|
||||
Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
|
||||
Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
|
||||
stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
|
||||
This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
|
||||
safe.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ bounds of that allocation. In particular, this range must not "wrap around" the
|
|||
of the address space. Note that "range" here refers to a half-open range as usual in Rust,
|
||||
i.e., `self..result` for non-negative offsets and `result..self` for negative offsets.
|
||||
|
||||
Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
|
||||
Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
|
||||
stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
|
||||
This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
|
||||
safe.
|
||||
|
|
|
|||
|
|
@ -1,48 +1,46 @@
|
|||
//! Random value generation.
|
||||
//!
|
||||
//! The [`Random`] trait allows generating a random value for a type using a
|
||||
//! given [`RandomSource`].
|
||||
|
||||
use crate::range::RangeFull;
|
||||
|
||||
/// A source of randomness.
|
||||
#[unstable(feature = "random", issue = "130703")]
|
||||
pub trait RandomSource {
|
||||
/// Fills `bytes` with random bytes.
|
||||
///
|
||||
/// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once
|
||||
/// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two
|
||||
/// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw
|
||||
/// part of it away if not needed.
|
||||
fn fill_bytes(&mut self, bytes: &mut [u8]);
|
||||
}
|
||||
|
||||
/// A trait for getting a random value for a type.
|
||||
///
|
||||
/// **Warning:** Be careful when manipulating random values! The
|
||||
/// [`random`](Random::random) method on integers samples them with a uniform
|
||||
/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
|
||||
/// modulo operations, some of the resulting values can become more likely than
|
||||
/// others. Use audited crates when in doubt.
|
||||
/// A trait representing a distribution of random values for a type.
|
||||
#[unstable(feature = "random", issue = "130703")]
|
||||
pub trait Random: Sized {
|
||||
/// Generates a random value.
|
||||
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self;
|
||||
pub trait Distribution<T> {
|
||||
/// Samples a random value from the distribution, using the specified random source.
|
||||
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T;
|
||||
}
|
||||
|
||||
impl Random for bool {
|
||||
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
|
||||
u8::random(source) & 1 == 1
|
||||
impl<T, DT: Distribution<T>> Distribution<T> for &DT {
|
||||
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T {
|
||||
(*self).sample(source)
|
||||
}
|
||||
}
|
||||
|
||||
impl Distribution<bool> for RangeFull {
|
||||
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool {
|
||||
let byte: u8 = RangeFull.sample(source);
|
||||
byte & 1 == 1
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_primitive {
|
||||
($t:ty) => {
|
||||
impl Random for $t {
|
||||
/// Generates a random value.
|
||||
///
|
||||
/// **Warning:** Be careful when manipulating the resulting value! This
|
||||
/// method samples according to a uniform distribution, so a value of 1 is
|
||||
/// just as likely as [`MAX`](Self::MAX). By using modulo operations, some
|
||||
/// values can become more likely than others. Use audited crates when in
|
||||
/// doubt.
|
||||
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
|
||||
let mut bytes = (0 as Self).to_ne_bytes();
|
||||
impl Distribution<$t> for RangeFull {
|
||||
fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
|
||||
let mut bytes = (0 as $t).to_ne_bytes();
|
||||
source.fill_bytes(&mut bytes);
|
||||
Self::from_ne_bytes(bytes)
|
||||
<$t>::from_ne_bytes(bytes)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5192,7 +5192,7 @@ where
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T> const Default for &[T] {
|
||||
/// Creates an empty slice.
|
||||
fn default() -> Self {
|
||||
|
|
@ -5201,7 +5201,7 @@ impl<T> const Default for &[T] {
|
|||
}
|
||||
|
||||
#[stable(feature = "mut_slice_default", since = "1.5.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl<T> const Default for &mut [T] {
|
||||
/// Creates a mutable empty slice.
|
||||
fn default() -> Self {
|
||||
|
|
|
|||
|
|
@ -3072,7 +3072,7 @@ impl AsRef<[u8]> for str {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl const Default for &str {
|
||||
/// Creates an empty str
|
||||
#[inline]
|
||||
|
|
@ -3082,7 +3082,7 @@ impl const Default for &str {
|
|||
}
|
||||
|
||||
#[stable(feature = "default_mut_str", since = "1.28.0")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
|
||||
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
|
||||
impl const Default for &mut str {
|
||||
/// Creates an empty mutable str
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
use crate::cmp::Ordering::{self, *};
|
||||
use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
|
||||
use crate::ops::ControlFlow::{self, Break, Continue};
|
||||
use crate::random::{Random, RandomSource};
|
||||
|
||||
// Recursive macro for implementing n-ary tuple functions and operations
|
||||
//
|
||||
|
|
@ -131,16 +130,6 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[unstable(feature = "random", issue = "130703")]
|
||||
impl<$($T: Random),+> Random for ($($T,)+) {
|
||||
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
|
||||
($({ let x: $T = Random::random(source); x},)+)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
|
||||
|
|
|
|||
|
|
@ -165,3 +165,39 @@ fn cursor_set_init() {
|
|||
assert_eq!(rbuf.unfilled().uninit_mut().len(), 4);
|
||||
assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cursor_with_unfilled_buf() {
|
||||
let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
|
||||
let mut rbuf = BorrowedBuf::from(buf);
|
||||
let mut cursor = rbuf.unfilled();
|
||||
|
||||
cursor.with_unfilled_buf(|buf| {
|
||||
buf.unfilled().append(&[1, 2, 3]);
|
||||
assert_eq!(buf.filled(), &[1, 2, 3]);
|
||||
});
|
||||
|
||||
assert_eq!(cursor.init_mut().len(), 0);
|
||||
assert_eq!(cursor.written(), 3);
|
||||
|
||||
cursor.with_unfilled_buf(|buf| {
|
||||
assert_eq!(buf.capacity(), 13);
|
||||
assert_eq!(buf.init_len(), 0);
|
||||
|
||||
buf.unfilled().ensure_init();
|
||||
buf.unfilled().advance(4);
|
||||
});
|
||||
|
||||
assert_eq!(cursor.init_mut().len(), 9);
|
||||
assert_eq!(cursor.written(), 7);
|
||||
|
||||
cursor.with_unfilled_buf(|buf| {
|
||||
assert_eq!(buf.capacity(), 9);
|
||||
assert_eq!(buf.init_len(), 9);
|
||||
});
|
||||
|
||||
assert_eq!(cursor.init_mut().len(), 9);
|
||||
assert_eq!(cursor.written(), 7);
|
||||
|
||||
assert_eq!(rbuf.filled(), &[1, 2, 3, 0, 0, 0, 0]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
//! Random value generation.
|
||||
//!
|
||||
//! The [`Random`] trait allows generating a random value for a type using a
|
||||
//! given [`RandomSource`].
|
||||
|
||||
#[unstable(feature = "random", issue = "130703")]
|
||||
pub use core::random::*;
|
||||
|
|
@ -68,18 +65,11 @@ impl RandomSource for DefaultRandomSource {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generates a random value with the default random source.
|
||||
/// Generates a random value from a distribution, using the default random source.
|
||||
///
|
||||
/// This is a convenience function for `T::random(&mut DefaultRandomSource)` and
|
||||
/// will sample according to the same distribution as the underlying [`Random`]
|
||||
/// trait implementation. See [`DefaultRandomSource`] for more information about
|
||||
/// how randomness is sourced.
|
||||
///
|
||||
/// **Warning:** Be careful when manipulating random values! The
|
||||
/// [`random`](Random::random) method on integers samples them with a uniform
|
||||
/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
|
||||
/// modulo operations, some of the resulting values can become more likely than
|
||||
/// others. Use audited crates when in doubt.
|
||||
/// This is a convenience function for `dist.sample(&mut DefaultRandomSource)` and will sample
|
||||
/// according to the same distribution as the underlying [`Distribution`] trait implementation. See
|
||||
/// [`DefaultRandomSource`] for more information about how randomness is sourced.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -89,7 +79,7 @@ impl RandomSource for DefaultRandomSource {
|
|||
///
|
||||
/// use std::random::random;
|
||||
///
|
||||
/// let bits: u128 = random();
|
||||
/// let bits: u128 = random(..);
|
||||
/// let g1 = (bits >> 96) as u32;
|
||||
/// let g2 = (bits >> 80) as u16;
|
||||
/// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16;
|
||||
|
|
@ -101,6 +91,6 @@ impl RandomSource for DefaultRandomSource {
|
|||
///
|
||||
/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
|
||||
#[unstable(feature = "random", issue = "130703")]
|
||||
pub fn random<T: Random>() -> T {
|
||||
T::random(&mut DefaultRandomSource)
|
||||
pub fn random<T>(dist: impl Distribution<T>) -> T {
|
||||
dist.sample(&mut DefaultRandomSource)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
|
|||
use crate::os::windows::io::{
|
||||
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
|
||||
};
|
||||
use crate::sync::OnceLock;
|
||||
use crate::sync::atomic::Atomic;
|
||||
use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
|
||||
use crate::sys::c;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::Duration;
|
||||
|
|
@ -114,33 +115,38 @@ pub(super) mod netc {
|
|||
#[expect(missing_debug_implementations)]
|
||||
pub struct Socket(OwnedSocket);
|
||||
|
||||
static WSA_CLEANUP: OnceLock<unsafe extern "system" fn() -> i32> = OnceLock::new();
|
||||
static WSA_INITIALIZED: Atomic<bool> = Atomic::<bool>::new(false);
|
||||
|
||||
/// Checks whether the Windows socket interface has been started already, and
|
||||
/// if not, starts it.
|
||||
#[inline]
|
||||
pub fn init() {
|
||||
let _ = WSA_CLEANUP.get_or_init(|| unsafe {
|
||||
if !WSA_INITIALIZED.load(Relaxed) {
|
||||
wsa_startup();
|
||||
}
|
||||
}
|
||||
|
||||
#[cold]
|
||||
fn wsa_startup() {
|
||||
unsafe {
|
||||
let mut data: c::WSADATA = mem::zeroed();
|
||||
let ret = c::WSAStartup(
|
||||
0x202, // version 2.2
|
||||
&mut data,
|
||||
);
|
||||
assert_eq!(ret, 0);
|
||||
|
||||
// Only register `WSACleanup` if `WSAStartup` is actually ever called.
|
||||
// Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
|
||||
// See issue #85441.
|
||||
c::WSACleanup
|
||||
});
|
||||
if WSA_INITIALIZED.swap(true, AcqRel) {
|
||||
// If another thread raced with us and called WSAStartup first then call
|
||||
// WSACleanup so it's as though WSAStartup was only called once.
|
||||
c::WSACleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cleanup() {
|
||||
// only perform cleanup if network functionality was actually initialized
|
||||
if let Some(cleanup) = WSA_CLEANUP.get() {
|
||||
unsafe {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
// We don't need to call WSACleanup here because exiting the process will cause
|
||||
// the OS to clean everything for us, which is faster than doing it manually.
|
||||
// See #141799.
|
||||
}
|
||||
|
||||
/// Returns the last error from the Windows socket interface.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::cmp;
|
|||
use crate::io::{
|
||||
BorrowedCursor, Error as IoError, ErrorKind, IoSlice, IoSliceMut, Result as IoResult,
|
||||
};
|
||||
use crate::random::{DefaultRandomSource, Random};
|
||||
use crate::random::random;
|
||||
use crate::time::{Duration, Instant};
|
||||
|
||||
pub(crate) mod alloc;
|
||||
|
|
@ -179,7 +179,7 @@ pub fn wait(event_mask: u64, mut timeout: u64) -> IoResult<u64> {
|
|||
// trusted to ensure accurate timeouts.
|
||||
if let Ok(timeout_signed) = i64::try_from(timeout) {
|
||||
let tenth = timeout_signed / 10;
|
||||
let deviation = i64::random(&mut DefaultRandomSource).checked_rem(tenth).unwrap_or(0);
|
||||
let deviation = random::<i64>(..).checked_rem(tenth).unwrap_or(0);
|
||||
timeout = timeout_signed.saturating_add(deviation) as _;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,18 @@ use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all};
|
|||
// This means we only need one atomic value with 4 states:
|
||||
|
||||
/// No initialization has run yet, and no thread is currently using the Once.
|
||||
const INCOMPLETE: Primitive = 0;
|
||||
const INCOMPLETE: Primitive = 3;
|
||||
/// Some thread has previously attempted to initialize the Once, but it panicked,
|
||||
/// so the Once is now poisoned. There are no other threads currently accessing
|
||||
/// this Once.
|
||||
const POISONED: Primitive = 1;
|
||||
const POISONED: Primitive = 2;
|
||||
/// Some thread is currently attempting to run initialization. It may succeed,
|
||||
/// so all future threads need to wait for it to finish.
|
||||
const RUNNING: Primitive = 2;
|
||||
const RUNNING: Primitive = 1;
|
||||
/// Initialization has completed and all future calls should finish immediately.
|
||||
const COMPLETE: Primitive = 3;
|
||||
/// By choosing this state as the all-zero state the `is_completed` check can be
|
||||
/// a bit faster on some platforms.
|
||||
const COMPLETE: Primitive = 0;
|
||||
|
||||
// An additional bit indicates whether there are waiting threads:
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue