Merge pull request #4486 from rust-lang/rustup-2025-07-21
Automatic Rustup
This commit is contained in:
commit
9ef15d2302
100 changed files with 973 additions and 723 deletions
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
|
|
@ -182,11 +182,6 @@ jobs:
|
|||
- name: install MinGW
|
||||
run: src/ci/scripts/install-mingw.sh
|
||||
|
||||
# Workaround for spurious ci failures after mingw install
|
||||
# see https://rust-lang.zulipchat.com/#narrow/channel/242791-t-infra/topic/Spurious.20bors.20CI.20failures/near/528915775
|
||||
- name: ensure home dir exists
|
||||
run: mkdir -p ~
|
||||
|
||||
- name: install ninja
|
||||
run: src/ci/scripts/install-ninja.sh
|
||||
|
||||
|
|
|
|||
110
Cargo.lock
110
Cargo.lock
|
|
@ -216,7 +216,7 @@ dependencies = [
|
|||
"memchr",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"winnow 0.7.11",
|
||||
"winnow 0.7.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -510,23 +510,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "chrono-tz"
|
||||
version = "0.10.3"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3"
|
||||
checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz-build",
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chrono-tz-build"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402"
|
||||
dependencies = [
|
||||
"parse-zoneinfo",
|
||||
"phf_codegen",
|
||||
"phf 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -541,9 +530,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
||||
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -561,9 +550,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
||||
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -573,9 +562,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
||||
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
|
|
@ -847,9 +836,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
|
@ -1038,9 +1027,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "derive_setters"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c848e86c87e5cc305313041c5677d4d95d60baa71cf95e5f6ea2554bb629ff"
|
||||
checksum = "ae5c625eda104c228c06ecaf988d1c60e542176bd7a490e60eeda3493244c0c9"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
|
@ -2103,9 +2092,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
|||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.4"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
|
||||
checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
|
@ -2215,7 +2204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
|
||||
dependencies = [
|
||||
"log",
|
||||
"phf",
|
||||
"phf 0.11.3",
|
||||
"phf_codegen",
|
||||
"string_cache",
|
||||
"string_cache_codegen",
|
||||
|
|
@ -2254,9 +2243,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "measureme"
|
||||
version = "12.0.1"
|
||||
version = "12.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "570a507d8948a66a97f42cbbaf8a6bb9516a51017d4ee949502ad7a10a864395"
|
||||
checksum = "6ebd1ebda747ae161a4a377bf93f87e18d46faad2331cc0c7d25b84b1d445f49"
|
||||
dependencies = [
|
||||
"log",
|
||||
"memmap2",
|
||||
|
|
@ -2698,15 +2687,6 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse-zoneinfo"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.3"
|
||||
|
|
@ -2778,7 +2758,16 @@ version = "0.11.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7"
|
||||
dependencies = [
|
||||
"phf_shared 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2788,7 +2777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2797,7 +2786,7 @@ version = "0.11.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.3",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
|
|
@ -2810,6 +2799,15 @@ dependencies = [
|
|||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
|
|
@ -4818,15 +4816,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4947,9 +4945,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
version = "1.0.141"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -5104,7 +5102,7 @@ checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
|
|||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"parking_lot",
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.3",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
]
|
||||
|
|
@ -5116,7 +5114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
|
@ -5181,9 +5179,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.36.0"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aab138f5c1bb35231de19049060a87977ad23e04f2303e953bc5c2947ac7dec4"
|
||||
checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
|
|
@ -5488,7 +5486,7 @@ dependencies = [
|
|||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_write",
|
||||
"winnow 0.7.11",
|
||||
"winnow 0.7.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5886,9 +5884,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasi-preview1-component-adapter-provider"
|
||||
version = "34.0.1"
|
||||
version = "34.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aafa1e6af9a954a4bcf6ef420c33355d0ce84ddc6afbcba7bb6f05126f9120ae"
|
||||
checksum = "33696c5f1ff1e083de9f36c3da471abd736362bc173e093f8b0b1ed5a387e39b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
|
|
@ -6532,9 +6530,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.11"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ impl OwnedTargetMachine {
|
|||
debug_info_compression: &CStr,
|
||||
use_emulated_tls: bool,
|
||||
args_cstr_buff: &[u8],
|
||||
use_wasm_eh: bool,
|
||||
) -> Result<Self, LlvmError<'static>> {
|
||||
assert!(args_cstr_buff.len() > 0);
|
||||
assert!(
|
||||
|
|
@ -72,6 +73,7 @@ impl OwnedTargetMachine {
|
|||
use_emulated_tls,
|
||||
args_cstr_buff.as_ptr() as *const c_char,
|
||||
args_cstr_buff.len(),
|
||||
use_wasm_eh,
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use rustc_codegen_ssa::back::write::{
|
|||
BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig,
|
||||
TargetMachineFactoryFn,
|
||||
};
|
||||
use rustc_codegen_ssa::base::wants_wasm_eh;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, ModuleKind};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
|
|
@ -285,6 +286,8 @@ pub(crate) fn target_machine_factory(
|
|||
let file_name_display_preference =
|
||||
sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO);
|
||||
|
||||
let use_wasm_eh = wants_wasm_eh(sess);
|
||||
|
||||
Arc::new(move |config: TargetMachineFactoryConfig| {
|
||||
let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
|
||||
let path = path.unwrap_or_default();
|
||||
|
|
@ -321,6 +324,7 @@ pub(crate) fn target_machine_factory(
|
|||
&debuginfo_compression,
|
||||
use_emulated_tls,
|
||||
&args_cstr_buff,
|
||||
use_wasm_eh,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ pub(crate) unsafe fn create_module<'ll>(
|
|||
// LLVM 21 updated the default layout on nvptx: https://github.com/llvm/llvm-project/pull/124961
|
||||
target_data_layout = target_data_layout.replace("e-p6:32:32-i64", "e-i64");
|
||||
}
|
||||
if sess.target.arch == "amdgpu" {
|
||||
// LLVM 21 adds the address width for address space 8.
|
||||
// See https://github.com/llvm/llvm-project/pull/139419
|
||||
target_data_layout = target_data_layout.replace("p8:128:128:128:48", "p8:128:128")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
|
|
|
|||
|
|
@ -2425,6 +2425,7 @@ unsafe extern "C" {
|
|||
UseEmulatedTls: bool,
|
||||
ArgsCstrBuff: *const c_char,
|
||||
ArgsCstrBuffLen: usize,
|
||||
UseWasmEH: bool,
|
||||
) -> *mut TargetMachine;
|
||||
|
||||
pub(crate) fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
|
||||
|
|
|
|||
|
|
@ -630,7 +630,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
OperandRef { val: OperandValue::Immediate(static_), layout }
|
||||
}
|
||||
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
|
||||
mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"),
|
||||
mir::Rvalue::Repeat(ref elem, len_const) => {
|
||||
// All arrays have `BackendRepr::Memory`, so only the ZST cases
|
||||
// end up here. Anything else forces the destination local to be
|
||||
// `Memory`, and thus ends up handled in `codegen_rvalue` instead.
|
||||
let operand = self.codegen_operand(bx, elem);
|
||||
let array_ty = Ty::new_array_with_const_len(bx.tcx(), operand.layout.ty, len_const);
|
||||
let array_ty = self.monomorphize(array_ty);
|
||||
let array_layout = bx.layout_of(array_ty);
|
||||
assert!(array_layout.is_zst());
|
||||
OperandRef { val: OperandValue::ZeroSized, layout: array_layout }
|
||||
}
|
||||
mir::Rvalue::Aggregate(ref kind, ref fields) => {
|
||||
let (variant_index, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
|
||||
|
|
@ -1000,12 +1010,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
mir::Rvalue::NullaryOp(..) |
|
||||
mir::Rvalue::ThreadLocalRef(_) |
|
||||
mir::Rvalue::Use(..) |
|
||||
mir::Rvalue::Repeat(..) | // (*)
|
||||
mir::Rvalue::Aggregate(..) | // (*)
|
||||
mir::Rvalue::WrapUnsafeBinder(..) => // (*)
|
||||
true,
|
||||
// Arrays are always aggregates, so it's not worth checking anything here.
|
||||
// (If it's really `[(); N]` or `[T; 0]` and we use the place path, fine.)
|
||||
mir::Rvalue::Repeat(..) => false,
|
||||
}
|
||||
|
||||
// (*) this is only true if the type is suitable
|
||||
|
|
|
|||
|
|
@ -149,14 +149,14 @@ fn parse_rust_feature_flag<'a>(
|
|||
if let Some(base_feature) = feature.strip_prefix('+') {
|
||||
// Skip features that are not target features, but rustc features.
|
||||
if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
callback(base_feature, sess.target.implied_target_features(base_feature), true)
|
||||
} else if let Some(base_feature) = feature.strip_prefix('-') {
|
||||
// Skip features that are not target features, but rustc features.
|
||||
if RUSTC_SPECIFIC_FEATURES.contains(&base_feature) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If `f1` implies `f2`, then `!f2` implies `!f1` -- this is standard logical
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ pub enum AllocKind {
|
|||
LiveData,
|
||||
/// A function allocation (that fn ptrs point to).
|
||||
Function,
|
||||
/// A (symbolic) vtable allocation.
|
||||
VTable,
|
||||
/// A "virtual" allocation, used for vtables and TypeId.
|
||||
Virtual,
|
||||
/// A dead allocation.
|
||||
Dead,
|
||||
}
|
||||
|
|
@ -950,11 +950,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env);
|
||||
let mutbl = global_alloc.mutability(*self.tcx, self.typing_env);
|
||||
let kind = match global_alloc {
|
||||
GlobalAlloc::TypeId { .. }
|
||||
| GlobalAlloc::Static { .. }
|
||||
| GlobalAlloc::Memory { .. } => AllocKind::LiveData,
|
||||
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
|
||||
GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),
|
||||
GlobalAlloc::VTable { .. } => AllocKind::VTable,
|
||||
GlobalAlloc::VTable { .. } | GlobalAlloc::TypeId { .. } => AllocKind::Virtual,
|
||||
};
|
||||
return AllocInfo::new(size, align, kind, mutbl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2495,6 +2495,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
ty::List::empty(),
|
||||
PredicateFilter::All,
|
||||
);
|
||||
self.add_sizedness_bounds(
|
||||
&mut bounds,
|
||||
self_ty,
|
||||
hir_bounds,
|
||||
None,
|
||||
None,
|
||||
hir_ty.span,
|
||||
);
|
||||
self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
|
||||
self_ty
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,12 +160,10 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks {
|
|||
let (arg_indices, are_zsts_allowed): (&[_], _) = match diag_name {
|
||||
sym::ptr_read
|
||||
| sym::ptr_read_unaligned
|
||||
| sym::ptr_read_volatile
|
||||
| sym::ptr_replace
|
||||
| sym::ptr_write
|
||||
| sym::ptr_write_bytes
|
||||
| sym::ptr_write_unaligned
|
||||
| sym::ptr_write_volatile => (&[0], true),
|
||||
| sym::ptr_write_unaligned => (&[0], true),
|
||||
sym::slice_from_raw_parts | sym::slice_from_raw_parts_mut => (&[0], false),
|
||||
sym::ptr_copy
|
||||
| sym::ptr_copy_nonoverlapping
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
|
||||
const char *SplitDwarfFile, const char *OutputObjFile,
|
||||
const char *DebugInfoCompression, bool UseEmulatedTls,
|
||||
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
|
||||
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen, bool UseWasmEH) {
|
||||
|
||||
auto OptLevel = fromRust(RustOptLevel);
|
||||
auto RM = fromRust(RustReloc);
|
||||
|
|
@ -462,6 +462,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||
Options.ThreadModel = ThreadModel::Single;
|
||||
}
|
||||
|
||||
if (UseWasmEH)
|
||||
Options.ExceptionModel = ExceptionHandling::Wasm;
|
||||
|
||||
Options.EmitStackSizeSection = EmitStackSizeSection;
|
||||
|
||||
if (ArgsCstrBuff != nullptr) {
|
||||
|
|
|
|||
|
|
@ -1210,30 +1210,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
}
|
||||
|
||||
for (assoc_item_def_id, term) in assoc_items {
|
||||
// Skip printing `<{coroutine@} as Coroutine<_>>::Return` from async blocks,
|
||||
// unless we can find out what coroutine return type it comes from.
|
||||
let term = if let Some(ty) = term.skip_binder().as_type()
|
||||
&& let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& let Some(assoc) = tcx.opt_associated_item(proj.def_id)
|
||||
&& assoc
|
||||
.trait_container(tcx)
|
||||
.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine))
|
||||
&& assoc.opt_name() == Some(rustc_span::sym::Return)
|
||||
{
|
||||
if let ty::Coroutine(_, args) = args.type_at(0).kind() {
|
||||
let return_ty = args.as_coroutine().return_ty();
|
||||
if !return_ty.is_ty_var() {
|
||||
return_ty.into()
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
term.skip_binder()
|
||||
};
|
||||
|
||||
if first {
|
||||
p!("<");
|
||||
first = false;
|
||||
|
|
@ -1243,7 +1219,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
|
||||
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name()));
|
||||
|
||||
match term.kind() {
|
||||
match term.skip_binder().kind() {
|
||||
TermKind::Ty(ty) => p!(print(ty)),
|
||||
TermKind::Const(c) => p!(print(c)),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -119,14 +119,16 @@ impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
|
|||
#[track_caller]
|
||||
fn fail(&self, location: Location, msg: impl AsRef<str>) {
|
||||
// We might see broken MIR when other errors have already occurred.
|
||||
assert!(
|
||||
self.tcx.dcx().has_errors().is_some(),
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
self.body.source.instance,
|
||||
self.when,
|
||||
location,
|
||||
msg.as_ref(),
|
||||
);
|
||||
if self.tcx.dcx().has_errors().is_none() {
|
||||
span_bug!(
|
||||
self.body.source_info(location).span,
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
self.body.source.instance,
|
||||
self.when,
|
||||
location,
|
||||
msg.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_edge(&mut self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) {
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ impl ExpnId {
|
|||
|
||||
/// `expn_id.outer_expn_is_descendant_of(ctxt)` is equivalent to but faster than
|
||||
/// `expn_id.is_descendant_of(ctxt.outer_expn())`.
|
||||
#[inline]
|
||||
pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
||||
HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
|
||||
}
|
||||
|
|
@ -394,6 +395,7 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with<R>(f: impl FnOnce(&mut HygieneData) -> R) -> R {
|
||||
with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut()))
|
||||
}
|
||||
|
|
@ -406,6 +408,7 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn local_expn_data(&self, expn_id: LocalExpnId) -> &ExpnData {
|
||||
self.local_expn_data[expn_id].as_ref().expect("no expansion data for an expansion ID")
|
||||
}
|
||||
|
|
@ -437,23 +440,28 @@ impl HygieneData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_to_macros_2_0(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn normalize_to_macro_rules(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId {
|
||||
self.syntax_context_data[ctxt.0 as usize].outer_expn
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
|
||||
let data = &self.syntax_context_data[ctxt.0 as usize];
|
||||
(data.outer_expn, data.outer_transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
|
||||
self.syntax_context_data[ctxt.0 as usize].parent
|
||||
}
|
||||
|
|
@ -718,11 +726,13 @@ impl SyntaxContext {
|
|||
SyntaxContext(raw as u32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_usize(raw: usize) -> SyntaxContext {
|
||||
SyntaxContext(u32::try_from(raw).unwrap())
|
||||
}
|
||||
|
||||
/// Extend a syntax context with a given expansion and transparency.
|
||||
#[inline]
|
||||
pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
|
||||
HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
|
||||
}
|
||||
|
|
@ -743,10 +753,12 @@ impl SyntaxContext {
|
|||
/// of g (call it g1), calling remove_mark will result in the SyntaxContext for the
|
||||
/// invocation of f that created g1.
|
||||
/// Returns the mark that was removed.
|
||||
#[inline]
|
||||
pub fn remove_mark(&mut self) -> ExpnId {
|
||||
HygieneData::with(|data| data.remove_mark(self).0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
|
||||
HygieneData::with(|data| data.marks(self))
|
||||
}
|
||||
|
|
@ -776,11 +788,13 @@ impl SyntaxContext {
|
|||
/// ```
|
||||
/// This returns the expansion whose definition scope we use to privacy check the resolution,
|
||||
/// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
|
||||
#[inline]
|
||||
pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
|
||||
HygieneData::with(|data| data.adjust(self, expn_id))
|
||||
}
|
||||
|
||||
/// Like `SyntaxContext::adjust`, but also normalizes `self` to macros 2.0.
|
||||
#[inline]
|
||||
pub(crate) fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
|
||||
HygieneData::with(|data| {
|
||||
*self = data.normalize_to_macros_2_0(*self);
|
||||
|
|
@ -901,10 +915,12 @@ impl SyntaxContext {
|
|||
HygieneData::with(|data| data.outer_mark(self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn dollar_crate_name(self) -> Symbol {
|
||||
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn edition(self) -> Edition {
|
||||
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_session_globals<R, F>(f: F) -> R
|
||||
where
|
||||
F: FnOnce(&SessionGlobals) -> R,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetMetadata,
|
|||
pub(crate) fn target() -> Target {
|
||||
Target {
|
||||
arch: "amdgpu".into(),
|
||||
data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(),
|
||||
data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(),
|
||||
llvm_target: "amdgcn-amd-amdhsa".into(),
|
||||
metadata: TargetMetadata {
|
||||
description: Some("AMD GPU".into()),
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ use rustc_infer::traits::solve::Goal;
|
|||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::Certainty;
|
||||
use rustc_middle::ty::{
|
||||
self, SizedTraitKind, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
|
||||
self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
|
||||
};
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
|
||||
|
||||
use crate::traits::{EvaluateConstErr, ObligationCause, specialization_graph};
|
||||
use crate::traits::{EvaluateConstErr, ObligationCause, sizedness_fast_path, specialization_graph};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct SolverDelegate<'tcx>(InferCtxt<'tcx>);
|
||||
|
|
@ -76,19 +76,11 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
|
||||
if trait_pred.polarity() == ty::PredicatePolarity::Positive {
|
||||
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
|
||||
Some(LangItem::Sized)
|
||||
if self
|
||||
.resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
|
||||
.has_trivial_sizedness(self.0.tcx, SizedTraitKind::Sized) =>
|
||||
{
|
||||
return Some(Certainty::Yes);
|
||||
}
|
||||
Some(LangItem::MetaSized)
|
||||
if self
|
||||
.resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
|
||||
.has_trivial_sizedness(self.0.tcx, SizedTraitKind::MetaSized) =>
|
||||
{
|
||||
return Some(Certainty::Yes);
|
||||
Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
|
||||
let predicate = self.resolve_vars_if_possible(goal.predicate);
|
||||
if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
|
||||
return Some(Certainty::Yes);
|
||||
}
|
||||
}
|
||||
Some(LangItem::Copy | LangItem::Clone) => {
|
||||
let self_ty =
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
|
||||
let infcx = self.selcx.infcx;
|
||||
|
||||
if sizedness_fast_path(infcx.tcx, obligation.predicate) {
|
||||
if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
|
||||
return ProcessResult::Changed(thin_vec![]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResponse> {
|
||||
if sizedness_fast_path(tcx, key.value.predicate) {
|
||||
if sizedness_fast_path(tcx, key.value.predicate, key.param_env) {
|
||||
return Some(());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
None => self.check_recursion_limit(&obligation, &obligation)?,
|
||||
}
|
||||
|
||||
if sizedness_fast_path(self.tcx(), obligation.predicate) {
|
||||
if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) {
|
||||
return Ok(EvaluatedToOk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -365,7 +365,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>) -> bool {
|
||||
pub fn sizedness_fast_path<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> bool {
|
||||
// Proving `Sized`/`MetaSized`, very often on "obviously sized" types like
|
||||
// `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to
|
||||
// canonicalize and all that for such cases.
|
||||
|
|
@ -390,6 +394,20 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
|||
debug!("fast path -- trivial sizedness");
|
||||
return true;
|
||||
}
|
||||
|
||||
if matches!(trait_pred.self_ty().kind(), ty::Param(_) | ty::Placeholder(_)) {
|
||||
for clause in param_env.caller_bounds() {
|
||||
if let ty::ClauseKind::Trait(clause_pred) = clause.kind().skip_binder()
|
||||
&& clause_pred.polarity == ty::PredicatePolarity::Positive
|
||||
&& clause_pred.self_ty() == trait_pred.self_ty()
|
||||
&& (clause_pred.def_id() == trait_pred.def_id()
|
||||
|| (sizedness == SizedTraitKind::MetaSized
|
||||
&& tcx.is_lang_item(clause_pred.def_id(), LangItem::Sized)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ fn evaluate_obligation<'tcx>(
|
|||
debug!("evaluate_obligation: goal={:#?}", goal);
|
||||
let ParamEnvAnd { param_env, value: predicate } = goal;
|
||||
|
||||
if sizedness_fast_path(tcx, predicate) {
|
||||
if sizedness_fast_path(tcx, predicate, param_env) {
|
||||
return Ok(EvaluationResult::EvaluatedToOk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ impl TypeId {
|
|||
|
||||
// This is a provenance-stripping memcpy.
|
||||
for (i, chunk) in self.data.iter().copied().enumerate() {
|
||||
let chunk = chunk.expose_provenance().to_ne_bytes();
|
||||
let chunk = chunk.addr().to_ne_bytes();
|
||||
let start = i * chunk.len();
|
||||
bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,15 +28,15 @@ pub trait AsyncIterator {
|
|||
/// async iterator state:
|
||||
///
|
||||
/// - `Poll::Pending` means that this async iterator's next value is not ready
|
||||
/// yet. Implementations will ensure that the current task will be notified
|
||||
/// when the next value may be ready.
|
||||
/// yet. Implementations will ensure that the current task will be notified
|
||||
/// when the next value may be ready.
|
||||
///
|
||||
/// - `Poll::Ready(Some(val))` means that the async iterator has successfully
|
||||
/// produced a value, `val`, and may produce further values on subsequent
|
||||
/// `poll_next` calls.
|
||||
/// produced a value, `val`, and may produce further values on subsequent
|
||||
/// `poll_next` calls.
|
||||
///
|
||||
/// - `Poll::Ready(None)` means that the async iterator has terminated, and
|
||||
/// `poll_next` should not be invoked again.
|
||||
/// `poll_next` should not be invoked again.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1482,13 +1482,14 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
|||
}
|
||||
}
|
||||
|
||||
fn default_chaining_impl<T: PointeeSized, U: PointeeSized>(
|
||||
fn default_chaining_impl<T, U>(
|
||||
lhs: &T,
|
||||
rhs: &U,
|
||||
p: impl FnOnce(Ordering) -> bool,
|
||||
) -> ControlFlow<bool>
|
||||
where
|
||||
T: PartialOrd<U>,
|
||||
T: PartialOrd<U> + PointeeSized,
|
||||
U: PointeeSized,
|
||||
{
|
||||
// It's important that this only call `partial_cmp` once, not call `eq` then
|
||||
// one of the relational operators. We don't want to `bcmp`-then-`memcp` a
|
||||
|
|
|
|||
|
|
@ -854,7 +854,6 @@ impl Display for Arguments<'_> {
|
|||
/// }";
|
||||
/// assert_eq!(format!("The origin is: {origin:#?}"), expected);
|
||||
/// ```
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented(
|
||||
on(
|
||||
|
|
|
|||
|
|
@ -1379,6 +1379,7 @@ pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f16::floor`](../../std/primitive.f16.html#method.floor)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn floorf16(x: f16) -> f16;
|
||||
|
|
@ -1386,6 +1387,7 @@ pub const unsafe fn floorf16(x: f16) -> f16;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f32::floor`](../../std/primitive.f32.html#method.floor)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn floorf32(x: f32) -> f32;
|
||||
|
|
@ -1393,6 +1395,7 @@ pub const unsafe fn floorf32(x: f32) -> f32;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f64::floor`](../../std/primitive.f64.html#method.floor)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn floorf64(x: f64) -> f64;
|
||||
|
|
@ -1400,6 +1403,7 @@ pub const unsafe fn floorf64(x: f64) -> f64;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f128::floor`](../../std/primitive.f128.html#method.floor)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn floorf128(x: f128) -> f128;
|
||||
|
|
@ -1408,6 +1412,7 @@ pub const unsafe fn floorf128(x: f128) -> f128;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f16::ceil`](../../std/primitive.f16.html#method.ceil)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn ceilf16(x: f16) -> f16;
|
||||
|
|
@ -1415,6 +1420,7 @@ pub const unsafe fn ceilf16(x: f16) -> f16;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f32::ceil`](../../std/primitive.f32.html#method.ceil)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn ceilf32(x: f32) -> f32;
|
||||
|
|
@ -1422,6 +1428,7 @@ pub const unsafe fn ceilf32(x: f32) -> f32;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f64::ceil`](../../std/primitive.f64.html#method.ceil)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn ceilf64(x: f64) -> f64;
|
||||
|
|
@ -1429,6 +1436,7 @@ pub const unsafe fn ceilf64(x: f64) -> f64;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f128::ceil`](../../std/primitive.f128.html#method.ceil)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn ceilf128(x: f128) -> f128;
|
||||
|
|
@ -1437,6 +1445,7 @@ pub const unsafe fn ceilf128(x: f128) -> f128;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f16::trunc`](../../std/primitive.f16.html#method.trunc)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn truncf16(x: f16) -> f16;
|
||||
|
|
@ -1444,6 +1453,7 @@ pub const unsafe fn truncf16(x: f16) -> f16;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f32::trunc`](../../std/primitive.f32.html#method.trunc)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn truncf32(x: f32) -> f32;
|
||||
|
|
@ -1451,6 +1461,7 @@ pub const unsafe fn truncf32(x: f32) -> f32;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f64::trunc`](../../std/primitive.f64.html#method.trunc)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn truncf64(x: f64) -> f64;
|
||||
|
|
@ -1458,6 +1469,7 @@ pub const unsafe fn truncf64(x: f64) -> f64;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f128::trunc`](../../std/primitive.f128.html#method.trunc)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn truncf128(x: f128) -> f128;
|
||||
|
|
@ -1467,6 +1479,7 @@ pub const unsafe fn truncf128(x: f128) -> f128;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const fn round_ties_even_f16(x: f16) -> f16;
|
||||
|
|
@ -1476,6 +1489,7 @@ pub const fn round_ties_even_f16(x: f16) -> f16;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const fn round_ties_even_f32(x: f32) -> f32;
|
||||
|
|
@ -1485,6 +1499,7 @@ pub const fn round_ties_even_f32(x: f32) -> f32;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const fn round_ties_even_f64(x: f64) -> f64;
|
||||
|
|
@ -1494,6 +1509,7 @@ pub const fn round_ties_even_f64(x: f64) -> f64;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const fn round_ties_even_f128(x: f128) -> f128;
|
||||
|
|
@ -1502,6 +1518,7 @@ pub const fn round_ties_even_f128(x: f128) -> f128;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f16::round`](../../std/primitive.f16.html#method.round)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn roundf16(x: f16) -> f16;
|
||||
|
|
@ -1509,6 +1526,7 @@ pub const unsafe fn roundf16(x: f16) -> f16;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f32::round`](../../std/primitive.f32.html#method.round)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn roundf32(x: f32) -> f32;
|
||||
|
|
@ -1516,6 +1534,7 @@ pub const unsafe fn roundf32(x: f32) -> f32;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f64::round`](../../std/primitive.f64.html#method.round)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn roundf64(x: f64) -> f64;
|
||||
|
|
@ -1523,6 +1542,7 @@ pub const unsafe fn roundf64(x: f64) -> f64;
|
|||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`f128::round`](../../std/primitive.f128.html#method.round)
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_nounwind]
|
||||
pub const unsafe fn roundf128(x: f128) -> f128;
|
||||
|
|
|
|||
|
|
@ -436,7 +436,6 @@ pub trait Extend<A> {
|
|||
/// **For implementors:** For a collection to unsafely rely on this method's safety precondition (that is,
|
||||
/// invoke UB if they are violated), it must implement `extend_reserve` correctly. In other words,
|
||||
/// callers may assume that if they `extend_reserve`ed enough space they can call this method.
|
||||
|
||||
// This method is for internal usage only. It is only on the trait because of specialization's limitations.
|
||||
#[unstable(feature = "extend_one_unchecked", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
|
|
|
|||
|
|
@ -3414,10 +3414,10 @@ pub trait Iterator {
|
|||
/// ```
|
||||
#[stable(feature = "iter_copied", since = "1.36.0")]
|
||||
#[rustc_diagnostic_item = "iter_copied"]
|
||||
fn copied<'a, T: 'a>(self) -> Copied<Self>
|
||||
fn copied<'a, T>(self) -> Copied<Self>
|
||||
where
|
||||
T: Copy + 'a,
|
||||
Self: Sized + Iterator<Item = &'a T>,
|
||||
T: Copy,
|
||||
{
|
||||
Copied::new(self)
|
||||
}
|
||||
|
|
@ -3462,10 +3462,10 @@ pub trait Iterator {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "iter_cloned"]
|
||||
fn cloned<'a, T: 'a>(self) -> Cloned<Self>
|
||||
fn cloned<'a, T>(self) -> Cloned<Self>
|
||||
where
|
||||
T: Clone + 'a,
|
||||
Self: Sized + Iterator<Item = &'a T>,
|
||||
T: Clone,
|
||||
{
|
||||
Cloned::new(self)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@
|
|||
//! return. You should mark your implementation using `#[panic_handler]`.
|
||||
//!
|
||||
//! * `rust_eh_personality` - is used by the failure mechanisms of the
|
||||
//! compiler. This is often mapped to GCC's personality function, but crates
|
||||
//! which do not trigger a panic can be assured that this function is never
|
||||
//! called. The `lang` attribute is called `eh_personality`.
|
||||
//! compiler. This is often mapped to GCC's personality function, but crates
|
||||
//! which do not trigger a panic can be assured that this function is never
|
||||
//! called. The `lang` attribute is called `eh_personality`.
|
||||
|
||||
#![stable(feature = "core", since = "1.6.0")]
|
||||
#![doc(
|
||||
|
|
|
|||
|
|
@ -1005,28 +1005,6 @@ impl<T> MaybeUninit<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::assume_init_ref`].
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent assume_init_ref method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
|
||||
// SAFETY: Same for both methods.
|
||||
unsafe { slice.assume_init_ref() }
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::assume_init_mut`].
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent assume_init_mut method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
|
||||
// SAFETY: Same for both methods.
|
||||
unsafe { slice.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Gets a pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
|
|
@ -1040,94 +1018,6 @@ impl<T> MaybeUninit<T> {
|
|||
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
|
||||
this.as_mut_ptr() as *mut T
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_copy_of_slice`].
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_copy_of_slice method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
this.write_copy_of_slice(src)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_clone_of_slice`].
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_clone_of_slice method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn clone_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
this.write_clone_of_slice(src)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_filled`].
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_filled method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
this.write_filled(value)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_with`].
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_with method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T]
|
||||
where
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
this.write_with(|_| f())
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_iter`].
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_iter method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn fill_from<'a, I>(
|
||||
this: &'a mut [MaybeUninit<T>],
|
||||
it: I,
|
||||
) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
this.write_iter(it)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::as_bytes`].
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent as_bytes method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] {
|
||||
this.as_bytes()
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::as_bytes_mut`].
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent as_bytes_mut method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] {
|
||||
this.as_bytes_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> [MaybeUninit<T>] {
|
||||
|
|
@ -1304,7 +1194,7 @@ impl<T> [MaybeUninit<T>] {
|
|||
/// Fills a slice with elements returned by calling a closure for each index.
|
||||
///
|
||||
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
|
||||
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
|
||||
/// [slice::write_filled]. If you want to use the `Default` trait to generate values, you can
|
||||
/// pass [`|_| Default::default()`][Default::default] as the argument.
|
||||
///
|
||||
/// # Panics
|
||||
|
|
@ -1463,7 +1353,7 @@ impl<T> [MaybeUninit<T>] {
|
|||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
|
||||
/// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit);
|
||||
/// let uninit_bytes = uninit.as_bytes_mut();
|
||||
/// uninit_bytes.write_copy_of_slice(&[0x12, 0x34, 0x56, 0x78]);
|
||||
/// let vals = unsafe { uninit.assume_init_ref() };
|
||||
/// if cfg!(target_endian = "little") {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub use crate::intrinsics::transmute;
|
|||
/// * If you want to leak memory, see [`Box::leak`].
|
||||
/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`].
|
||||
/// * If you want to dispose of a value properly, running its destructor, see
|
||||
/// [`mem::drop`].
|
||||
/// [`mem::drop`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
|
|
|
|||
|
|
@ -787,7 +787,6 @@ impl Ipv4Addr {
|
|||
/// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
|
||||
/// [unspecified address]: Ipv4Addr::UNSPECIFIED
|
||||
/// [broadcast address]: Ipv4Addr::BROADCAST
|
||||
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn floor(self) -> f128 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1478,7 +1477,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn ceil(self) -> f128 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1514,7 +1512,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round(self) -> f128 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1548,7 +1545,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round_ties_even(self) -> f128 {
|
||||
intrinsics::round_ties_even_f128(self)
|
||||
|
|
@ -1580,7 +1576,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn trunc(self) -> f128 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1611,7 +1606,6 @@ impl f128 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f128", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn fract(self) -> f128 {
|
||||
self - self.trunc()
|
||||
|
|
|
|||
|
|
@ -1424,7 +1424,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn floor(self) -> f16 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1454,7 +1453,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn ceil(self) -> f16 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1490,7 +1488,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round(self) -> f16 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1524,7 +1521,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round_ties_even(self) -> f16 {
|
||||
intrinsics::round_ties_even_f16(self)
|
||||
|
|
@ -1556,7 +1552,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn trunc(self) -> f16 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1587,7 +1582,6 @@ impl f16 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
#[rustc_const_unstable(feature = "f16", issue = "116909")]
|
||||
// #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn fract(self) -> f16 {
|
||||
self - self.trunc()
|
||||
|
|
|
|||
|
|
@ -1591,7 +1591,6 @@ pub mod math {
|
|||
/// [`f32::floor`]: ../../../std/primitive.f32.html#method.floor
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn floor(x: f32) -> f32 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1622,7 +1621,6 @@ pub mod math {
|
|||
#[doc(alias = "ceiling")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
pub const fn ceil(x: f32) -> f32 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
unsafe { intrinsics::ceilf32(x) }
|
||||
|
|
@ -1657,7 +1655,6 @@ pub mod math {
|
|||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
pub const fn round(x: f32) -> f32 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
unsafe { intrinsics::roundf32(x) }
|
||||
|
|
@ -1691,7 +1688,6 @@ pub mod math {
|
|||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
pub const fn round_ties_even(x: f32) -> f32 {
|
||||
intrinsics::round_ties_even_f32(x)
|
||||
}
|
||||
|
|
@ -1722,7 +1718,6 @@ pub mod math {
|
|||
#[doc(alias = "truncate")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
pub const fn trunc(x: f32) -> f32 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
unsafe { intrinsics::truncf32(x) }
|
||||
|
|
@ -1752,7 +1747,6 @@ pub mod math {
|
|||
/// [`f32::fract`]: ../../../std/primitive.f32.html#method.fract
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn fract(x: f32) -> f32 {
|
||||
x - trunc(x)
|
||||
|
|
|
|||
|
|
@ -1589,7 +1589,6 @@ pub mod math {
|
|||
/// [`f64::floor`]: ../../../std/primitive.f64.html#method.floor
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn floor(x: f64) -> f64 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1619,7 +1618,6 @@ pub mod math {
|
|||
#[inline]
|
||||
#[doc(alias = "ceiling")]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn ceil(x: f64) -> f64 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1654,7 +1652,6 @@ pub mod math {
|
|||
/// [`f64::round`]: ../../../std/primitive.f64.html#method.round
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round(x: f64) -> f64 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1688,7 +1685,6 @@ pub mod math {
|
|||
/// [`f64::round_ties_even`]: ../../../std/primitive.f64.html#method.round_ties_even
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn round_ties_even(x: f64) -> f64 {
|
||||
intrinsics::round_ties_even_f64(x)
|
||||
|
|
@ -1719,7 +1715,6 @@ pub mod math {
|
|||
#[inline]
|
||||
#[doc(alias = "truncate")]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn trunc(x: f64) -> f64 {
|
||||
// SAFETY: intrinsic with no preconditions
|
||||
|
|
@ -1750,7 +1745,6 @@ pub mod math {
|
|||
/// [`f64::fract`]: ../../../std/primitive.f64.html#method.fract
|
||||
#[inline]
|
||||
#[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
pub const fn fract(x: f64) -> f64 {
|
||||
x - trunc(x)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/// These functions compute the integer logarithm of their type, assuming
|
||||
/// that someone has already checked that the value is strictly positive.
|
||||
//! These functions compute the integer logarithm of their type, assuming
|
||||
//! that someone has already checked that the value is strictly positive.
|
||||
|
||||
// 0 < val <= u8::MAX
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -556,7 +556,7 @@ macro_rules! uint_impl {
|
|||
pub const fn strict_add(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_add(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
}
|
||||
}
|
||||
|
||||
/// Unchecked integer addition. Computes `self + rhs`, assuming overflow
|
||||
/// cannot occur.
|
||||
|
|
@ -653,7 +653,7 @@ macro_rules! uint_impl {
|
|||
pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
|
||||
let (a, b) = self.overflowing_add_signed(rhs);
|
||||
if b { overflow_panic::add() } else { a }
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked integer subtraction. Computes `self - rhs`, returning
|
||||
/// `None` if overflow occurred.
|
||||
|
|
@ -713,7 +713,7 @@ macro_rules! uint_impl {
|
|||
pub const fn strict_sub(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_sub(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
}
|
||||
}
|
||||
|
||||
/// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
|
||||
/// cannot occur.
|
||||
|
|
@ -805,6 +805,43 @@ macro_rules! uint_impl {
|
|||
}
|
||||
}
|
||||
|
||||
/// Strict subtraction with a signed integer. Computes `self - rhs`,
|
||||
/// panicking if overflow occurred.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// ## Overflow behavior
|
||||
///
|
||||
/// This function will always panic on overflow, regardless of whether overflow checks are enabled.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_overflow_ops)]
|
||||
#[doc = concat!("assert_eq!(3", stringify!($SelfT), ".strict_sub_signed(2), 1);")]
|
||||
/// ```
|
||||
///
|
||||
/// The following panic because of overflow:
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(strict_overflow_ops)]
|
||||
#[doc = concat!("let _ = 1", stringify!($SelfT), ".strict_sub_signed(2);")]
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(strict_overflow_ops)]
|
||||
#[doc = concat!("let _ = (", stringify!($SelfT), "::MAX).strict_sub_signed(-1);")]
|
||||
/// ```
|
||||
#[unstable(feature = "strict_overflow_ops", issue = "118260")]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub const fn strict_sub_signed(self, rhs: $SignedT) -> Self {
|
||||
let (a, b) = self.overflowing_sub_signed(rhs);
|
||||
if b { overflow_panic::sub() } else { a }
|
||||
}
|
||||
|
||||
#[doc = concat!(
|
||||
"Checked integer subtraction. Computes `self - rhs` and checks if the result fits into an [`",
|
||||
stringify!($SignedT), "`], returning `None` if overflow occurred."
|
||||
|
|
@ -913,7 +950,7 @@ macro_rules! uint_impl {
|
|||
pub const fn strict_mul(self, rhs: Self) -> Self {
|
||||
let (a, b) = self.overflowing_mul(rhs);
|
||||
if b { overflow_panic::mul() } else { a }
|
||||
}
|
||||
}
|
||||
|
||||
/// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
|
||||
/// cannot occur.
|
||||
|
|
|
|||
|
|
@ -1363,7 +1363,6 @@ mod prim_f16 {}
|
|||
/// x = a + b + c + d; // As written
|
||||
/// x = (a + c) + (b + d); // Reordered to shorten critical path and enable vectorization
|
||||
/// ```
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
mod prim_f32 {}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,24 +10,24 @@ When calling this method, you have to ensure that *either* the pointer is null *
|
|||
all of the following is true:
|
||||
|
||||
* The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
|
||||
and it must be properly aligned. This means in particular:
|
||||
and it must be properly aligned. This means in particular:
|
||||
|
||||
* The entire memory range of this slice must be contained within a single [allocation]!
|
||||
Slices can never span across multiple allocations.
|
||||
Slices can never span across multiple allocations.
|
||||
|
||||
* The pointer must be aligned even for zero-length slices. One
|
||||
reason for this is that enum layout optimizations may rely on references
|
||||
(including slices of any length) being aligned and non-null to distinguish
|
||||
them from other data. You can obtain a pointer that is usable as `data`
|
||||
for zero-length slices using [`NonNull::dangling()`].
|
||||
reason for this is that enum layout optimizations may rely on references
|
||||
(including slices of any length) being aligned and non-null to distinguish
|
||||
them from other data. You can obtain a pointer that is usable as `data`
|
||||
for zero-length slices using [`NonNull::dangling()`].
|
||||
|
||||
* The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
|
||||
See the safety documentation of [`pointer::offset`].
|
||||
See the safety documentation of [`pointer::offset`].
|
||||
|
||||
* You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
|
||||
arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
||||
In particular, while this reference exists, the memory the pointer points to must
|
||||
not get mutated (except inside `UnsafeCell`).
|
||||
arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
|
||||
In particular, while this reference exists, the memory the pointer points to must
|
||||
not get mutated (except inside `UnsafeCell`).
|
||||
|
||||
This applies even if the result of this method is unused!
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@
|
|||
//! undefined behavior to perform two concurrent accesses to the same location from different
|
||||
//! threads unless both accesses only read from memory. Notice that this explicitly
|
||||
//! includes [`read_volatile`] and [`write_volatile`]: Volatile accesses cannot
|
||||
//! be used for inter-thread synchronization.
|
||||
//! be used for inter-thread synchronization, regardless of whether they are acting on
|
||||
//! Rust memory or not.
|
||||
//! * The result of casting a reference to a pointer is valid for as long as the
|
||||
//! underlying allocation is live and no reference (just raw pointers) is used to
|
||||
//! access the same memory. That is, reference and pointer accesses cannot be
|
||||
|
|
@ -114,6 +115,10 @@
|
|||
//! fully contiguous (i.e., has no "holes"), there is no guarantee that this
|
||||
//! will not change in the future.
|
||||
//!
|
||||
//! Allocations must behave like "normal" memory: in particular, reads must not have
|
||||
//! side-effects, and writes must become visible to other threads using the usual synchronization
|
||||
//! primitives.
|
||||
//!
|
||||
//! For any allocation with `base` address, `size`, and a set of
|
||||
//! `addresses`, the following are guaranteed:
|
||||
//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base +
|
||||
|
|
@ -2021,54 +2026,61 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Performs a volatile read of the value from `src` without moving it. This
|
||||
/// leaves the memory in `src` unchanged.
|
||||
/// Performs a volatile read of the value from `src` without moving it.
|
||||
///
|
||||
/// Volatile operations are intended to act on I/O memory, and are guaranteed
|
||||
/// to not be elided or reordered by the compiler across other volatile
|
||||
/// operations.
|
||||
/// Volatile operations are intended to act on I/O memory. As such, they are considered externally
|
||||
/// observable events (just like syscalls, but less opaque), and are guaranteed to not be elided or
|
||||
/// reordered by the compiler across other externally observable events. With this in mind, there
|
||||
/// are two cases of usage that need to be distinguished:
|
||||
///
|
||||
/// # Notes
|
||||
/// - When a volatile operation is used for memory inside an [allocation], it behaves exactly like
|
||||
/// [`read`], except for the additional guarantee that it won't be elided or reordered (see
|
||||
/// above). This implies that the operation will actually access memory and not e.g. be lowered to
|
||||
/// reusing data from a previous read. Other than that, all the usual rules for memory accesses
|
||||
/// apply (including provenance). In particular, just like in C, whether an operation is volatile
|
||||
/// has no bearing whatsoever on questions involving concurrent accesses from multiple threads.
|
||||
/// Volatile accesses behave exactly like non-atomic accesses in that regard.
|
||||
///
|
||||
/// Rust does not currently have a rigorously and formally defined memory model,
|
||||
/// so the precise semantics of what "volatile" means here is subject to change
|
||||
/// over time. That being said, the semantics will almost always end up pretty
|
||||
/// similar to [C11's definition of volatile][c11].
|
||||
/// - Volatile operations, however, may also be used to access memory that is _outside_ of any Rust
|
||||
/// allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is
|
||||
/// typically used for CPU and peripheral registers that must be accessed via an I/O memory
|
||||
/// mapping, most commonly at fixed addresses reserved by the hardware. These often have special
|
||||
/// semantics associated to their manipulation, and cannot be used as general purpose memory.
|
||||
/// Here, any address value is possible, including 0 and [`usize::MAX`], so long as the semantics
|
||||
/// of such a read are well-defined by the target hardware. The provenance of the pointer is
|
||||
/// irrelevant, and it can be created with [`without_provenance`]. The access must not trap. It
|
||||
/// can cause side-effects, but those must not affect Rust-allocated memory in any way. This
|
||||
/// access is still not considered [atomic], and as such it cannot be used for inter-thread
|
||||
/// synchronization.
|
||||
///
|
||||
/// The compiler shouldn't change the relative order or number of volatile
|
||||
/// memory operations. However, volatile memory operations on zero-sized types
|
||||
/// (e.g., if a zero-sized type is passed to `read_volatile`) are noops
|
||||
/// and may be ignored.
|
||||
/// Note that volatile memory operations where T is a zero-sized type are noops and may be ignored.
|
||||
///
|
||||
/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
|
||||
/// [allocation]: crate::ptr#allocated-object
|
||||
/// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of whether `T` is
|
||||
/// [`Copy`]. If `T` is not [`Copy`], using both the returned value and the value at `*src` can
|
||||
/// [violate memory safety][read-ownership]. However, storing non-[`Copy`] types in volatile memory
|
||||
/// is almost certainly incorrect.
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `src` must be [valid] for reads.
|
||||
/// * `src` must be either [valid] for reads, or it must point to memory outside of all Rust
|
||||
/// allocations and reading from that memory must:
|
||||
/// - not trap, and
|
||||
/// - not cause any memory inside a Rust allocation to be modified.
|
||||
///
|
||||
/// * `src` must be properly aligned.
|
||||
///
|
||||
/// * `src` must point to a properly initialized value of type `T`.
|
||||
///
|
||||
/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
|
||||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
|
||||
/// value and the value at `*src` can [violate memory safety][read-ownership].
|
||||
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
|
||||
/// incorrect.
|
||||
/// * Reading from `src` must produce a properly initialized value of type `T`.
|
||||
///
|
||||
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
|
||||
///
|
||||
/// [valid]: self#safety
|
||||
/// [read-ownership]: read#ownership-of-the-returned-value
|
||||
///
|
||||
/// Just like in C, whether an operation is volatile has no bearing whatsoever
|
||||
/// on questions involving concurrent access from multiple threads. Volatile
|
||||
/// accesses behave exactly like non-atomic accesses in that regard. In particular,
|
||||
/// a race between a `read_volatile` and any write operation to the same location
|
||||
/// is undefined behavior.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
|
@ -2090,50 +2102,63 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
|||
unsafe {
|
||||
ub_checks::assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
"ptr::read_volatile requires that the pointer argument is aligned and non-null",
|
||||
"ptr::read_volatile requires that the pointer argument is aligned",
|
||||
(
|
||||
addr: *const () = src as *const (),
|
||||
align: usize = align_of::<T>(),
|
||||
is_zst: bool = T::IS_ZST,
|
||||
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
|
||||
) => ub_checks::maybe_is_aligned(addr, align)
|
||||
);
|
||||
intrinsics::volatile_load(src)
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a volatile write of a memory location with the given value without
|
||||
/// reading or dropping the old value.
|
||||
/// Performs a volatile write of a memory location with the given value without reading or dropping
|
||||
/// the old value.
|
||||
///
|
||||
/// Volatile operations are intended to act on I/O memory, and are guaranteed
|
||||
/// to not be elided or reordered by the compiler across other volatile
|
||||
/// operations.
|
||||
/// Volatile operations are intended to act on I/O memory. As such, they are considered externally
|
||||
/// observable events (just like syscalls), and are guaranteed to not be elided or reordered by the
|
||||
/// compiler across other externally observable events. With this in mind, there are two cases of
|
||||
/// usage that need to be distinguished:
|
||||
///
|
||||
/// `write_volatile` does not drop the contents of `dst`. This is safe, but it
|
||||
/// could leak allocations or resources, so care should be taken not to overwrite
|
||||
/// an object that should be dropped.
|
||||
/// - When a volatile operation is used for memory inside an [allocation], it behaves exactly like
|
||||
/// [`write`][write()], except for the additional guarantee that it won't be elided or reordered
|
||||
/// (see above). This implies that the operation will actually access memory and not e.g. be
|
||||
/// lowered to a register access. Other than that, all the usual rules for memory accesses apply
|
||||
/// (including provenance). In particular, just like in C, whether an operation is volatile has no
|
||||
/// bearing whatsoever on questions involving concurrent access from multiple threads. Volatile
|
||||
/// accesses behave exactly like non-atomic accesses in that regard.
|
||||
///
|
||||
/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
|
||||
/// location pointed to by `dst`.
|
||||
/// - Volatile operations, however, may also be used to access memory that is _outside_ of any Rust
|
||||
/// allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is
|
||||
/// typically used for CPU and peripheral registers that must be accessed via an I/O memory
|
||||
/// mapping, most commonly at fixed addresses reserved by the hardware. These often have special
|
||||
/// semantics associated to their manipulation, and cannot be used as general purpose memory.
|
||||
/// Here, any address value is possible, including 0 and [`usize::MAX`], so long as the semantics
|
||||
/// of such a write are well-defined by the target hardware. The provenance of the pointer is
|
||||
/// irrelevant, and it can be created with [`without_provenance`]. The access must not trap. It
|
||||
/// can cause side-effects, but those must not affect Rust-allocated memory in any way. This
|
||||
/// access is still not considered [atomic], and as such it cannot be used for inter-thread
|
||||
/// synchronization.
|
||||
///
|
||||
/// # Notes
|
||||
/// Note that volatile memory operations on zero-sized types (e.g., if a zero-sized type is passed
|
||||
/// to `write_volatile`) are noops and may be ignored.
|
||||
///
|
||||
/// Rust does not currently have a rigorously and formally defined memory model,
|
||||
/// so the precise semantics of what "volatile" means here is subject to change
|
||||
/// over time. That being said, the semantics will almost always end up pretty
|
||||
/// similar to [C11's definition of volatile][c11].
|
||||
/// `write_volatile` does not drop the contents of `dst`. This is safe, but it could leak
|
||||
/// allocations or resources, so care should be taken not to overwrite an object that should be
|
||||
/// dropped when operating on Rust memory. Additionally, it does not drop `src`. Semantically, `src`
|
||||
/// is moved into the location pointed to by `dst`.
|
||||
///
|
||||
/// The compiler shouldn't change the relative order or number of volatile
|
||||
/// memory operations. However, volatile memory operations on zero-sized types
|
||||
/// (e.g., if a zero-sized type is passed to `write_volatile`) are noops
|
||||
/// and may be ignored.
|
||||
///
|
||||
/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
|
||||
/// [allocation]: crate::ptr#allocated-object
|
||||
/// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Behavior is undefined if any of the following conditions are violated:
|
||||
///
|
||||
/// * `dst` must be [valid] for writes.
|
||||
/// * `dst` must be either [valid] for writes, or it must point to memory outside of all Rust
|
||||
/// allocations and writing to that memory must:
|
||||
/// - not trap, and
|
||||
/// - not cause any memory inside a Rust allocation to be modified.
|
||||
///
|
||||
/// * `dst` must be properly aligned.
|
||||
///
|
||||
|
|
@ -2141,12 +2166,6 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
|||
///
|
||||
/// [valid]: self#safety
|
||||
///
|
||||
/// Just like in C, whether an operation is volatile has no bearing whatsoever
|
||||
/// on questions involving concurrent access from multiple threads. Volatile
|
||||
/// accesses behave exactly like non-atomic accesses in that regard. In particular,
|
||||
/// a race between a `write_volatile` and any other operation (reading or writing)
|
||||
/// on the same location is undefined behavior.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
|
@ -2170,12 +2189,11 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
|
|||
unsafe {
|
||||
ub_checks::assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
"ptr::write_volatile requires that the pointer argument is aligned and non-null",
|
||||
"ptr::write_volatile requires that the pointer argument is aligned",
|
||||
(
|
||||
addr: *mut () = dst as *mut (),
|
||||
align: usize = align_of::<T>(),
|
||||
is_zst: bool = T::IS_ZST,
|
||||
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
|
||||
) => ub_checks::maybe_is_aligned(addr, align)
|
||||
);
|
||||
intrinsics::volatile_store(dst, src);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2651,7 +2651,6 @@ impl str {
|
|||
/// you're trying to parse into.
|
||||
///
|
||||
/// `parse` can parse into any type that implements the [`FromStr`] trait.
|
||||
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
|
|
|||
|
|
@ -120,13 +120,25 @@ pub(crate) const fn maybe_is_aligned_and_not_null(
|
|||
align: usize,
|
||||
is_zst: bool,
|
||||
) -> bool {
|
||||
// This is just for safety checks so we can const_eval_select.
|
||||
maybe_is_aligned(ptr, align) && (is_zst || !ptr.is_null())
|
||||
}
|
||||
|
||||
/// Checks whether `ptr` is properly aligned with respect to the given alignment.
|
||||
///
|
||||
/// In `const` this is approximate and can fail spuriously. It is primarily intended
|
||||
/// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the
|
||||
/// check is anyway not executed in `const`.
|
||||
#[inline]
|
||||
#[rustc_allow_const_fn_unstable(const_eval_select)]
|
||||
pub(crate) const fn maybe_is_aligned(ptr: *const (), align: usize) -> bool {
|
||||
// This is just for safety checks so we can const_eval_select.
|
||||
const_eval_select!(
|
||||
@capture { ptr: *const (), align: usize, is_zst: bool } -> bool:
|
||||
@capture { ptr: *const (), align: usize } -> bool:
|
||||
if const {
|
||||
is_zst || !ptr.is_null()
|
||||
true
|
||||
} else {
|
||||
ptr.is_aligned_to(align) && (is_zst || !ptr.is_null())
|
||||
ptr.is_aligned_to(align)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#![feature(const_deref)]
|
||||
#![feature(const_destruct)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_float_round_methods)]
|
||||
#![feature(const_ops)]
|
||||
#![feature(const_ref_cell)]
|
||||
#![feature(const_trait_impl)]
|
||||
|
|
|
|||
|
|
@ -329,7 +329,6 @@
|
|||
#![feature(bstr_internals)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(clone_to_uninit)]
|
||||
#![feature(const_float_round_methods)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_io_borrowed_buf)]
|
||||
#![feature(duration_constants)]
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn floor(self) -> f32 {
|
||||
core::f32::math::floor(self)
|
||||
|
|
@ -67,7 +67,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn ceil(self) -> f32 {
|
||||
core::f32::math::ceil(self)
|
||||
|
|
@ -96,7 +96,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn round(self) -> f32 {
|
||||
core::f32::math::round(self)
|
||||
|
|
@ -123,7 +123,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn round_ties_even(self) -> f32 {
|
||||
core::f32::math::round_ties_even(self)
|
||||
|
|
@ -149,7 +149,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn trunc(self) -> f32 {
|
||||
core::f32::math::trunc(self)
|
||||
|
|
@ -173,7 +173,7 @@ impl f32 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn fract(self) -> f32 {
|
||||
core::f32::math::fract(self)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn floor(self) -> f64 {
|
||||
core::f64::math::floor(self)
|
||||
|
|
@ -67,7 +67,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn ceil(self) -> f64 {
|
||||
core::f64::math::ceil(self)
|
||||
|
|
@ -96,7 +96,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn round(self) -> f64 {
|
||||
core::f64::math::round(self)
|
||||
|
|
@ -123,7 +123,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "round_ties_even", since = "1.77.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn round_ties_even(self) -> f64 {
|
||||
core::f64::math::round_ties_even(self)
|
||||
|
|
@ -149,7 +149,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn trunc(self) -> f64 {
|
||||
core::f64::math::trunc(self)
|
||||
|
|
@ -173,7 +173,7 @@ impl f64 {
|
|||
#[rustc_allow_incoherent_impl]
|
||||
#[must_use = "method returns a new number and does not mutate the original value"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
|
||||
#[rustc_const_stable(feature = "const_float_round_methods", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn fract(self) -> f64 {
|
||||
core::f64::math::fract(self)
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ impl Step for CodegenBackend {
|
|||
cargo
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
|
||||
rustc_cargo_env(builder, &mut cargo, target, build_compiler.stage);
|
||||
rustc_cargo_env(builder, &mut cargo, target);
|
||||
|
||||
let _guard = builder.msg_check(format!("rustc_codegen_{backend}"), target, None);
|
||||
|
||||
|
|
|
|||
|
|
@ -1316,15 +1316,10 @@ pub fn rustc_cargo(
|
|||
cargo.env("RUSTC_WRAPPER", ccache);
|
||||
}
|
||||
|
||||
rustc_cargo_env(builder, cargo, target, build_compiler.stage);
|
||||
rustc_cargo_env(builder, cargo, target);
|
||||
}
|
||||
|
||||
pub fn rustc_cargo_env(
|
||||
builder: &Builder<'_>,
|
||||
cargo: &mut Cargo,
|
||||
target: TargetSelection,
|
||||
build_stage: u32,
|
||||
) {
|
||||
pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
|
||||
// Set some configuration variables picked up by build scripts and
|
||||
// the compiler alike
|
||||
cargo
|
||||
|
|
@ -1379,18 +1374,24 @@ pub fn rustc_cargo_env(
|
|||
cargo.rustflag("--cfg=llvm_enzyme");
|
||||
}
|
||||
|
||||
// Note that this is disabled if LLVM itself is disabled or we're in a check
|
||||
// build. If we are in a check build we still go ahead here presuming we've
|
||||
// detected that LLVM is already built and good to go which helps prevent
|
||||
// busting caches (e.g. like #71152).
|
||||
// These conditionals represent a tension between three forces:
|
||||
// - For non-check builds, we need to define some LLVM-related environment
|
||||
// variables, requiring LLVM to have been built.
|
||||
// - For check builds, we want to avoid building LLVM if possible.
|
||||
// - Check builds and non-check builds should have the same environment if
|
||||
// possible, to avoid unnecessary rebuilds due to cache-busting.
|
||||
//
|
||||
// Therefore we try to avoid building LLVM for check builds, but only if
|
||||
// building LLVM would be expensive. If "building" LLVM is cheap
|
||||
// (i.e. it's already built or is downloadable), we prefer to maintain a
|
||||
// consistent environment between check and non-check builds.
|
||||
if builder.config.llvm_enabled(target) {
|
||||
let building_is_expensive =
|
||||
let building_llvm_is_expensive =
|
||||
crate::core::build_steps::llvm::prebuilt_llvm_config(builder, target, false)
|
||||
.should_build();
|
||||
// `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler
|
||||
let can_skip_build = builder.kind == Kind::Check && builder.top_stage == build_stage;
|
||||
let should_skip_build = building_is_expensive && can_skip_build;
|
||||
if !should_skip_build {
|
||||
|
||||
let skip_llvm = (builder.kind == Kind::Check) && building_llvm_is_expensive;
|
||||
if !skip_llvm {
|
||||
rustc_llvm_env(builder, cargo, target)
|
||||
}
|
||||
}
|
||||
|
|
@ -1407,6 +1408,9 @@ pub fn rustc_cargo_env(
|
|||
|
||||
/// Pass down configuration from the LLVM build into the build of
|
||||
/// rustc_llvm and rustc_codegen_llvm.
|
||||
///
|
||||
/// Note that this has the side-effect of _building LLVM_, which is sometimes
|
||||
/// unwanted (e.g. for check builds).
|
||||
fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
|
||||
if builder.config.is_rust_llvm(target) {
|
||||
cargo.env("LLVM_RUSTLLVM", "1");
|
||||
|
|
@ -1665,7 +1669,7 @@ impl Step for CodegenBackend {
|
|||
cargo
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
|
||||
rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
|
||||
rustc_cargo_env(builder, &mut cargo, target);
|
||||
|
||||
// Ideally, we'd have a separate step for the individual codegen backends,
|
||||
// like we have in tests (test::CodegenGCC) but that would require a lot of restructuring.
|
||||
|
|
|
|||
|
|
@ -1757,6 +1757,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
cmd.arg("--host").arg(&*compiler.host.triple);
|
||||
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
|
||||
|
||||
if let Some(codegen_backend) = builder.config.default_codegen_backend(compiler.host) {
|
||||
cmd.arg("--codegen-backend").arg(&codegen_backend);
|
||||
}
|
||||
|
||||
if builder.build.config.llvm_enzyme {
|
||||
cmd.arg("--has-enzyme");
|
||||
}
|
||||
|
|
@ -1810,7 +1814,24 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
}
|
||||
|
||||
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
|
||||
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
||||
flags.push(format!(
|
||||
"-Cdebuginfo={}",
|
||||
if suite == "codegen" {
|
||||
// codegen tests typically check LLVM IR and are sensitive to additional debuginfo.
|
||||
// So do not apply `rust.debuginfo-level-tests` for codegen tests.
|
||||
if builder.config.rust_debuginfo_level_tests
|
||||
!= crate::core::config::DebuginfoLevel::None
|
||||
{
|
||||
println!(
|
||||
"NOTE: ignoring `rust.debuginfo-level-tests={}` for codegen tests",
|
||||
builder.config.rust_debuginfo_level_tests
|
||||
);
|
||||
}
|
||||
crate::core::config::DebuginfoLevel::None
|
||||
} else {
|
||||
builder.config.rust_debuginfo_level_tests
|
||||
}
|
||||
));
|
||||
flags.extend(builder.config.cmd.compiletest_rustc_args().iter().map(|s| s.to_string()));
|
||||
|
||||
if suite != "mir-opt" {
|
||||
|
|
@ -3387,7 +3408,7 @@ impl Step for CodegenCranelift {
|
|||
cargo
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join("compiler/rustc_codegen_cranelift/build_system/Cargo.toml"));
|
||||
compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
|
||||
compile::rustc_cargo_env(builder, &mut cargo, target);
|
||||
|
||||
// Avoid incremental cache issues when changing rustc
|
||||
cargo.env("CARGO_BUILD_INCREMENTAL", "false");
|
||||
|
|
@ -3519,7 +3540,7 @@ impl Step for CodegenGCC {
|
|||
cargo
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml"));
|
||||
compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
|
||||
compile::rustc_cargo_env(builder, &mut cargo, target);
|
||||
add_cg_gcc_cargo_flags(&mut cargo, &gcc);
|
||||
|
||||
// Avoid incremental cache issues when changing rustc
|
||||
|
|
|
|||
|
|
@ -712,7 +712,11 @@ mod snapshot {
|
|||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_rustc_no_explicit_stage() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
ctx.config("build")
|
||||
.path("rustc")
|
||||
|
|
@ -1303,17 +1307,19 @@ mod snapshot {
|
|||
ctx.config("check")
|
||||
.path("compiler")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> cranelift 1 <host>
|
||||
[check] rustc 0 <host> -> gcc 1 <host>
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_rustc_no_explicit_stage() {
|
||||
let ctx = TestCtx::new();
|
||||
insta::assert_snapshot!(
|
||||
ctx.config("check")
|
||||
.path("rustc")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
");
|
||||
}
|
||||
|
|
@ -1333,7 +1339,6 @@ mod snapshot {
|
|||
.path("compiler")
|
||||
.stage(1)
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> cranelift 1 <host>
|
||||
[check] rustc 0 <host> -> gcc 1 <host>
|
||||
|
|
@ -1465,7 +1470,6 @@ mod snapshot {
|
|||
.paths(&["library", "compiler"])
|
||||
.args(&args)
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> cranelift 1 <host>
|
||||
[check] rustc 0 <host> -> gcc 1 <host>
|
||||
|
|
@ -1479,7 +1483,6 @@ mod snapshot {
|
|||
ctx.config("check")
|
||||
.path("miri")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> Miri 1 <host>
|
||||
");
|
||||
|
|
@ -1500,7 +1503,6 @@ mod snapshot {
|
|||
.path("miri")
|
||||
.stage(1)
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> Miri 1 <host>
|
||||
");
|
||||
|
|
@ -1553,7 +1555,6 @@ mod snapshot {
|
|||
ctx.config("check")
|
||||
.path("rustc_codegen_cranelift")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> cranelift 1 <host>
|
||||
[check] rustc 0 <host> -> gcc 1 <host>
|
||||
|
|
@ -1567,7 +1568,6 @@ mod snapshot {
|
|||
ctx.config("check")
|
||||
.path("rust-analyzer")
|
||||
.render_steps(), @r"
|
||||
[build] llvm <host>
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> rust-analyzer 1 <host>
|
||||
");
|
||||
|
|
|
|||
|
|
@ -43,4 +43,9 @@ if isWindows && isKnownToBeMingwBuild; then
|
|||
curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}"
|
||||
7z x -y mingw.7z > /dev/null
|
||||
ciCommandAddPath "$(cygpath -m "$(pwd)/${mingw_dir}/bin")"
|
||||
|
||||
# Initialize mingw for the user.
|
||||
# This should be done by github but isn't for some reason.
|
||||
# (see https://github.com/actions/runner-images/issues/12600)
|
||||
/c/msys64/usr/bin/bash -lc ' '
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -205,6 +205,8 @@ settings:
|
|||
on `wasm32-unknown-unknown` target because the target does not support the
|
||||
`proc-macro` crate type.
|
||||
- `needs-target-std` — ignores if target platform does not have std support.
|
||||
- `ignore-backends` — ignores the listed backends, separated by whitespace characters.
|
||||
- `needs-backends` — only runs the test if current codegen backend is listed.
|
||||
|
||||
The following directives will check LLVM support:
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub(crate) fn build_index(
|
|||
// Set up alias indexes.
|
||||
for (i, item) in cache.search_index.iter().enumerate() {
|
||||
for alias in &item.aliases[..] {
|
||||
aliases.entry(alias.as_str().to_lowercase()).or_default().push(i);
|
||||
aliases.entry(alias.to_string()).or_default().push(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
7
src/librustdoc/html/static/js/rustdoc.d.ts
vendored
7
src/librustdoc/html/static/js/rustdoc.d.ts
vendored
|
|
@ -219,6 +219,8 @@ declare namespace rustdoc {
|
|||
crate: string,
|
||||
descShard: SearchDescShard,
|
||||
id: number,
|
||||
// This is the name of the item. For doc aliases, if you want the name of the aliased
|
||||
// item, take a look at `Row.original.name`.
|
||||
name: string,
|
||||
normalizedName: string,
|
||||
word: string,
|
||||
|
|
@ -227,6 +229,11 @@ declare namespace rustdoc {
|
|||
path: string,
|
||||
ty: number,
|
||||
type: FunctionSearchType | null,
|
||||
descIndex: number,
|
||||
bitIndex: number,
|
||||
implDisambiguator: String | null,
|
||||
is_alias?: boolean,
|
||||
original?: Row,
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -830,7 +830,7 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
|
|||
*/
|
||||
function makePrimitiveElement(name, extra) {
|
||||
return Object.assign({
|
||||
name: name,
|
||||
name,
|
||||
id: null,
|
||||
fullPath: [name],
|
||||
pathWithoutLast: [],
|
||||
|
|
@ -1483,6 +1483,7 @@ class DocSearch {
|
|||
*/
|
||||
this.assocTypeIdNameMap = new Map();
|
||||
this.ALIASES = new Map();
|
||||
this.FOUND_ALIASES = new Set();
|
||||
this.rootPath = rootPath;
|
||||
this.searchState = searchState;
|
||||
|
||||
|
|
@ -2030,6 +2031,8 @@ class DocSearch {
|
|||
// normalized names, type signature objects and fingerprints, and aliases.
|
||||
id = 0;
|
||||
|
||||
/** @type {Array<[string, { [key: string]: Array<number> }, number]>} */
|
||||
const allAliases = [];
|
||||
for (const [crate, crateCorpus] of rawSearchIndex) {
|
||||
// a string representing the lengths of each description shard
|
||||
// a string representing the list of function types
|
||||
|
|
@ -2178,10 +2181,10 @@ class DocSearch {
|
|||
paths[i] = { ty, name, path, exactPath, unboxFlag };
|
||||
}
|
||||
|
||||
// convert `item*` into an object form, and construct word indices.
|
||||
// Convert `item*` into an object form, and construct word indices.
|
||||
//
|
||||
// before any analysis is performed lets gather the search terms to
|
||||
// search against apart from the rest of the data. This is a quick
|
||||
// Before any analysis is performed, let's gather the search terms to
|
||||
// search against apart from the rest of the data. This is a quick
|
||||
// operation that is cached for the life of the page state so that
|
||||
// all other search operations have access to this cached data for
|
||||
// faster analysis operations
|
||||
|
|
@ -2269,29 +2272,58 @@ class DocSearch {
|
|||
}
|
||||
|
||||
if (aliases) {
|
||||
const currentCrateAliases = new Map();
|
||||
this.ALIASES.set(crate, currentCrateAliases);
|
||||
for (const alias_name in aliases) {
|
||||
if (!Object.prototype.hasOwnProperty.call(aliases, alias_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @type{number[]} */
|
||||
let currentNameAliases;
|
||||
if (currentCrateAliases.has(alias_name)) {
|
||||
currentNameAliases = currentCrateAliases.get(alias_name);
|
||||
} else {
|
||||
currentNameAliases = [];
|
||||
currentCrateAliases.set(alias_name, currentNameAliases);
|
||||
}
|
||||
for (const local_alias of aliases[alias_name]) {
|
||||
currentNameAliases.push(local_alias + currentIndex);
|
||||
}
|
||||
}
|
||||
// We need to add the aliases in `searchIndex` after we finished filling it
|
||||
// to not mess up indexes.
|
||||
allAliases.push([crate, aliases, currentIndex]);
|
||||
}
|
||||
currentIndex += itemTypes.length;
|
||||
this.searchState.descShards.set(crate, descShardList);
|
||||
}
|
||||
|
||||
for (const [crate, aliases, index] of allAliases) {
|
||||
for (const [alias_name, alias_refs] of Object.entries(aliases)) {
|
||||
if (!this.ALIASES.has(crate)) {
|
||||
this.ALIASES.set(crate, new Map());
|
||||
}
|
||||
const word = alias_name.toLowerCase();
|
||||
const crate_alias_map = this.ALIASES.get(crate);
|
||||
if (!crate_alias_map.has(word)) {
|
||||
crate_alias_map.set(word, []);
|
||||
}
|
||||
const aliases_map = crate_alias_map.get(word);
|
||||
|
||||
const normalizedName = word.indexOf("_") === -1 ? word : word.replace(/_/g, "");
|
||||
for (const alias of alias_refs) {
|
||||
const originalIndex = alias + index;
|
||||
const original = searchIndex[originalIndex];
|
||||
/** @type {rustdoc.Row} */
|
||||
const row = {
|
||||
crate,
|
||||
name: alias_name,
|
||||
normalizedName,
|
||||
is_alias: true,
|
||||
ty: original.ty,
|
||||
type: original.type,
|
||||
paramNames: [],
|
||||
word,
|
||||
id,
|
||||
parent: undefined,
|
||||
original,
|
||||
path: "",
|
||||
implDisambiguator: original.implDisambiguator,
|
||||
// Needed to load the description of the original item.
|
||||
// @ts-ignore
|
||||
descShard: original.descShard,
|
||||
descIndex: original.descIndex,
|
||||
bitIndex: original.bitIndex,
|
||||
};
|
||||
aliases_map.push(row);
|
||||
this.nameTrie.insert(normalizedName, id, this.tailTable);
|
||||
id += 1;
|
||||
searchIndex.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drop the (rather large) hash table used for reusing function items
|
||||
this.TYPES_POOL = new Map();
|
||||
return searchIndex;
|
||||
|
|
@ -2536,6 +2568,8 @@ class DocSearch {
|
|||
parsedQuery.elems.reduce((acc, next) => acc + next.pathLast.length, 0) +
|
||||
parsedQuery.returned.reduce((acc, next) => acc + next.pathLast.length, 0);
|
||||
const maxEditDistance = Math.floor(queryLen / 3);
|
||||
// We reinitialize the `FOUND_ALIASES` map.
|
||||
this.FOUND_ALIASES.clear();
|
||||
|
||||
/**
|
||||
* @type {Map<string, number>}
|
||||
|
|
@ -2695,6 +2729,10 @@ class DocSearch {
|
|||
const buildHrefAndPath = item => {
|
||||
let displayPath;
|
||||
let href;
|
||||
if (item.is_alias) {
|
||||
this.FOUND_ALIASES.add(item.word);
|
||||
item = item.original;
|
||||
}
|
||||
const type = itemTypes[item.ty];
|
||||
const name = item.name;
|
||||
let path = item.path;
|
||||
|
|
@ -3198,8 +3236,7 @@ class DocSearch {
|
|||
result.item = this.searchIndex[result.id];
|
||||
result.word = this.searchIndex[result.id].word;
|
||||
if (isReturnTypeQuery) {
|
||||
// we are doing a return-type based search,
|
||||
// deprioritize "clone-like" results,
|
||||
// We are doing a return-type based search, deprioritize "clone-like" results,
|
||||
// ie. functions that also take the queried type as an argument.
|
||||
const resultItemType = result.item && result.item.type;
|
||||
if (!resultItemType) {
|
||||
|
|
@ -4259,28 +4296,13 @@ class DocSearch {
|
|||
return false;
|
||||
}
|
||||
|
||||
// this does not yet have a type in `rustdoc.d.ts`.
|
||||
// @ts-expect-error
|
||||
function createAliasFromItem(item) {
|
||||
return {
|
||||
crate: item.crate,
|
||||
name: item.name,
|
||||
path: item.path,
|
||||
descShard: item.descShard,
|
||||
descIndex: item.descIndex,
|
||||
exactPath: item.exactPath,
|
||||
ty: item.ty,
|
||||
parent: item.parent,
|
||||
type: item.type,
|
||||
is_alias: true,
|
||||
bitIndex: item.bitIndex,
|
||||
implDisambiguator: item.implDisambiguator,
|
||||
};
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
const handleAliases = async(ret, query, filterCrates, currentCrate) => {
|
||||
const lowerQuery = query.toLowerCase();
|
||||
if (this.FOUND_ALIASES.has(lowerQuery)) {
|
||||
return;
|
||||
}
|
||||
this.FOUND_ALIASES.add(lowerQuery);
|
||||
// We separate aliases and crate aliases because we want to have current crate
|
||||
// aliases to be before the others in the displayed results.
|
||||
// @ts-expect-error
|
||||
|
|
@ -4292,7 +4314,7 @@ class DocSearch {
|
|||
&& this.ALIASES.get(filterCrates).has(lowerQuery)) {
|
||||
const query_aliases = this.ALIASES.get(filterCrates).get(lowerQuery);
|
||||
for (const alias of query_aliases) {
|
||||
aliases.push(createAliasFromItem(this.searchIndex[alias]));
|
||||
aliases.push(alias);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4302,7 +4324,7 @@ class DocSearch {
|
|||
const pushTo = crate === currentCrate ? crateAliases : aliases;
|
||||
const query_aliases = crateAliasesIndex.get(lowerQuery);
|
||||
for (const alias of query_aliases) {
|
||||
pushTo.push(createAliasFromItem(this.searchIndex[alias]));
|
||||
pushTo.push(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4310,9 +4332,9 @@ class DocSearch {
|
|||
|
||||
// @ts-expect-error
|
||||
const sortFunc = (aaa, bbb) => {
|
||||
if (aaa.path < bbb.path) {
|
||||
if (aaa.original.path < bbb.original.path) {
|
||||
return 1;
|
||||
} else if (aaa.path === bbb.path) {
|
||||
} else if (aaa.original.path === bbb.original.path) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -4321,21 +4343,10 @@ class DocSearch {
|
|||
crateAliases.sort(sortFunc);
|
||||
aliases.sort(sortFunc);
|
||||
|
||||
// @ts-expect-error
|
||||
const fetchDesc = alias => {
|
||||
// @ts-expect-error
|
||||
return this.searchIndexEmptyDesc.get(alias.crate).contains(alias.bitIndex) ?
|
||||
"" : this.searchState.loadDesc(alias);
|
||||
};
|
||||
const [crateDescs, descs] = await Promise.all([
|
||||
// @ts-expect-error
|
||||
Promise.all(crateAliases.map(fetchDesc)),
|
||||
Promise.all(aliases.map(fetchDesc)),
|
||||
]);
|
||||
|
||||
// @ts-expect-error
|
||||
const pushFunc = alias => {
|
||||
alias.alias = query;
|
||||
// Cloning `alias` to prevent its fields to be updated.
|
||||
alias = {...alias};
|
||||
const res = buildHrefAndPath(alias);
|
||||
alias.displayPath = pathSplitter(res[0]);
|
||||
alias.fullPath = alias.displayPath + alias.name;
|
||||
|
|
@ -4347,16 +4358,8 @@ class DocSearch {
|
|||
}
|
||||
};
|
||||
|
||||
aliases.forEach((alias, i) => {
|
||||
// @ts-expect-error
|
||||
alias.desc = descs[i];
|
||||
});
|
||||
aliases.forEach(pushFunc);
|
||||
// @ts-expect-error
|
||||
crateAliases.forEach((alias, i) => {
|
||||
alias.desc = crateDescs[i];
|
||||
});
|
||||
// @ts-expect-error
|
||||
crateAliases.forEach(pushFunc);
|
||||
};
|
||||
|
||||
|
|
@ -4802,7 +4805,7 @@ async function addTab(array, query, display) {
|
|||
output.className = "search-results " + extraClass;
|
||||
|
||||
const lis = Promise.all(array.map(async item => {
|
||||
const name = item.name;
|
||||
const name = item.is_alias ? item.original.name : item.name;
|
||||
const type = itemTypes[item.ty];
|
||||
const longType = longItemTypes[item.ty];
|
||||
const typeName = longType.length !== 0 ? `${longType}` : "?";
|
||||
|
|
@ -4822,7 +4825,7 @@ async function addTab(array, query, display) {
|
|||
let alias = " ";
|
||||
if (item.is_alias) {
|
||||
alias = ` <div class="alias">\
|
||||
<b>${item.alias}</b><i class="grey"> - see </i>\
|
||||
<b>${item.name}</b><i class="grey"> - see </i>\
|
||||
</div>`;
|
||||
}
|
||||
resultName.insertAdjacentHTML(
|
||||
|
|
@ -5201,6 +5204,7 @@ function registerSearchEvents() {
|
|||
if (searchState.input.value.length === 0) {
|
||||
searchState.hideResults();
|
||||
} else {
|
||||
// @ts-ignore
|
||||
searchState.timeout = setTimeout(search, 500);
|
||||
}
|
||||
};
|
||||
|
|
@ -5842,8 +5846,8 @@ Lev1TParametricDescription.prototype.offsetIncrs3 = /*2 bits per value */ new In
|
|||
// be called ONLY when the whole file has been parsed and loaded.
|
||||
|
||||
// @ts-expect-error
|
||||
function initSearch(searchIndx) {
|
||||
rawSearchIndex = searchIndx;
|
||||
function initSearch(searchIndex) {
|
||||
rawSearchIndex = searchIndex;
|
||||
if (typeof window !== "undefined") {
|
||||
// @ts-expect-error
|
||||
docSearch = new DocSearch(rawSearchIndex, ROOT_PATH, searchState);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit d3c793b025645a4565ac59aceb30d2d116ff1a41
|
||||
Subproject commit e8a2ffcf322f45b8dce82c65ab27a3e2430a6b51
|
||||
|
|
@ -175,6 +175,36 @@ pub enum Sanitizer {
|
|||
Hwaddress,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum CodegenBackend {
|
||||
Cranelift,
|
||||
Gcc,
|
||||
Llvm,
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a str> for CodegenBackend {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
|
||||
match value.to_lowercase().as_str() {
|
||||
"cranelift" => Ok(Self::Cranelift),
|
||||
"gcc" => Ok(Self::Gcc),
|
||||
"llvm" => Ok(Self::Llvm),
|
||||
_ => Err("unknown backend"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CodegenBackend {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::Cranelift => "cranelift",
|
||||
Self::Gcc => "gcc",
|
||||
Self::Llvm => "llvm",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for `compiletest` *per invocation*.
|
||||
///
|
||||
/// In terms of `bootstrap`, this means that `./x test tests/ui tests/run-make` actually correspond
|
||||
|
|
@ -651,6 +681,9 @@ pub struct Config {
|
|||
/// need `core` stubs in cross-compilation scenarios that do not otherwise want/need to
|
||||
/// `-Zbuild-std`. Used in e.g. ABI tests.
|
||||
pub minicore_path: Utf8PathBuf,
|
||||
|
||||
/// Current codegen backend used.
|
||||
pub codegen_backend: CodegenBackend,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
|
@ -753,6 +786,7 @@ impl Config {
|
|||
profiler_runtime: Default::default(),
|
||||
diff_command: Default::default(),
|
||||
minicore_path: Default::default(),
|
||||
codegen_backend: CodegenBackend::Llvm,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use camino::{Utf8Path, Utf8PathBuf};
|
|||
use semver::Version;
|
||||
use tracing::*;
|
||||
|
||||
use crate::common::{Config, Debugger, FailMode, PassMode, RunFailMode, TestMode};
|
||||
use crate::common::{CodegenBackend, Config, Debugger, FailMode, PassMode, RunFailMode, TestMode};
|
||||
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
|
||||
use crate::directives::auxiliary::{AuxProps, parse_and_update_aux};
|
||||
use crate::directives::needs::CachedNeedsConditions;
|
||||
|
|
@ -818,6 +818,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"ignore-arm-unknown-linux-musleabihf",
|
||||
"ignore-auxiliary",
|
||||
"ignore-avr",
|
||||
"ignore-backends",
|
||||
"ignore-beta",
|
||||
"ignore-cdb",
|
||||
"ignore-compare-mode-next-solver",
|
||||
|
|
@ -907,6 +908,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
|
|||
"min-llvm-version",
|
||||
"min-system-llvm-version",
|
||||
"needs-asm-support",
|
||||
"needs-backends",
|
||||
"needs-crate-type",
|
||||
"needs-deterministic-layouts",
|
||||
"needs-dlltool",
|
||||
|
|
@ -1669,6 +1671,8 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
decision!(cfg::handle_only(config, ln));
|
||||
decision!(needs::handle_needs(&cache.needs, config, ln));
|
||||
decision!(ignore_llvm(config, path, ln));
|
||||
decision!(ignore_backends(config, path, ln));
|
||||
decision!(needs_backends(config, path, ln));
|
||||
decision!(ignore_cdb(config, ln));
|
||||
decision!(ignore_gdb(config, ln));
|
||||
decision!(ignore_lldb(config, ln));
|
||||
|
|
@ -1795,6 +1799,49 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
|
|||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
if let Some(backends_to_ignore) = config.parse_name_value_directive(line, "ignore-backends") {
|
||||
for backend in backends_to_ignore.split_whitespace().map(|backend| {
|
||||
match CodegenBackend::try_from(backend) {
|
||||
Ok(backend) => backend,
|
||||
Err(error) => {
|
||||
panic!("Invalid ignore-backends value `{backend}` in `{path}`: {error}")
|
||||
}
|
||||
}
|
||||
}) {
|
||||
if config.codegen_backend == backend {
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!("{} backend is marked as ignore", backend.as_str()),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn needs_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
if let Some(needed_backends) = config.parse_name_value_directive(line, "needs-backends") {
|
||||
if !needed_backends
|
||||
.split_whitespace()
|
||||
.map(|backend| match CodegenBackend::try_from(backend) {
|
||||
Ok(backend) => backend,
|
||||
Err(error) => {
|
||||
panic!("Invalid needs-backends value `{backend}` in `{path}`: {error}")
|
||||
}
|
||||
})
|
||||
.any(|backend| config.codegen_backend == backend)
|
||||
{
|
||||
return IgnoreDecision::Ignore {
|
||||
reason: format!(
|
||||
"{} backend is not part of required backends",
|
||||
config.codegen_backend.as_str()
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision {
|
||||
if let Some(needed_components) =
|
||||
config.parse_name_value_directive(line, "needs-llvm-components")
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ use walkdir::WalkDir;
|
|||
|
||||
use self::directives::{EarlyProps, make_test_description};
|
||||
use crate::common::{
|
||||
CompareMode, Config, Debugger, PassMode, TestMode, TestPaths, UI_EXTENSIONS,
|
||||
CodegenBackend, CompareMode, Config, Debugger, PassMode, TestMode, TestPaths, UI_EXTENSIONS,
|
||||
expected_output_path, output_base_dir, output_relative_path,
|
||||
};
|
||||
use crate::directives::DirectivesCache;
|
||||
|
|
@ -203,6 +203,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
"debugger",
|
||||
"only test a specific debugger in debuginfo tests",
|
||||
"gdb | lldb | cdb",
|
||||
)
|
||||
.optopt(
|
||||
"",
|
||||
"codegen-backend",
|
||||
"the codegen backend currently used",
|
||||
"CODEGEN BACKEND NAME",
|
||||
);
|
||||
|
||||
let (argv0, args_) = args.split_first().unwrap();
|
||||
|
|
@ -264,6 +270,15 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
|| directives::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?),
|
||||
);
|
||||
|
||||
let codegen_backend = match matches.opt_str("codegen-backend").as_deref() {
|
||||
Some(backend) => match CodegenBackend::try_from(backend) {
|
||||
Ok(backend) => backend,
|
||||
Err(error) => panic!("invalid value `{backend}` for `--codegen-backend`: {error}"),
|
||||
},
|
||||
// By default, it's always llvm.
|
||||
None => CodegenBackend::Llvm,
|
||||
};
|
||||
|
||||
let run_ignored = matches.opt_present("ignored");
|
||||
let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions");
|
||||
let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions");
|
||||
|
|
@ -449,6 +464,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
diff_command: matches.opt_str("compiletest-diff-tool"),
|
||||
|
||||
minicore_path: opt_path(matches, "minicore-path"),
|
||||
|
||||
codegen_backend,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6707bf0f59485cf054ac1095725df43220e4be20
|
||||
460259d14de0274b97b8801e08cb2fe5f16fdac5
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.get_alloc_bytes_unchecked_raw(alloc_id)?
|
||||
}
|
||||
}
|
||||
AllocKind::Function | AllocKind::VTable => {
|
||||
AllocKind::Function | AllocKind::Virtual => {
|
||||
// Allocate some dummy memory to get a unique address for this function/vtable.
|
||||
let alloc_bytes = MiriAllocBytes::from_bytes(
|
||||
&[0u8; 1],
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
|||
dcx.log_protector();
|
||||
}
|
||||
},
|
||||
AllocKind::Function | AllocKind::VTable | AllocKind::Dead => {
|
||||
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
|
||||
// No stacked borrows on these allocations.
|
||||
}
|
||||
}
|
||||
|
|
@ -1021,7 +1021,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
|
||||
alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
|
||||
}
|
||||
AllocKind::Function | AllocKind::VTable | AllocKind::Dead => {
|
||||
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
|
||||
// No stacked borrows on these allocations.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
trace!("Tree Borrows tag {tag:?} exposed in {alloc_id:?}");
|
||||
alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag);
|
||||
}
|
||||
AllocKind::Function | AllocKind::VTable | AllocKind::Dead => {
|
||||
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
|
||||
// No tree borrows on these allocations.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
error: internal compiler error: compiler/rustc_mir_transform/src/validate.rs:LL:CC: broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]:
|
||||
place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection)
|
||||
--> tests/panic/mir-validation.rs:LL:CC
|
||||
|
|
||||
LL | *(tuple.0) = 1;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
|
||||
broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]:
|
||||
place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection)
|
||||
Box<dyn Any>
|
||||
stack backtrace:
|
||||
|
||||
error: the compiler unexpectedly panicked. this is a bug.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -20,3 +24,5 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
19
src/tools/miri/tests/pass/intrinsics/type-id.rs
Normal file
19
src/tools/miri/tests/pass/intrinsics/type-id.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use std::any::{Any, TypeId};
|
||||
|
||||
fn main() {
|
||||
let t1 = TypeId::of::<u64>();
|
||||
let t2 = TypeId::of::<u64>();
|
||||
assert_eq!(t1, t2);
|
||||
let t3 = TypeId::of::<usize>();
|
||||
assert_ne!(t1, t3);
|
||||
|
||||
let _ = format!("{t1:?}"); // test that we can debug-print
|
||||
|
||||
let b = Box::new(0u64) as Box<dyn Any>;
|
||||
assert_eq!(*b.downcast_ref::<u64>().unwrap(), 0);
|
||||
assert!(b.downcast_ref::<usize>().is_none());
|
||||
|
||||
// Get the first pointer chunk and try to make it a ZST ref.
|
||||
// This used to trigger an error because TypeId allocs got misclassified as "LiveData".
|
||||
let _raw_chunk = unsafe { (&raw const t1).cast::<&()>().read() };
|
||||
}
|
||||
|
|
@ -19,9 +19,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ammonia"
|
||||
version = "4.1.0"
|
||||
version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ada2ee439075a3e70b6992fce18ac4e407cd05aea9ca3f75d2c0b0c20bbb364"
|
||||
checksum = "d6b346764dd0814805de8abf899fe03065bcee69bb1a4771c785817e39f3978f"
|
||||
dependencies = [
|
||||
"cssparser",
|
||||
"html5ever",
|
||||
|
|
@ -156,9 +156,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.29"
|
||||
version = "1.2.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
|
||||
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
|
@ -185,9 +185,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
|
||||
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -195,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
|
||||
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -208,18 +208,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.54"
|
||||
version = "4.5.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677"
|
||||
checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.40"
|
||||
version = "4.5.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
|
||||
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
|
|
@ -256,9 +256,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
|
@ -582,12 +582,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
|||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.31.0"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953cbbe631aae7fc0a112702ad5d3aaf09da38beaf45ea84610d6e1c358f569c"
|
||||
checksum = "55d958c2f74b664487a2035fe1dadb032c48718a03b63f3ab0b8537db8549ed4"
|
||||
dependencies = [
|
||||
"log",
|
||||
"mac",
|
||||
"markup5ever",
|
||||
"match_token",
|
||||
]
|
||||
|
|
@ -863,9 +862,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
|||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.16.2"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e4cd8c02f18a011991a039855480c64d74291c5792fcc160d55d77dc4de4a39"
|
||||
checksum = "311fe69c934650f8f19652b3946075f0fc41ad8757dbb68f1ca14e7900ecc1c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"tendril",
|
||||
|
|
@ -874,9 +873,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "match_token"
|
||||
version = "0.1.0"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
|
||||
checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1394,15 +1393,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1460,9 +1459,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
version = "1.0.141"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -2103,9 +2102,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.11"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -28,7 +28,14 @@ function readFile(filePath) {
|
|||
}
|
||||
|
||||
function contentToDiffLine(key, value) {
|
||||
return `"${key}": "${value}",`;
|
||||
if (typeof value === "object" && !Array.isArray(value) && value !== null) {
|
||||
const out = Object.entries(value)
|
||||
.filter(([subKey, _]) => ["path", "name"].includes(subKey))
|
||||
.map(([subKey, subValue]) => `"${subKey}": ${JSON.stringify(subValue)}`)
|
||||
.join(", ");
|
||||
return `"${key}": ${out},`;
|
||||
}
|
||||
return `"${key}": ${JSON.stringify(value)},`;
|
||||
}
|
||||
|
||||
function shouldIgnoreField(fieldName) {
|
||||
|
|
@ -37,47 +44,61 @@ function shouldIgnoreField(fieldName) {
|
|||
fieldName === "proposeCorrectionTo";
|
||||
}
|
||||
|
||||
function valueMapper(key, testOutput) {
|
||||
const isAlias = testOutput["is_alias"];
|
||||
let value = testOutput[key];
|
||||
// To make our life easier, if there is a "parent" type, we add it to the path.
|
||||
if (key === "path") {
|
||||
if (testOutput["parent"] !== undefined) {
|
||||
if (value.length > 0) {
|
||||
value += "::" + testOutput["parent"]["name"];
|
||||
} else {
|
||||
value = testOutput["parent"]["name"];
|
||||
}
|
||||
} else if (testOutput["is_alias"]) {
|
||||
value = valueMapper(key, testOutput["original"]);
|
||||
}
|
||||
} else if (isAlias && key === "alias") {
|
||||
value = testOutput["name"];
|
||||
} else if (isAlias && ["name"].includes(key)) {
|
||||
value = testOutput["original"][key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// This function is only called when no matching result was found and therefore will only display
|
||||
// the diff between the two items.
|
||||
function betterLookingDiff(entry, data) {
|
||||
function betterLookingDiff(expected, testOutput) {
|
||||
let output = " {\n";
|
||||
const spaces = " ";
|
||||
for (const key in entry) {
|
||||
if (!Object.prototype.hasOwnProperty.call(entry, key)) {
|
||||
const spaces = " ";
|
||||
for (const key in expected) {
|
||||
if (!Object.prototype.hasOwnProperty.call(expected, key)) {
|
||||
continue;
|
||||
}
|
||||
if (!data || !Object.prototype.hasOwnProperty.call(data, key)) {
|
||||
output += "-" + spaces + contentToDiffLine(key, entry[key]) + "\n";
|
||||
if (!testOutput || !Object.prototype.hasOwnProperty.call(testOutput, key)) {
|
||||
output += "-" + spaces + contentToDiffLine(key, expected[key]) + "\n";
|
||||
continue;
|
||||
}
|
||||
const value = data[key];
|
||||
if (value !== entry[key]) {
|
||||
output += "-" + spaces + contentToDiffLine(key, entry[key]) + "\n";
|
||||
const value = valueMapper(key, testOutput);
|
||||
if (value !== expected[key]) {
|
||||
output += "-" + spaces + contentToDiffLine(key, expected[key]) + "\n";
|
||||
output += "+" + spaces + contentToDiffLine(key, value) + "\n";
|
||||
} else {
|
||||
output += spaces + contentToDiffLine(key, value) + "\n";
|
||||
output += spaces + " " + contentToDiffLine(key, value) + "\n";
|
||||
}
|
||||
}
|
||||
return output + " }";
|
||||
}
|
||||
|
||||
function lookForEntry(entry, data) {
|
||||
return data.findIndex(data_entry => {
|
||||
function lookForEntry(expected, testOutput) {
|
||||
return testOutput.findIndex(testOutputEntry => {
|
||||
let allGood = true;
|
||||
for (const key in entry) {
|
||||
if (!Object.prototype.hasOwnProperty.call(entry, key)) {
|
||||
for (const key in expected) {
|
||||
if (!Object.prototype.hasOwnProperty.call(expected, key)) {
|
||||
continue;
|
||||
}
|
||||
let value = data_entry[key];
|
||||
// To make our life easier, if there is a "parent" type, we add it to the path.
|
||||
if (key === "path" && data_entry["parent"] !== undefined) {
|
||||
if (value.length > 0) {
|
||||
value += "::" + data_entry["parent"]["name"];
|
||||
} else {
|
||||
value = data_entry["parent"]["name"];
|
||||
}
|
||||
}
|
||||
if (value !== entry[key]) {
|
||||
const value = valueMapper(key, testOutputEntry);
|
||||
if (value !== expected[key]) {
|
||||
allGood = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "unicode-table-generator"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl RawEmitter {
|
|||
|
||||
let points = ranges
|
||||
.iter()
|
||||
.flat_map(|r| (r.start..r.end).into_iter().collect::<Vec<u32>>())
|
||||
.flat_map(|r| (r.start..r.end).collect::<Vec<u32>>())
|
||||
.collect::<Vec<u32>>();
|
||||
|
||||
println!("there are {} points", points.len());
|
||||
|
|
@ -32,21 +32,20 @@ impl RawEmitter {
|
|||
// assert that there is no whitespace over the 0x3000 range.
|
||||
assert!(point <= 0x3000, "the highest unicode whitespace value has changed");
|
||||
let high_bytes = point as usize >> 8;
|
||||
let codepoints = codepoints_by_high_bytes.entry(high_bytes).or_insert_with(Vec::new);
|
||||
let codepoints = codepoints_by_high_bytes.entry(high_bytes).or_default();
|
||||
codepoints.push(point);
|
||||
}
|
||||
|
||||
let mut bit_for_high_byte = 1u8;
|
||||
let mut arms = Vec::<String>::new();
|
||||
|
||||
let mut high_bytes: Vec<usize> =
|
||||
codepoints_by_high_bytes.keys().map(|k| k.clone()).collect();
|
||||
let mut high_bytes: Vec<usize> = codepoints_by_high_bytes.keys().copied().collect();
|
||||
high_bytes.sort();
|
||||
for high_byte in high_bytes {
|
||||
let codepoints = codepoints_by_high_bytes.get_mut(&high_byte).unwrap();
|
||||
if codepoints.len() == 1 {
|
||||
let ch = codepoints.pop().unwrap();
|
||||
arms.push(format!("{} => c as u32 == {:#04x}", high_byte, ch));
|
||||
arms.push(format!("{high_byte} => c as u32 == {ch:#04x}"));
|
||||
continue;
|
||||
}
|
||||
// more than 1 codepoint in this arm
|
||||
|
|
@ -54,8 +53,7 @@ impl RawEmitter {
|
|||
map[(*codepoint & 0xff) as usize] |= bit_for_high_byte;
|
||||
}
|
||||
arms.push(format!(
|
||||
"{} => WHITESPACE_MAP[c as usize & 0xff] & {} != 0",
|
||||
high_byte, bit_for_high_byte
|
||||
"{high_byte} => WHITESPACE_MAP[c as usize & 0xff] & {bit_for_high_byte} != 0"
|
||||
));
|
||||
bit_for_high_byte <<= 1;
|
||||
}
|
||||
|
|
@ -68,7 +66,7 @@ impl RawEmitter {
|
|||
writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap();
|
||||
writeln!(&mut self.file, " match c as u32 >> 8 {{").unwrap();
|
||||
for arm in arms {
|
||||
writeln!(&mut self.file, " {},", arm).unwrap();
|
||||
writeln!(&mut self.file, " {arm},").unwrap();
|
||||
}
|
||||
writeln!(&mut self.file, " _ => false,").unwrap();
|
||||
writeln!(&mut self.file, " }}").unwrap();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const INDEX_MASK: u32 = 1 << 22;
|
|||
pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String {
|
||||
let mut file = String::new();
|
||||
|
||||
write!(file, "const INDEX_MASK: u32 = 0x{:x};", INDEX_MASK).unwrap();
|
||||
write!(file, "const INDEX_MASK: u32 = 0x{INDEX_MASK:x};").unwrap();
|
||||
file.push_str("\n\n");
|
||||
file.push_str(HEADER.trim_start());
|
||||
file.push('\n');
|
||||
|
|
|
|||
|
|
@ -160,15 +160,15 @@ fn load_data() -> UnicodeData {
|
|||
.push(Codepoints::Single(row.codepoint));
|
||||
}
|
||||
|
||||
if let Some(mapped) = row.simple_lowercase_mapping {
|
||||
if mapped != row.codepoint {
|
||||
to_lower.insert(row.codepoint.value(), (mapped.value(), 0, 0));
|
||||
}
|
||||
if let Some(mapped) = row.simple_lowercase_mapping
|
||||
&& mapped != row.codepoint
|
||||
{
|
||||
to_lower.insert(row.codepoint.value(), (mapped.value(), 0, 0));
|
||||
}
|
||||
if let Some(mapped) = row.simple_uppercase_mapping {
|
||||
if mapped != row.codepoint {
|
||||
to_upper.insert(row.codepoint.value(), (mapped.value(), 0, 0));
|
||||
}
|
||||
if let Some(mapped) = row.simple_uppercase_mapping
|
||||
&& mapped != row.codepoint
|
||||
{
|
||||
to_upper.insert(row.codepoint.value(), (mapped.value(), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,12 +196,12 @@ fn load_data() -> UnicodeData {
|
|||
.flat_map(|codepoints| match codepoints {
|
||||
Codepoints::Single(c) => c
|
||||
.scalar()
|
||||
.map(|ch| (ch as u32..ch as u32 + 1))
|
||||
.map(|ch| ch as u32..ch as u32 + 1)
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>(),
|
||||
Codepoints::Range(c) => c
|
||||
.into_iter()
|
||||
.flat_map(|c| c.scalar().map(|ch| (ch as u32..ch as u32 + 1)))
|
||||
.flat_map(|c| c.scalar().map(|ch| ch as u32..ch as u32 + 1))
|
||||
.collect::<Vec<_>>(),
|
||||
})
|
||||
.collect::<Vec<Range<u32>>>(),
|
||||
|
|
@ -236,7 +236,7 @@ fn main() {
|
|||
let ranges_by_property = &unicode_data.ranges;
|
||||
|
||||
if let Some(path) = test_path {
|
||||
std::fs::write(&path, generate_tests(&write_location, &ranges_by_property)).unwrap();
|
||||
std::fs::write(&path, generate_tests(&write_location, ranges_by_property)).unwrap();
|
||||
}
|
||||
|
||||
let mut total_bytes = 0;
|
||||
|
|
@ -246,9 +246,9 @@ fn main() {
|
|||
|
||||
let mut emitter = RawEmitter::new();
|
||||
if property == &"White_Space" {
|
||||
emit_whitespace(&mut emitter, &ranges);
|
||||
emit_whitespace(&mut emitter, ranges);
|
||||
} else {
|
||||
emit_codepoints(&mut emitter, &ranges);
|
||||
emit_codepoints(&mut emitter, ranges);
|
||||
}
|
||||
|
||||
modules.push((property.to_lowercase().to_string(), emitter.file));
|
||||
|
|
@ -288,7 +288,7 @@ fn main() {
|
|||
for line in contents.lines() {
|
||||
if !line.trim().is_empty() {
|
||||
table_file.push_str(" ");
|
||||
table_file.push_str(&line);
|
||||
table_file.push_str(line);
|
||||
}
|
||||
table_file.push('\n');
|
||||
}
|
||||
|
|
@ -312,7 +312,7 @@ fn version() -> String {
|
|||
let start = readme.find(prefix).unwrap() + prefix.len();
|
||||
let end = readme.find(" of the Unicode Standard.").unwrap();
|
||||
let version =
|
||||
readme[start..end].split('.').map(|v| v.parse::<u32>().expect(&v)).collect::<Vec<_>>();
|
||||
readme[start..end].split('.').map(|v| v.parse::<u32>().expect(v)).collect::<Vec<_>>();
|
||||
let [major, minor, micro] = [version[0], version[1], version[2]];
|
||||
|
||||
out.push_str(&format!("({major}, {minor}, {micro});\n"));
|
||||
|
|
@ -320,7 +320,7 @@ fn version() -> String {
|
|||
}
|
||||
|
||||
fn fmt_list<V: std::fmt::Debug>(values: impl IntoIterator<Item = V>) -> String {
|
||||
let pieces = values.into_iter().map(|b| format!("{:?}, ", b)).collect::<Vec<_>>();
|
||||
let pieces = values.into_iter().map(|b| format!("{b:?}, ")).collect::<Vec<_>>();
|
||||
let mut out = String::new();
|
||||
let mut line = String::from("\n ");
|
||||
for piece in pieces {
|
||||
|
|
@ -348,7 +348,7 @@ fn generate_tests(data_path: &str, ranges: &[(&str, Vec<Range<u32>>)]) -> String
|
|||
s.push_str("\nfn main() {\n");
|
||||
|
||||
for (property, ranges) in ranges {
|
||||
s.push_str(&format!(r#" println!("Testing {}");"#, property));
|
||||
s.push_str(&format!(r#" println!("Testing {property}");"#));
|
||||
s.push('\n');
|
||||
s.push_str(&format!(" {}_true();\n", property.to_lowercase()));
|
||||
s.push_str(&format!(" {}_false();\n", property.to_lowercase()));
|
||||
|
|
@ -373,7 +373,7 @@ fn generate_tests(data_path: &str, ranges: &[(&str, Vec<Range<u32>>)]) -> String
|
|||
s.push_str(" }\n\n");
|
||||
}
|
||||
|
||||
s.push_str("}");
|
||||
s.push('}');
|
||||
s
|
||||
}
|
||||
|
||||
|
|
@ -388,7 +388,7 @@ fn generate_asserts(s: &mut String, property: &str, points: &[u32], truthy: bool
|
|||
range.start,
|
||||
));
|
||||
} else {
|
||||
s.push_str(&format!(" for chn in {:?}u32 {{\n", range));
|
||||
s.push_str(&format!(" for chn in {range:?}u32 {{\n"));
|
||||
s.push_str(&format!(
|
||||
" assert!({}unicode_data::{}::lookup(std::char::from_u32(chn).unwrap()), \"{{:?}}\", chn);\n",
|
||||
if truthy { "" } else { "!" },
|
||||
|
|
@ -439,7 +439,7 @@ fn merge_ranges(ranges: &mut Vec<Range<u32>>) {
|
|||
let mut last_end = None;
|
||||
for range in ranges {
|
||||
if let Some(last) = last_end {
|
||||
assert!(range.start > last, "{:?}", range);
|
||||
assert!(range.start > last, "{range:?}");
|
||||
}
|
||||
last_end = Some(range.end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,10 +156,10 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
|
|||
emitter.blank_line();
|
||||
|
||||
let mut bitset = emitter.clone();
|
||||
let bitset_ok = bitset.emit_bitset(&ranges).is_ok();
|
||||
let bitset_ok = bitset.emit_bitset(ranges).is_ok();
|
||||
|
||||
let mut skiplist = emitter.clone();
|
||||
skiplist.emit_skiplist(&ranges);
|
||||
skiplist.emit_skiplist(ranges);
|
||||
|
||||
if bitset_ok && bitset.bytes_used <= skiplist.bytes_used {
|
||||
*emitter = bitset;
|
||||
|
|
@ -174,7 +174,7 @@ pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
|
|||
emitter.blank_line();
|
||||
|
||||
let mut cascading = emitter.clone();
|
||||
cascading.emit_cascading_map(&ranges);
|
||||
cascading.emit_cascading_map(ranges);
|
||||
*emitter = cascading;
|
||||
emitter.desc = String::from("cascading");
|
||||
}
|
||||
|
|
@ -272,7 +272,7 @@ impl Canonicalized {
|
|||
// for canonical when possible.
|
||||
while let Some((&to, _)) = mappings
|
||||
.iter()
|
||||
.find(|(&to, _)| to == 0)
|
||||
.find(|&(&to, _)| to == 0)
|
||||
.or_else(|| mappings.iter().max_by_key(|m| m.1.len()))
|
||||
{
|
||||
// Get the mapping with the most entries. Currently, no mapping can
|
||||
|
|
@ -311,10 +311,9 @@ impl Canonicalized {
|
|||
}
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
unique_mapping
|
||||
.insert(to, UniqueMapping::Canonical(canonical_words.len()))
|
||||
.is_none()
|
||||
assert_eq!(
|
||||
unique_mapping.insert(to, UniqueMapping::Canonical(canonical_words.len())),
|
||||
None
|
||||
);
|
||||
canonical_words.push(to);
|
||||
|
||||
|
|
@ -340,14 +339,10 @@ impl Canonicalized {
|
|||
// We'll probably always have some slack though so this loop will still
|
||||
// be needed.
|
||||
for &w in unique_words {
|
||||
if !unique_mapping.contains_key(&w) {
|
||||
assert!(
|
||||
unique_mapping
|
||||
.insert(w, UniqueMapping::Canonical(canonical_words.len()))
|
||||
.is_none()
|
||||
);
|
||||
unique_mapping.entry(w).or_insert_with(|| {
|
||||
canonical_words.push(w);
|
||||
}
|
||||
UniqueMapping::Canonical(canonical_words.len())
|
||||
});
|
||||
}
|
||||
assert_eq!(canonicalized_words.len() + canonical_words.len(), unique_words.len());
|
||||
assert_eq!(unique_mapping.len(), unique_words.len());
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// other architectures (including ARM and x86-64) use the prefix `.Lanon.`
|
||||
//@ only-linux
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: --crate-type=lib -Copt-level=3
|
||||
//@ compile-flags: --crate-type=lib -Copt-level=3 -Cllvm-args=-enable-global-merge=0
|
||||
//@ edition: 2024
|
||||
|
||||
use std::ffi::CStr;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@
|
|||
//@ min-llvm-version: 21.0.0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
|
||||
unsafe extern "C" {
|
||||
safe fn add(x: i32, y: i32) -> i32;
|
||||
}
|
||||
|
||||
pub fn add_one(x: i32) -> i32 {
|
||||
// CHECK-LABEL: __cfi__{{.*}}7add_one{{.*}}:
|
||||
|
|
@ -23,7 +31,7 @@ pub fn add_one(x: i32) -> i32 {
|
|||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: mov ecx, 2628068948
|
||||
x + 1
|
||||
add(x, 1)
|
||||
}
|
||||
|
||||
pub fn add_two(x: i32, _y: i32) -> i32 {
|
||||
|
|
@ -40,7 +48,7 @@ pub fn add_two(x: i32, _y: i32) -> i32 {
|
|||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: mov edx, 2505940310
|
||||
x + 2
|
||||
add(x, 2)
|
||||
}
|
||||
|
||||
pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
|
|
@ -57,5 +65,5 @@ pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
|
|||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: nop
|
||||
// CHECK-NEXT: mov edx, 653723426
|
||||
f(arg) + f(arg)
|
||||
add(f(arg), f(arg))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -C target-feature=+exception-handling
|
||||
//@ compile-flags: -C panic=unwind
|
||||
//@ compile-flags: -C llvm-args=-wasm-enable-eh
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
|
|
|||
28
tests/codegen/repeat-operand-zero-len.rs
Normal file
28
tests/codegen/repeat-operand-zero-len.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes
|
||||
|
||||
// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`.
|
||||
// It only applies when the resulting array is a ZST, so the test is written in
|
||||
// such a way as to keep MIR optimizations from seeing that fact and removing
|
||||
// the local and statement altogether. (At the time of writing, no other codegen
|
||||
// test hit that code path, nor did a stage 2 build of the compiler.)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Wrapper<T, const N: usize>([T; N]);
|
||||
|
||||
// CHECK-LABEL: define {{.+}}do_repeat{{.+}}(i32 noundef %x)
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NOT: alloca
|
||||
// CHECK-NEXT: ret void
|
||||
#[inline(never)]
|
||||
pub fn do_repeat<T: Copy, const N: usize>(x: T) -> Wrapper<T, N> {
|
||||
Wrapper([x; N])
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @trigger_repeat_zero_len
|
||||
#[no_mangle]
|
||||
pub fn trigger_repeat_zero_len() -> Wrapper<u32, 0> {
|
||||
// CHECK: call void {{.+}}do_repeat{{.+}}(i32 noundef 4)
|
||||
do_repeat(4)
|
||||
}
|
||||
28
tests/codegen/repeat-operand-zst-elem.rs
Normal file
28
tests/codegen/repeat-operand-zst-elem.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes
|
||||
|
||||
// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`.
|
||||
// It only applies when the resulting array is a ZST, so the test is written in
|
||||
// such a way as to keep MIR optimizations from seeing that fact and removing
|
||||
// the local and statement altogether. (At the time of writing, no other codegen
|
||||
// test hit that code path, nor did a stage 2 build of the compiler.)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Wrapper<T, const N: usize>([T; N]);
|
||||
|
||||
// CHECK-LABEL: define {{.+}}do_repeat{{.+}}()
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NOT: alloca
|
||||
// CHECK-NEXT: ret void
|
||||
#[inline(never)]
|
||||
pub fn do_repeat<T: Copy, const N: usize>(x: T) -> Wrapper<T, N> {
|
||||
Wrapper([x; N])
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @trigger_repeat_zst_elem
|
||||
#[no_mangle]
|
||||
pub fn trigger_repeat_zst_elem() -> Wrapper<(), 8> {
|
||||
// CHECK: call void {{.+}}do_repeat{{.+}}()
|
||||
do_repeat(())
|
||||
}
|
||||
11
tests/rustdoc-js-std/alias-lev.js
Normal file
11
tests/rustdoc-js-std/alias-lev.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// This test ensures that aliases are also allowed to be partially matched.
|
||||
|
||||
// ignore-order
|
||||
|
||||
const EXPECTED = {
|
||||
// The full alias name is `getcwd`.
|
||||
'query': 'getcw',
|
||||
'others': [
|
||||
{ 'path': 'std::env', 'name': 'current_dir', 'alias': 'getcwd' },
|
||||
],
|
||||
};
|
||||
|
|
@ -115,11 +115,10 @@ const EXPECTED = [
|
|||
query: '加法',
|
||||
others: [
|
||||
{
|
||||
name: "add",
|
||||
name: "加法",
|
||||
path: "non_english_identifier",
|
||||
is_alias: true,
|
||||
alias: "加法",
|
||||
href: "../non_english_identifier/macro.add.html"
|
||||
href: "../non_english_identifier/trait.加法.html",
|
||||
desc: "Add"
|
||||
},
|
||||
{
|
||||
name: "add",
|
||||
|
|
@ -129,11 +128,13 @@ const EXPECTED = [
|
|||
href: "../non_english_identifier/fn.add.html"
|
||||
},
|
||||
{
|
||||
name: "加法",
|
||||
name: "add",
|
||||
path: "non_english_identifier",
|
||||
href: "../non_english_identifier/trait.加法.html",
|
||||
desc: "Add"
|
||||
}],
|
||||
is_alias: true,
|
||||
alias: "加法",
|
||||
href: "../non_english_identifier/macro.add.html"
|
||||
},
|
||||
],
|
||||
in_args: [{
|
||||
name: "加上",
|
||||
path: "non_english_identifier::加法",
|
||||
|
|
|
|||
24
tests/ui/cfg/crt-static-with-target-features-works.rs
Normal file
24
tests/ui/cfg/crt-static-with-target-features-works.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Test to ensure that specifying a value for crt-static in target features
|
||||
// does not result in skipping the features following it.
|
||||
// This is a regression test for #144143
|
||||
|
||||
//@ add-core-stubs
|
||||
//@ needs-llvm-components: x86
|
||||
//@ compile-flags: --target=x86_64-unknown-linux-gnu
|
||||
//@ compile-flags: -Ctarget-feature=+crt-static,+avx2
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(no_core, rustc_attrs, lang_items)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! compile_error {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[cfg(target_feature = "avx2")]
|
||||
compile_error!("+avx2");
|
||||
//~^ ERROR: +avx2
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error: +avx2
|
||||
--> $DIR/crt-static-with-target-features-works.rs:23:1
|
||||
|
|
||||
LL | compile_error!("+avx2");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
19
tests/ui/impl-trait/in-bindings/implicit-sized.rs
Normal file
19
tests/ui/impl-trait/in-bindings/implicit-sized.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#![feature(impl_trait_in_bindings)]
|
||||
|
||||
trait Trait {}
|
||||
impl<T: ?Sized> Trait for T {}
|
||||
|
||||
fn doesnt_work() {
|
||||
let x: &impl Trait = "hi";
|
||||
//~^ ERROR the size for values of type `str` cannot be known at compilation time
|
||||
}
|
||||
|
||||
fn works() {
|
||||
let x: &(impl Trait + ?Sized) = "hi";
|
||||
// No implicit sized.
|
||||
|
||||
let x: &impl Trait = &();
|
||||
// Is actually sized.
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
11
tests/ui/impl-trait/in-bindings/implicit-sized.stderr
Normal file
11
tests/ui/impl-trait/in-bindings/implicit-sized.stderr
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/implicit-sized.rs:7:13
|
||||
|
|
||||
LL | let x: &impl Trait = "hi";
|
||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -58,10 +58,9 @@ unsafe fn null_ptr() {
|
|||
let _a: A = ptr::read_unaligned(ptr::null_mut());
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
||||
// These two should *not* fire the lint.
|
||||
let _a: A = ptr::read_volatile(ptr::null());
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
let _a: A = ptr::read_volatile(ptr::null_mut());
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
||||
let _a: A = ptr::replace(ptr::null_mut(), v);
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
|
@ -82,8 +81,8 @@ unsafe fn null_ptr() {
|
|||
ptr::write_unaligned(ptr::null_mut(), v);
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
||||
// This one should *not* fire the lint.
|
||||
ptr::write_volatile(ptr::null_mut(), v);
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
||||
ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
|
||||
//~^ ERROR calling this function with a null pointer is undefined behavior
|
||||
|
|
|
|||
|
|
@ -164,27 +164,7 @@ LL | let _a: A = ptr::read_unaligned(ptr::null_mut());
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:61:17
|
||||
|
|
||||
LL | let _a: A = ptr::read_volatile(ptr::null());
|
||||
| ^^^^^^^^^^^^^^^^^^^-----------^
|
||||
| |
|
||||
| null pointer originates from here
|
||||
|
|
||||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:63:17
|
||||
|
|
||||
LL | let _a: A = ptr::read_volatile(ptr::null_mut());
|
||||
| ^^^^^^^^^^^^^^^^^^^---------------^
|
||||
| |
|
||||
| null pointer originates from here
|
||||
|
|
||||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:66:17
|
||||
--> $DIR/invalid_null_args.rs:65:17
|
||||
|
|
||||
LL | let _a: A = ptr::replace(ptr::null_mut(), v);
|
||||
| ^^^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -194,7 +174,7 @@ LL | let _a: A = ptr::replace(ptr::null_mut(), v);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:69:5
|
||||
--> $DIR/invalid_null_args.rs:68:5
|
||||
|
|
||||
LL | ptr::swap::<A>(ptr::null_mut(), &mut v);
|
||||
| ^^^^^^^^^^^^^^^---------------^^^^^^^^^
|
||||
|
|
@ -204,7 +184,7 @@ LL | ptr::swap::<A>(ptr::null_mut(), &mut v);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:71:5
|
||||
--> $DIR/invalid_null_args.rs:70:5
|
||||
|
|
||||
LL | ptr::swap::<A>(&mut v, ptr::null_mut());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^---------------^
|
||||
|
|
@ -214,7 +194,7 @@ LL | ptr::swap::<A>(&mut v, ptr::null_mut());
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:74:5
|
||||
--> $DIR/invalid_null_args.rs:73:5
|
||||
|
|
||||
LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^^^^^
|
||||
|
|
@ -224,7 +204,7 @@ LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:76:5
|
||||
--> $DIR/invalid_null_args.rs:75:5
|
||||
|
|
||||
LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -234,7 +214,7 @@ LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:79:5
|
||||
--> $DIR/invalid_null_args.rs:78:5
|
||||
|
|
||||
LL | ptr::write(ptr::null_mut(), v);
|
||||
| ^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -244,7 +224,7 @@ LL | ptr::write(ptr::null_mut(), v);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:82:5
|
||||
--> $DIR/invalid_null_args.rs:81:5
|
||||
|
|
||||
LL | ptr::write_unaligned(ptr::null_mut(), v);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -254,17 +234,7 @@ LL | ptr::write_unaligned(ptr::null_mut(), v);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:85:5
|
||||
|
|
||||
LL | ptr::write_volatile(ptr::null_mut(), v);
|
||||
| ^^^^^^^^^^^^^^^^^^^^---------------^^^^
|
||||
| |
|
||||
| null pointer originates from here
|
||||
|
|
||||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:88:5
|
||||
--> $DIR/invalid_null_args.rs:87:5
|
||||
|
|
||||
LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^
|
||||
|
|
@ -274,7 +244,7 @@ LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:93:18
|
||||
--> $DIR/invalid_null_args.rs:92:18
|
||||
|
|
||||
LL | let _a: u8 = ptr::read(const_ptr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -287,7 +257,7 @@ LL | let null_ptr = ptr::null_mut();
|
|||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:100:5
|
||||
--> $DIR/invalid_null_args.rs:99:5
|
||||
|
|
||||
LL | std::slice::from_raw_parts::<()>(ptr::null(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
|
||||
|
|
@ -297,7 +267,7 @@ LL | std::slice::from_raw_parts::<()>(ptr::null(), 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:102:5
|
||||
--> $DIR/invalid_null_args.rs:101:5
|
||||
|
|
||||
LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
|
||||
|
|
@ -307,7 +277,7 @@ LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:104:5
|
||||
--> $DIR/invalid_null_args.rs:103:5
|
||||
|
|
||||
LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -317,7 +287,7 @@ LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0);
|
|||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
|
||||
--> $DIR/invalid_null_args.rs:106:5
|
||||
--> $DIR/invalid_null_args.rs:105:5
|
||||
|
|
||||
LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
|
||||
|
|
@ -326,5 +296,5 @@ LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0);
|
|||
|
|
||||
= help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html>
|
||||
|
||||
error: aborting due to 31 previous errors
|
||||
error: aborting due to 28 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
// This test reproduces the circumstances that caused the error to appear, and checks
|
||||
// that compilation is successful.
|
||||
|
||||
//@ check-pass
|
||||
//@ build-pass
|
||||
//@ compile-flags: --test -C debuginfo=2 -C lto=fat
|
||||
//@ no-prefer-dynamic
|
||||
//@ incremental
|
||||
|
||||
extern crate alloc;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ pub fn f(a: u32) -> u32 {
|
|||
}
|
||||
bb1 = {
|
||||
Call(RET = f(1), ReturnTo(bb2), UnwindTerminate(ReasonAbi))
|
||||
//~^ ERROR broken MIR in Item
|
||||
//~| ERROR encountered critical edge in `Call` terminator
|
||||
}
|
||||
|
||||
bb2 = {
|
||||
|
|
@ -29,5 +31,3 @@ pub fn f(a: u32) -> u32 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~? RAW encountered critical edge in `Call` terminator
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
//@ run-crash
|
||||
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
|
||||
//@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires
|
||||
//@ revisions: null misaligned
|
||||
|
||||
#![allow(invalid_null_arguments)]
|
||||
//@ revisions: misaligned
|
||||
|
||||
use std::ptr;
|
||||
|
||||
|
|
@ -11,8 +9,6 @@ fn main() {
|
|||
let src = [0u16; 2];
|
||||
let src = src.as_ptr();
|
||||
unsafe {
|
||||
#[cfg(null)]
|
||||
ptr::read_volatile(ptr::null::<u8>());
|
||||
#[cfg(misaligned)]
|
||||
ptr::read_volatile(src.byte_add(1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
//@ run-crash
|
||||
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
|
||||
//@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires
|
||||
//@ revisions: null misaligned
|
||||
|
||||
#![allow(invalid_null_arguments)]
|
||||
//@ revisions: misaligned
|
||||
|
||||
use std::ptr;
|
||||
|
||||
|
|
@ -11,8 +9,6 @@ fn main() {
|
|||
let mut dst = [0u16; 2];
|
||||
let mut dst = dst.as_mut_ptr();
|
||||
unsafe {
|
||||
#[cfg(null)]
|
||||
ptr::write_volatile(ptr::null_mut::<u8>(), 1u8);
|
||||
#[cfg(misaligned)]
|
||||
ptr::write_volatile(dst.byte_add(1), 1u16);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:27:28
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:30:28
|
||||
|
|
||||
LL | let _x = T::Assoc::new(());
|
||||
| ------------- ^^ expected `[u32; 1]`, found `()`
|
||||
|
|
@ -7,7 +7,7 @@ LL | let _x = T::Assoc::new(());
|
|||
| arguments to this function are incorrect
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:18:8
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:21:8
|
||||
|
|
||||
LL | fn new(r: R) -> R {
|
||||
| ^^^ ----
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:30:28
|
||||
|
|
||||
LL | let _x = T::Assoc::new(());
|
||||
| ------------- ^^ expected `[u32; 1]`, found `()`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: associated function defined here
|
||||
--> $DIR/incomplete-inference-issue-143992.rs:21:8
|
||||
|
|
||||
LL | fn new(r: R) -> R {
|
||||
| ^^^ ----
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
//@ compile-flags: --crate-type=lib
|
||||
//@ revisions: current next
|
||||
//@ revisions: current next current_sized_hierarchy next_sized_hierarchy
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[current] check-pass
|
||||
//@[next] check-pass
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-fail
|
||||
//@[next_sized_hierarchy] compile-flags: -Znext-solver
|
||||
|
||||
#![cfg_attr(any(current_sized_hierarchy, next_sized_hierarchy), feature(sized_hierarchy))]
|
||||
|
||||
// Test that we avoid incomplete inference when normalizing. Without this,
|
||||
// `Trait`'s implicit `MetaSized` supertrait requires proving `T::Assoc<_>: MetaSized`
|
||||
|
|
@ -25,5 +28,6 @@ where
|
|||
T::Assoc<[u32; 1]>: Clone,
|
||||
{
|
||||
let _x = T::Assoc::new(());
|
||||
//[next]~^ ERROR mismatched types
|
||||
//[next_sized_hierarchy]~^ ERROR mismatched types
|
||||
//[current_sized_hierarchy]~^^ ERROR mismatched types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,6 @@ LL | impl<T: Bound, U> Trait<U> for T {
|
|||
| ----- ^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required by a bound in `Bound`
|
||||
--> $DIR/normalizes-to-is-not-productive.rs:8:1
|
||||
|
|
||||
LL | / trait Bound {
|
||||
LL | | fn method();
|
||||
LL | | }
|
||||
| |_^ required by this bound in `Bound`
|
||||
|
||||
error[E0277]: the trait bound `Foo: Bound` is not satisfied
|
||||
--> $DIR/normalizes-to-is-not-productive.rs:47:19
|
||||
|
|
|
|||
|
|
@ -19,23 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
|
|||
LL | Self::Assoc: A<T>,
|
||||
| ^^^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized`
|
||||
--> $DIR/normalize-param-env-2.rs:24:22
|
||||
|
|
||||
LL | Self::Assoc: A<T>,
|
||||
| ^^^^
|
||||
|
|
||||
note: required by a bound in `A`
|
||||
--> $DIR/normalize-param-env-2.rs:9:1
|
||||
|
|
||||
LL | / trait A<T> {
|
||||
LL | | type Assoc;
|
||||
LL | |
|
||||
LL | | fn f()
|
||||
... |
|
||||
LL | | }
|
||||
| |_^ required by this bound in `A`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
|
||||
--> $DIR/normalize-param-env-2.rs:24:22
|
||||
|
|
||||
|
|
@ -63,6 +46,6 @@ LL | where
|
|||
LL | Self::Assoc: A<T>,
|
||||
| ^^^^ required by this bound in `A::f`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
|
|
|||
|
|
@ -4,20 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
|
|||
LL | <T as Trait>::Assoc: Trait,
|
||||
| ^^^^^
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized`
|
||||
--> $DIR/normalize-param-env-4.rs:19:26
|
||||
|
|
||||
LL | <T as Trait>::Assoc: Trait,
|
||||
| ^^^^^
|
||||
|
|
||||
note: required by a bound in `Trait`
|
||||
--> $DIR/normalize-param-env-4.rs:7:1
|
||||
|
|
||||
LL | / trait Trait {
|
||||
LL | | type Assoc;
|
||||
LL | | }
|
||||
| |_^ required by this bound in `Trait`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use std::ops::Add;
|
||||
|
||||
fn dbl<T>(x: T) -> <T as Add>::Output
|
||||
//~^ ERROR type annotations needed
|
||||
where
|
||||
T: Copy + Add,
|
||||
UUU: Copy,
|
||||
//~^ ERROR cannot find type `UUU` in this scope
|
||||
{
|
||||
x + x
|
||||
//~^ ERROR use of moved value: `x`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,33 @@
|
|||
error[E0412]: cannot find type `UUU` in this scope
|
||||
--> $DIR/ignore-err-clauses.rs:7:5
|
||||
--> $DIR/ignore-err-clauses.rs:6:5
|
||||
|
|
||||
LL | UUU: Copy,
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/ignore-err-clauses.rs:3:14
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/ignore-err-clauses.rs:9:9
|
||||
|
|
||||
LL | fn dbl<T>(x: T) -> <T as Add>::Output
|
||||
| ^ cannot infer type for type parameter `T`
|
||||
| - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | x + x
|
||||
| ----^
|
||||
| | |
|
||||
| | value used here after move
|
||||
| `x` moved due to usage in operator
|
||||
|
|
||||
help: if `T` implemented `Clone`, you could clone the value
|
||||
--> $DIR/ignore-err-clauses.rs:3:8
|
||||
|
|
||||
LL | fn dbl<T>(x: T) -> <T as Add>::Output
|
||||
| ^ consider constraining this type parameter with `Clone`
|
||||
...
|
||||
LL | x + x
|
||||
| - you could clone this value
|
||||
note: calling this operator moves the left-hand side
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0412.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
Some errors have detailed explanations: E0382, E0412.
|
||||
For more information about an error, try `rustc --explain E0382`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue