Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2025-07-15 05:07:09 +00:00
commit f7da0212af
213 changed files with 1816 additions and 1339 deletions

2
.gitmodules vendored
View file

@ -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

View file

@ -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"

View file

@ -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",

View file

@ -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

View file

@ -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]

View file

@ -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))`.

View file

@ -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),

View file

@ -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,

View file

@ -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'

View file

@ -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;
}

View file

@ -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 })
}
}

View file

@ -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;
}

View file

@ -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 {

View file

@ -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)
}

View file

@ -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> },

View file

@ -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() {

View file

@ -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

View file

@ -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`

View file

@ -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,

View file

@ -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 {

View file

@ -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

View file

@ -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};

View file

@ -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.

View file

@ -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 {

View file

@ -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();

View file

@ -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)
}

View file

@ -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");
}
}
}

View file

@ -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;
}

View file

@ -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 {

View file

@ -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 });
}
}

View file

@ -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`

View file

@ -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) {

View file

@ -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;
}

View file

@ -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

View file

@ -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;
};

View file

@ -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 {

View file

@ -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;
}

View file

@ -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"

View file

@ -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))
}
}

View file

@ -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),

View file

@ -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)) };

View file

@ -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)>,

View file

@ -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),

View file

@ -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;

View file

@ -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>>

View file

@ -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),

View file

@ -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;

View file

@ -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;

View file

@ -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::{

View file

@ -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()),

View file

@ -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;

View file

@ -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;

View file

@ -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>;

View file

@ -1,5 +1,5 @@
[package]
name = "rustc_smir"
name = "rustc_public_bridge"
version = "0.0.0"
edition = "2024"

View file

@ -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};

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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,
&region_constraint_data,
);

View file

@ -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]

View file

@ -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>`.
///

View file

@ -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> {

View file

@ -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]

View file

@ -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]

View file

@ -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
}
}

View file

@ -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)

View file

@ -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

View file

@ -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>,

View file

@ -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].
///

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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)
}
}
};

View file

@ -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 {

View file

@ -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]

View file

@ -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")]

View file

@ -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]);
}

View file

@ -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)
}

View file

@ -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.

View file

@ -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 _;
}
}

View file

@ -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