authorbors <bors@rust-lang.org> 2026-05-29 09:59:05 UTC
committerbors <bors@rust-lang.org> 2026-05-29 09:59:05 UTC
logb5d1746e7d25465729706ac5a0004b035e219d01
tree1ff23f2e1d9fa6f5dea88612781b51eca738b533
parentdc375db7d8df0aa450e622c529147c95eee756f5
parent6b29e581c45d3620d0d8125b2a627fd176fd1307

Auto merge of #157095 - JonathanBrouwer:rollup-eMYdzcn, r=JonathanBrouwer

Rollup of 12 pull requests Successful merges: - rust-lang/rust#156867 (Stop needing an alloca for `catch_unwind`) - rust-lang/rust#157050 (Couple of changes to help with moving LTO to the link phase) - rust-lang/rust#148345 (add inline to copy_within) - rust-lang/rust#156931 (Add splitting caveats to `{read,write}_volatile`) - rust-lang/rust#156980 (Add frame pointer annotations to the module) - rust-lang/rust#156991 ([AIX] Sync compiler and std with libc changes) - rust-lang/rust#157008 (Avoid some symbol interning) - rust-lang/rust#157038 (android: implement file locking by calling flock) - rust-lang/rust#157071 (Fix `cfg` typo in rustdoc book) - rust-lang/rust#157080 (Fix typo in Rustdoc release notes) - rust-lang/rust#157084 (Clean up error reporting for impl Drop enum casts) - rust-lang/rust#157091 (Remove minicore ping for myself)

41 files changed, 312 insertions(+), 209 deletions(-)

RELEASES.md+1-1
......@@ -57,7 +57,7 @@ Rustdoc
5757-----
5858- [Deprecation notes are now rendered like any other documentation](https://github.com/rust-lang/rust/pull/149931). Previously they used the css `white-space: pre-wrap;` property and stripped any `<p>` elements from the rendered html, however this caused issues and unintuitive behavior. The new behavior should be more predictable, however some multi-line deprecation notes will now be rendered as as single lines. If this is undesirable, you can use the standard markdown method of forcing a linebreak, which is two spaces followed by a newline (`"\n"`).
5959- [Don't emit rustdoc `missing_doc_code_examples` lint on impl items](https://github.com/rust-lang/rust/pull/154048)
60- [Seperate methods and associated functions in sidebar](https://github.com/rust-lang/rust/pull/154644)
60- [Separate methods and associated functions in sidebar](https://github.com/rust-lang/rust/pull/154644)
6161
6262<a id="1.96.0-Compatibility-Notes"></a>
6363
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs+6-6
......@@ -1365,8 +1365,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
13651365 {
13661366 fx.bcx.ins().call_indirect(f_sig, f, &[data]);
13671367
1368 let layout = fx.layout_of(fx.tcx.types.i32);
1369 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout);
1368 let layout = fx.layout_of(fx.tcx.types.bool);
1369 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I8, 0), layout);
13701370 ret.write_cvalue(fx, ret_val);
13711371
13721372 fx.bcx.ins().jump(ret_block, &[]);
......@@ -1399,8 +1399,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
13991399
14001400 fx.bcx.seal_block(fallthrough_block);
14011401 fx.bcx.switch_to_block(fallthrough_block);
1402 let layout = fx.layout_of(fx.tcx.types.i32);
1403 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout);
1402 let layout = fx.layout_of(fx.tcx.types.bool);
1403 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I8, 0), layout);
14041404 ret.write_cvalue(fx, ret_val);
14051405 fx.bcx.ins().jump(ret_block, &[]);
14061406
......@@ -1409,8 +1409,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
14091409 fx.bcx.set_cold_block(catch_block);
14101410 let exception = fx.bcx.append_block_param(catch_block, pointer_ty(fx.tcx));
14111411 fx.bcx.ins().call_indirect(catch_fn_sig, catch_fn, &[data, exception]);
1412 let layout = fx.layout_of(fx.tcx.types.i32);
1413 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 1), layout);
1412 let layout = fx.layout_of(fx.tcx.types.bool);
1413 let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I8, 1), layout);
14141414 ret.write_cvalue(fx, ret_val);
14151415 fx.bcx.ins().jump(ret_block, &[]);
14161416 }
compiler/rustc_codegen_gcc/src/intrinsic/mod.rs+7-7
......@@ -1364,7 +1364,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
13641364 bx.call(fn_type, None, None, try_func, &[data], None, None);
13651365 // Return 0 unconditionally from the intrinsic call;
13661366 // we can never unwind.
1367 OperandValue::Immediate(bx.const_i32(0)).store(bx, dest);
1367 OperandValue::Immediate(bx.const_bool(false)).store(bx, dest);
13681368 } else {
13691369 if wants_msvc_seh(bx.sess()) {
13701370 unimplemented!();
......@@ -1421,7 +1421,7 @@ fn codegen_gnu_try<'gcc, 'tcx>(
14211421 let current_block = bx.block;
14221422
14231423 bx.switch_to_block(then);
1424 bx.ret(bx.const_i32(0));
1424 bx.ret(bx.const_bool(false));
14251425
14261426 // Type indicator for the exception being thrown.
14271427 //
......@@ -1435,7 +1435,7 @@ fn codegen_gnu_try<'gcc, 'tcx>(
14351435 let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
14361436 let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
14371437 bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
1438 bx.ret(bx.const_i32(1));
1438 bx.ret(bx.const_bool(true));
14391439
14401440 // NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
14411441 // generate a try/catch.
......@@ -1468,7 +1468,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
14681468 // Define the type up front for the signature of the rust_try function.
14691469 let tcx = cx.tcx;
14701470 let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8);
1471 // `unsafe fn(*mut i8) -> ()`
1471 // `unsafe fn(*mut Data) -> ()`
14721472 let try_fn_ty = Ty::new_fn_ptr(
14731473 tcx,
14741474 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(
......@@ -1477,7 +1477,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
14771477 rustc_hir::Safety::Unsafe,
14781478 )),
14791479 );
1480 // `unsafe fn(*mut i8, *mut i8) -> ()`
1480 // `unsafe fn(*mut Data, *mut i8) -> ()`
14811481 let catch_fn_ty = Ty::new_fn_ptr(
14821482 tcx,
14831483 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(
......@@ -1486,10 +1486,10 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(
14861486 rustc_hir::Safety::Unsafe,
14871487 )),
14881488 );
1489 // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
1489 // `unsafe fn(unsafe fn(*mut Data) -> (), *mut Data, unsafe fn(*mut Data, *mut i8) -> ()) -> bool`
14901490 let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi(
14911491 [try_fn_ty, i8p, catch_fn_ty],
1492 tcx.types.i32,
1492 tcx.types.bool,
14931493 rustc_hir::Safety::Unsafe,
14941494 ));
14951495 let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
compiler/rustc_codegen_gcc/src/lib.rs+5-3
......@@ -339,9 +339,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {
339339}
340340
341341impl ExtraBackendMethods for GccCodegenBackend {
342 fn supports_parallel(&self) -> bool {
343 false
344 }
342 type Module = GccContext;
345343
346344 fn codegen_allocator(
347345 &self,
......@@ -424,6 +422,10 @@ impl WriteBackendMethods for GccCodegenBackend {
424422 type ModuleBuffer = ModuleBuffer;
425423 type ThinData = ();
426424
425 fn supports_parallel(&self) -> bool {
426 false
427 }
428
427429 fn target_machine_factory(
428430 &self,
429431 _sess: &Session,
compiler/rustc_codegen_llvm/src/attributes.rs+9-4
......@@ -171,10 +171,7 @@ pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>)
171171 llvm::CreateUWTableAttr(llcx, async_unwind)
172172}
173173
174pub(crate) fn frame_pointer_type_attr<'ll>(
175 cx: &SimpleCx<'ll>,
176 sess: &Session,
177) -> Option<&'ll Attribute> {
174pub(crate) fn frame_pointer(sess: &Session) -> FramePointer {
178175 let mut fp = sess.target.frame_pointer;
179176 let opts = &sess.opts;
180177 // "mcount" function relies on stack pointer.
......@@ -183,6 +180,14 @@ pub(crate) fn frame_pointer_type_attr<'ll>(
183180 fp.ratchet(FramePointer::Always);
184181 }
185182 fp.ratchet(opts.cg.force_frame_pointers);
183 fp
184}
185
186pub(crate) fn frame_pointer_type_attr<'ll>(
187 cx: &SimpleCx<'ll>,
188 sess: &Session,
189) -> Option<&'ll Attribute> {
190 let fp = frame_pointer(sess);
186191 let attr_value = match fp {
187192 FramePointer::Always => "all",
188193 FramePointer::NonLeaf => "non-leaf",
compiler/rustc_codegen_llvm/src/context.rs+17-6
......@@ -28,7 +28,8 @@ use rustc_session::config::{
2828use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, sym};
2929use rustc_symbol_mangling::mangle_internal_symbol;
3030use rustc_target::spec::{
31 Arch, CfgAbi, Env, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport, Target, TlsModel,
31 Arch, CfgAbi, Env, FramePointer, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport,
32 Target, TlsModel,
3233};
3334use smallvec::SmallVec;
3435
......@@ -489,6 +490,20 @@ pub(crate) unsafe fn create_module<'ll>(
489490 }
490491 }
491492
493 let fp = attributes::frame_pointer(sess);
494 if fp != FramePointer::MayOmit {
495 llvm::add_module_flag_u32(
496 llmod,
497 llvm::ModuleFlagMergeBehavior::Max,
498 "frame-pointer",
499 match fp {
500 FramePointer::Always => llvm::FramePointerKind::All as u32,
501 FramePointer::NonLeaf => llvm::FramePointerKind::NonLeaf as u32,
502 FramePointer::MayOmit => llvm::FramePointerKind::None as u32,
503 },
504 );
505 }
506
492507 if sess.opts.unstable_opts.indirect_branch_cs_prefix {
493508 llvm::add_module_flag_u32(
494509 llmod,
......@@ -960,11 +975,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
960975 fn intrinsic_call_expects_place_always(&self, name: Symbol) -> bool {
961976 matches!(
962977 name,
963 sym::autodiff
964 | sym::catch_unwind
965 | sym::volatile_load
966 | sym::unaligned_volatile_load
967 | sym::black_box
978 sym::autodiff | sym::volatile_load | sym::unaligned_volatile_load | sym::black_box
968979 )
969980 }
970981}
compiler/rustc_codegen_llvm/src/intrinsic.rs+33-44
......@@ -288,18 +288,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
288288 }
289289 }
290290 sym::catch_unwind => {
291 let result = PlaceRef {
292 val: result_place.unwrap(),
293 layout: result_layout,
294 };
295291 catch_unwind_intrinsic(
296292 self,
297293 args[0].immediate(),
298294 args[1].immediate(),
299295 args[2].immediate(),
300 result,
301 );
302 return IntrinsicResult::WroteIntoPlace;
296 )
303297 }
304298 sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]),
305299 sym::va_arg => {
......@@ -1351,22 +1345,21 @@ fn catch_unwind_intrinsic<'ll, 'tcx>(
13511345 try_func: &'ll Value,
13521346 data: &'ll Value,
13531347 catch_func: &'ll Value,
1354 dest: PlaceRef<'tcx, &'ll Value>,
1355) {
1348) -> &'ll Value {
13561349 if !bx.sess().panic_strategy().unwinds() {
13571350 let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
13581351 bx.call(try_func_ty, None, None, try_func, &[data], None, None);
13591352 // Return 0 unconditionally from the intrinsic call;
13601353 // we can never unwind.
1361 OperandValue::Immediate(bx.const_i32(0)).store(bx, dest);
1354 bx.const_bool(false)
13621355 } else if wants_msvc_seh(bx.sess()) {
1363 codegen_msvc_try(bx, try_func, data, catch_func, dest);
1356 codegen_msvc_try(bx, try_func, data, catch_func)
13641357 } else if wants_wasm_eh(bx.sess()) {
1365 codegen_wasm_try(bx, try_func, data, catch_func, dest);
1358 codegen_wasm_try(bx, try_func, data, catch_func)
13661359 } else if bx.sess().target.os == Os::Emscripten {
1367 codegen_emcc_try(bx, try_func, data, catch_func, dest);
1360 codegen_emcc_try(bx, try_func, data, catch_func)
13681361 } else {
1369 codegen_gnu_try(bx, try_func, data, catch_func, dest);
1362 codegen_gnu_try(bx, try_func, data, catch_func)
13701363 }
13711364}
13721365
......@@ -1382,8 +1375,7 @@ fn codegen_msvc_try<'ll, 'tcx>(
13821375 try_func: &'ll Value,
13831376 data: &'ll Value,
13841377 catch_func: &'ll Value,
1385 dest: PlaceRef<'tcx, &'ll Value>,
1386) {
1378) -> &'ll Value {
13871379 let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
13881380 bx.set_personality_fn(bx.eh_personality());
13891381
......@@ -1399,12 +1391,12 @@ fn codegen_msvc_try<'ll, 'tcx>(
13991391
14001392 // We're generating an IR snippet that looks like:
14011393 //
1402 // declare i32 @rust_try(%try_func, %data, %catch_func) {
1394 // declare bool @rust_try(%try_func, %data, %catch_func) {
14031395 // %slot = alloca i8*
14041396 // invoke %try_func(%data) to label %normal unwind label %catchswitch
14051397 //
14061398 // normal:
1407 // ret i32 0
1399 // ret i1 false
14081400 //
14091401 // catchswitch:
14101402 // %cs = catchswitch within none [%catchpad_rust, %catchpad_foreign] unwind to caller
......@@ -1421,7 +1413,7 @@ fn codegen_msvc_try<'ll, 'tcx>(
14211413 // catchret from %tok to label %caught
14221414 //
14231415 // caught:
1424 // ret i32 1
1416 // ret i1 true
14251417 // }
14261418 //
14271419 // This structure follows the basic usage of throw/try/catch in LLVM.
......@@ -1459,7 +1451,7 @@ fn codegen_msvc_try<'ll, 'tcx>(
14591451 bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
14601452
14611453 bx.switch_to_block(normal);
1462 bx.ret(bx.const_i32(0));
1454 bx.ret(bx.const_bool(false));
14631455
14641456 bx.switch_to_block(catchswitch);
14651457 let cs = bx.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]);
......@@ -1516,13 +1508,13 @@ fn codegen_msvc_try<'ll, 'tcx>(
15161508 bx.catch_ret(&funclet, caught);
15171509
15181510 bx.switch_to_block(caught);
1519 bx.ret(bx.const_i32(1));
1511 bx.ret(bx.const_bool(true));
15201512 });
15211513
15221514 // Note that no invoke is used here because by definition this function
15231515 // can't panic (that's what it's catching).
15241516 let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1525 OperandValue::Immediate(ret).store(bx, dest);
1517 ret
15261518}
15271519
15281520// WASM's definition of the `rust_try` function.
......@@ -1531,8 +1523,7 @@ fn codegen_wasm_try<'ll, 'tcx>(
15311523 try_func: &'ll Value,
15321524 data: &'ll Value,
15331525 catch_func: &'ll Value,
1534 dest: PlaceRef<'tcx, &'ll Value>,
1535) {
1526) -> &'ll Value {
15361527 let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
15371528 bx.set_personality_fn(bx.eh_personality());
15381529
......@@ -1547,12 +1538,12 @@ fn codegen_wasm_try<'ll, 'tcx>(
15471538
15481539 // We're generating an IR snippet that looks like:
15491540 //
1550 // declare i32 @rust_try(%try_func, %data, %catch_func) {
1541 // declare i1 @rust_try(%try_func, %data, %catch_func) {
15511542 // %slot = alloca i8*
15521543 // invoke %try_func(%data) to label %normal unwind label %catchswitch
15531544 //
15541545 // normal:
1555 // ret i32 0
1546 // ret i1 false
15561547 //
15571548 // catchswitch:
15581549 // %cs = catchswitch within none [%catchpad] unwind to caller
......@@ -1565,14 +1556,14 @@ fn codegen_wasm_try<'ll, 'tcx>(
15651556 // catchret from %tok to label %caught
15661557 //
15671558 // caught:
1568 // ret i32 1
1559 // ret i1 true
15691560 // }
15701561 //
15711562 let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
15721563 bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
15731564
15741565 bx.switch_to_block(normal);
1575 bx.ret(bx.const_i32(0));
1566 bx.ret(bx.const_bool(false));
15761567
15771568 bx.switch_to_block(catchswitch);
15781569 let cs = bx.catch_switch(None, None, &[catchpad]);
......@@ -1589,13 +1580,13 @@ fn codegen_wasm_try<'ll, 'tcx>(
15891580 bx.catch_ret(&funclet, caught);
15901581
15911582 bx.switch_to_block(caught);
1592 bx.ret(bx.const_i32(1));
1583 bx.ret(bx.const_bool(true));
15931584 });
15941585
15951586 // Note that no invoke is used here because by definition this function
15961587 // can't panic (that's what it's catching).
15971588 let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1598 OperandValue::Immediate(ret).store(bx, dest);
1589 ret
15991590}
16001591
16011592// Definition of the standard `try` function for Rust using the GNU-like model
......@@ -1614,8 +1605,7 @@ fn codegen_gnu_try<'ll, 'tcx>(
16141605 try_func: &'ll Value,
16151606 data: &'ll Value,
16161607 catch_func: &'ll Value,
1617 dest: PlaceRef<'tcx, &'ll Value>,
1618) {
1608) -> &'ll Value {
16191609 let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
16201610 // Codegens the shims described above:
16211611 //
......@@ -1639,7 +1629,7 @@ fn codegen_gnu_try<'ll, 'tcx>(
16391629 bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
16401630
16411631 bx.switch_to_block(then);
1642 bx.ret(bx.const_i32(0));
1632 bx.ret(bx.const_bool(false));
16431633
16441634 // Type indicator for the exception being thrown.
16451635 //
......@@ -1655,13 +1645,13 @@ fn codegen_gnu_try<'ll, 'tcx>(
16551645 let ptr = bx.extract_value(vals, 0);
16561646 let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
16571647 bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
1658 bx.ret(bx.const_i32(1));
1648 bx.ret(bx.const_bool(true));
16591649 });
16601650
16611651 // Note that no invoke is used here because by definition this function
16621652 // can't panic (that's what it's catching).
16631653 let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1664 OperandValue::Immediate(ret).store(bx, dest);
1654 ret
16651655}
16661656
16671657// Variant of codegen_gnu_try used for emscripten where Rust panics are
......@@ -1672,8 +1662,7 @@ fn codegen_emcc_try<'ll, 'tcx>(
16721662 try_func: &'ll Value,
16731663 data: &'ll Value,
16741664 catch_func: &'ll Value,
1675 dest: PlaceRef<'tcx, &'ll Value>,
1676) {
1665) -> &'ll Value {
16771666 let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
16781667 // Codegens the shims described above:
16791668 //
......@@ -1702,7 +1691,7 @@ fn codegen_emcc_try<'ll, 'tcx>(
17021691 bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
17031692
17041693 bx.switch_to_block(then);
1705 bx.ret(bx.const_i32(0));
1694 bx.ret(bx.const_bool(false));
17061695
17071696 // Type indicator for the exception being thrown.
17081697 //
......@@ -1737,13 +1726,13 @@ fn codegen_emcc_try<'ll, 'tcx>(
17371726
17381727 let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
17391728 bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None, None);
1740 bx.ret(bx.const_i32(1));
1729 bx.ret(bx.const_bool(true));
17411730 });
17421731
17431732 // Note that no invoke is used here because by definition this function
17441733 // can't panic (that's what it's catching).
17451734 let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1746 OperandValue::Immediate(ret).store(bx, dest);
1735 ret
17471736}
17481737
17491738// Helper function to give a Block to a closure to codegen a shim function.
......@@ -1782,20 +1771,20 @@ fn get_rust_try_fn<'a, 'll, 'tcx>(
17821771 // Define the type up front for the signature of the rust_try function.
17831772 let tcx = cx.tcx;
17841773 let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8);
1785 // `unsafe fn(*mut i8) -> ()`
1774 // `unsafe fn(*mut Data) -> ()`
17861775 let try_fn_ty = Ty::new_fn_ptr(
17871776 tcx,
17881777 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p], tcx.types.unit, hir::Safety::Unsafe)),
17891778 );
1790 // `unsafe fn(*mut i8, *mut i8) -> ()`
1779 // `unsafe fn(*mut Data, *mut i8) -> ()`
17911780 let catch_fn_ty = Ty::new_fn_ptr(
17921781 tcx,
17931782 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p, i8p], tcx.types.unit, hir::Safety::Unsafe)),
17941783 );
1795 // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
1784 // `unsafe fn(unsafe fn(*mut Data) -> (), *mut Data, unsafe fn(*mut Data, *mut i8) -> ()) -> bool`
17961785 let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi(
17971786 [try_fn_ty, i8p, catch_fn_ty],
1798 tcx.types.i32,
1787 tcx.types.bool,
17991788 hir::Safety::Unsafe,
18001789 ));
18011790 let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
compiler/rustc_codegen_llvm/src/lib.rs+3
......@@ -93,6 +93,8 @@ impl Drop for TimeTraceProfiler {
9393}
9494
9595impl ExtraBackendMethods for LlvmCodegenBackend {
96 type Module = ModuleLlvm;
97
9698 fn codegen_allocator<'tcx>(
9799 &self,
98100 tcx: TyCtxt<'tcx>,
......@@ -121,6 +123,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
121123 type ModuleBuffer = back::lto::ModuleBuffer;
122124 type TargetMachine = OwnedTargetMachine;
123125 type ThinData = back::lto::ThinData;
126
124127 fn thread_profiler() -> Box<dyn Any> {
125128 Box::new(TimeTraceProfiler::new())
126129 }
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+12
......@@ -251,6 +251,18 @@ pub(crate) enum UWTableKind {
251251 Async = 2,
252252}
253253
254/// Must match the layout of `llvm::FramePointerKind`.
255#[repr(C)]
256#[derive(Copy, Clone, Debug)]
257#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM")]
258pub(crate) enum FramePointerKind {
259 None = 0,
260 NonLeaf = 1,
261 All = 2,
262 Reserved = 3,
263 NonLeafNoReserve = 4,
264}
265
254266/// Must match the layout of `LLVMRustAttributeKind`.
255267/// Semantically a subset of the C++ enum llvm::Attribute::AttrKind,
256268/// though it is not ABI compatible (since it's a C++ enum)
compiler/rustc_codegen_ssa/src/back/write.rs+5-16
......@@ -352,7 +352,7 @@ pub struct CodegenContext {
352352 pub incr_comp_session_dir: Option<PathBuf>,
353353 /// `true` if the codegen should be run in parallel.
354354 ///
355 /// Depends on [`ExtraBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`.
355 /// Depends on [`WriteBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`.
356356 pub parallel: bool,
357357}
358358
......@@ -416,7 +416,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
416416 }
417417}
418418
419pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
419pub(crate) fn start_async_codegen<B: WriteBackendMethods>(
420420 backend: B,
421421 tcx: TyCtxt<'_>,
422422 allocator_module: Option<ModuleCodegen<B::Module>>,
......@@ -1115,18 +1115,6 @@ fn do_thin_lto<B: WriteBackendMethods>(
11151115 compiled_modules
11161116}
11171117
1118fn execute_thin_lto_work_item<B: WriteBackendMethods>(
1119 cgcx: &CodegenContext,
1120 prof: &SelfProfilerRef,
1121 shared_emitter: SharedEmitter,
1122 tm_factory: TargetMachineFactoryFn<B>,
1123 module: lto::ThinModule<B>,
1124) -> CompiledModule {
1125 let _timer = prof.generic_activity_with_arg("codegen_module_perform_lto", module.name());
1126
1127 B::optimize_and_codegen_thin(cgcx, prof, &shared_emitter, tm_factory, module)
1128}
1129
11301118/// Messages sent to the coordinator.
11311119pub(crate) enum Message<B: WriteBackendMethods> {
11321120 /// A jobserver token has become available. Sent from the jobserver helper
......@@ -1208,7 +1196,7 @@ enum MainThreadState {
12081196 Lending,
12091197}
12101198
1211fn start_executing_work<B: ExtraBackendMethods>(
1199fn start_executing_work<B: WriteBackendMethods>(
12121200 backend: B,
12131201 tcx: TyCtxt<'_>,
12141202 shared_emitter: SharedEmitter,
......@@ -1891,7 +1879,8 @@ fn spawn_thin_lto_work<B: WriteBackendMethods>(
18911879 execute_copy_from_cache_work_item(&cgcx, &prof, shared_emitter, m)
18921880 }
18931881 ThinLtoWorkItem::ThinLto(m) => {
1894 execute_thin_lto_work_item(&cgcx, &prof, shared_emitter, tm_factory, m)
1882 let _timer = prof.generic_activity_with_arg("codegen_module_perform_lto", m.name());
1883 B::optimize_and_codegen_thin(&cgcx, &prof, &shared_emitter, tm_factory, m)
18951884 }
18961885 }));
18971886
compiler/rustc_codegen_ssa/src/base.rs+7-1
......@@ -688,7 +688,13 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec<Allo
688688 methods
689689}
690690
691pub fn codegen_crate<B: ExtraBackendMethods>(backend: B, tcx: TyCtxt<'_>) -> OngoingCodegen<B> {
691pub fn codegen_crate<
692 B: ExtraBackendMethods<Module = M> + WriteBackendMethods<Module = M>,
693 M: Send,
694>(
695 backend: B,
696 tcx: TyCtxt<'_>,
697) -> OngoingCodegen<B> {
692698 if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() {
693699 // The target has no default cpu, but none is set explicitly
694700 tcx.dcx().emit_fatal(errors::CpuRequired);
compiler/rustc_codegen_ssa/src/traits/backend.rs+3-11
......@@ -14,7 +14,6 @@ use rustc_session::config::{CrateType, OutputFilenames, PrintRequest};
1414use rustc_span::Symbol;
1515
1616use super::CodegenObject;
17use super::write::WriteBackendMethods;
1817use crate::back::archive::ArArchiveBuilderBuilder;
1918use crate::back::link::link_binary;
2019use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
......@@ -162,9 +161,9 @@ pub trait CodegenBackend {
162161 }
163162}
164163
165pub trait ExtraBackendMethods:
166 WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
167{
164pub trait ExtraBackendMethods: Send + Sync + DynSend + DynSync {
165 type Module;
166
168167 fn codegen_allocator<'tcx>(
169168 &self,
170169 tcx: TyCtxt<'tcx>,
......@@ -179,11 +178,4 @@ pub trait ExtraBackendMethods:
179178 tcx: TyCtxt<'_>,
180179 cgu_name: Symbol,
181180 ) -> (ModuleCodegen<Self::Module>, u64);
182
183 /// Returns `true` if this backend can be safely called from multiple threads.
184 ///
185 /// Defaults to `true`.
186 fn supports_parallel(&self) -> bool {
187 true
188 }
189181}
compiler/rustc_codegen_ssa/src/traits/write.rs+13
......@@ -1,4 +1,5 @@
11use std::any::Any;
2use std::convert::Infallible;
23use std::path::PathBuf;
34
45use rustc_data_structures::profiling::SelfProfilerRef;
......@@ -18,6 +19,12 @@ pub trait WriteBackendMethods: Clone + 'static {
1819 type ModuleBuffer: ModuleBufferMethods;
1920 type ThinData: Send + Sync;
2021
22 /// Returns `true` if this backend can be safely called from multiple threads.
23 ///
24 /// Defaults to `true`.
25 fn supports_parallel(&self) -> bool {
26 true
27 }
2128 fn thread_profiler() -> Box<dyn Any> {
2229 Box::new(())
2330 }
......@@ -76,3 +83,9 @@ pub trait WriteBackendMethods: Clone + 'static {
7683pub trait ModuleBufferMethods: Send + Sync {
7784 fn data(&self) -> &[u8];
7885}
86
87impl ModuleBufferMethods for Infallible {
88 fn data(&self) -> &[u8] {
89 match *self {}
90 }
91}
compiler/rustc_hir_analysis/src/check/intrinsic.rs+8-6
......@@ -637,16 +637,18 @@ pub(crate) fn check_intrinsic_type(
637637 }
638638
639639 sym::catch_unwind => {
640 let mut_data = Ty::new_mut_ptr(tcx, param(0));
640641 let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
641642 let try_fn_ty =
642 ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([mut_u8], tcx.types.unit));
643 let catch_fn_ty =
644 ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([mut_u8, mut_u8], tcx.types.unit));
643 ty::Binder::dummy(tcx.mk_fn_sig_unsafe_rust_abi([mut_data], tcx.types.unit));
644 let catch_fn_ty = ty::Binder::dummy(
645 tcx.mk_fn_sig_unsafe_rust_abi([mut_data, mut_u8], tcx.types.unit),
646 );
645647 (
648 1,
646649 0,
647 0,
648 vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_u8, Ty::new_fn_ptr(tcx, catch_fn_ty)],
649 tcx.types.i32,
650 vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_data, Ty::new_fn_ptr(tcx, catch_fn_ty)],
651 tcx.types.bool,
650652 )
651653 }
652654
compiler/rustc_hir_analysis/src/collect/generics_of.rs+10-14
......@@ -9,7 +9,7 @@ use rustc_hir::{self as hir, AmbigArg, GenericParamKind, HirId, Node};
99use rustc_middle::span_bug;
1010use rustc_middle::ty::{self, TyCtxt};
1111use rustc_session::lint;
12use rustc_span::{Span, Symbol, kw};
12use rustc_span::{Span, kw, sym};
1313use tracing::{debug, instrument};
1414
1515use crate::middle::resolve_bound_vars as rbv;
......@@ -328,22 +328,18 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
328328 {
329329 // See `ClosureArgsParts`, `CoroutineArgsParts`, and `CoroutineClosureArgsParts`
330330 // for info on the usage of each of these fields.
331 let dummy_args = match kind {
332 ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
333 ClosureKind::Coroutine(_) => {
334 &["<coroutine_kind>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
335 }
336 ClosureKind::CoroutineClosure(_) => &[
337 "<closure_kind>",
338 "<closure_signature_parts>",
339 "<upvars>",
340 "<bound_captures_by_ref>",
341 ][..],
331 let len = match kind {
332 // The args are: closure_kind, closure_signature, upvars.
333 ClosureKind::Closure => 3,
334 // The args are: coroutine_kind, resume_ty, yield_ty, return_ty, upvars.
335 ClosureKind::Coroutine(_) => 5,
336 // The args are: closure_kind, closure_signature_parts, upvars, bound_captures_by_ref.
337 ClosureKind::CoroutineClosure(_) => 4,
342338 };
343339
344 own_params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef {
340 own_params.extend((0..len).map(|_| ty::GenericParamDef {
345341 index: next_index(),
346 name: Symbol::intern(arg),
342 name: sym::empty, // dummy; exact value doesn't matter
347343 def_id: def_id.to_def_id(),
348344 pure_wrt_drop: false,
349345 kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
compiler/rustc_hir_typeck/src/cast.rs+20-15
......@@ -175,6 +175,7 @@ enum CastError<'tcx> {
175175 NonScalar,
176176 UnknownExprPtrKind,
177177 UnknownCastPtrKind,
178 CastEnumDrop,
178179 /// Cast of int to (possibly) wide raw pointer.
179180 ///
180181 /// Argument is the specific name of the metadata in plain words, such as "a vtable"
......@@ -635,6 +636,12 @@ impl<'a, 'tcx> CastCheck<'tcx> {
635636 };
636637 fcx.dcx().emit_err(errors::CastUnknownPointer { span, to: unknown_cast_to, sub });
637638 }
639 CastError::CastEnumDrop => {
640 let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
641 let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
642
643 fcx.dcx().emit_err(errors::CastEnumDrop { span: self.span, expr_ty, cast_ty });
644 }
638645 CastError::ForeignNonExhaustiveAdt => {
639646 make_invalid_casting_error(
640647 self.span,
......@@ -870,11 +877,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
870877 // fn-ptr-cast
871878 (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
872879
880 // enum -> int
881 (Int(CEnum), Int(_)) => self.check_enum_cast(fcx),
882
873883 // prim -> prim
874 (Int(CEnum), Int(_)) => {
875 self.err_if_cenum_impl_drop(fcx);
876 Ok(CastKind::EnumCast)
877 }
878884 (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
879885
880886 (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
......@@ -1109,21 +1115,20 @@ impl<'a, 'tcx> CastCheck<'tcx> {
11091115 }
11101116 }
11111117
1112 fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<(), ty::error::TypeError<'tcx>> {
1113 match fcx.coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
1114 Ok(_) => Ok(()),
1115 Err(err) => Err(err),
1116 }
1117 }
1118
1119 fn err_if_cenum_impl_drop(&self, fcx: &FnCtxt<'a, 'tcx>) {
1118 fn check_enum_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError<'tcx>> {
11201119 if let ty::Adt(d, _) = self.expr_ty.kind()
11211120 && d.has_dtor(fcx.tcx)
11221121 {
1123 let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
1124 let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
1122 Err(CastError::CastEnumDrop)
1123 } else {
1124 Ok(CastKind::EnumCast)
1125 }
1126 }
11251127
1126 fcx.dcx().emit_err(errors::CastEnumDrop { span: self.span, expr_ty, cast_ty });
1128 fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<(), ty::error::TypeError<'tcx>> {
1129 match fcx.coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
1130 Ok(_) => Ok(()),
1131 Err(err) => Err(err),
11271132 }
11281133 }
11291134
compiler/rustc_middle/src/ty/context.rs+9
......@@ -2361,6 +2361,15 @@ impl<'tcx> TyCtxt<'tcx> {
23612361 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
23622362 }
23632363
2364 /// `mk_fn_sig`, but with an **un**safe Rust ABI, and no C-variadic argument.
2365 pub fn mk_fn_sig_unsafe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Output
2366 where
2367 I: IntoIterator<Item = T>,
2368 T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
2369 {
2370 self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Unsafe))
2371 }
2372
23642373 pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
23652374 where
23662375 I: Iterator<Item = T>,
compiler/rustc_session/src/filesearch.rs+1-1
......@@ -102,7 +102,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
102102 loop {
103103 if libc::loadquery(
104104 libc::L_GETINFO,
105 buffer.as_mut_ptr() as *mut u8,
105 buffer.as_mut_ptr() as *mut libc::c_void,
106106 (size_of::<libc::ld_info>() * buffer.len()) as u32,
107107 ) >= 0
108108 {
compiler/rustc_span/src/lib.rs+38
......@@ -34,6 +34,7 @@ use derive_where::derive_where;
3434use rustc_data_structures::stable_hash::StableHashCtxt;
3535use rustc_data_structures::{AtomicRef, outline};
3636use rustc_macros::{Decodable, Encodable, StableHash};
37use rustc_serialize::opaque::mem_encoder::MemEncoder;
3738use rustc_serialize::opaque::{FileEncoder, MemDecoder};
3839use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
3940use tracing::debug;
......@@ -1398,6 +1399,43 @@ impl SpanEncoder for FileEncoder {
13981399 }
13991400}
14001401
1402impl SpanEncoder for MemEncoder {
1403 fn encode_span(&mut self, span: Span) {
1404 let span = span.data();
1405 span.lo.encode(self);
1406 span.hi.encode(self);
1407 }
1408
1409 fn encode_symbol(&mut self, sym: Symbol) {
1410 self.emit_str(sym.as_str());
1411 }
1412
1413 fn encode_byte_symbol(&mut self, byte_sym: ByteSymbol) {
1414 self.emit_byte_str(byte_sym.as_byte_str());
1415 }
1416
1417 fn encode_expn_id(&mut self, _expn_id: ExpnId) {
1418 panic!("cannot encode `ExpnId` with `FileEncoder`");
1419 }
1420
1421 fn encode_syntax_context(&mut self, _syntax_context: SyntaxContext) {
1422 panic!("cannot encode `SyntaxContext` with `FileEncoder`");
1423 }
1424
1425 fn encode_crate_num(&mut self, crate_num: CrateNum) {
1426 self.emit_u32(crate_num.as_u32());
1427 }
1428
1429 fn encode_def_index(&mut self, _def_index: DefIndex) {
1430 panic!("cannot encode `DefIndex` with `FileEncoder`");
1431 }
1432
1433 fn encode_def_id(&mut self, def_id: DefId) {
1434 def_id.krate.encode(self);
1435 def_id.index.encode(self);
1436 }
1437}
1438
14011439impl<E: SpanEncoder> Encodable<E> for Span {
14021440 fn encode(&self, s: &mut E) {
14031441 s.encode_span(*self);
library/core/src/intrinsics/mod.rs+6-6
......@@ -2232,7 +2232,7 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina
22322232
22332233/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
22342234/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
2235/// Returns `1` if unwinding occurred and `catch_fn` was called; returns `0` otherwise.
2235/// Returns `true` if unwinding occurred and `catch_fn` was called; returns `false` otherwise.
22362236///
22372237/// `catch_fn` must not unwind.
22382238///
......@@ -2249,11 +2249,11 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina
22492249/// version of this intrinsic, `std::panic::catch_unwind`.
22502250#[rustc_intrinsic]
22512251#[rustc_nounwind]
2252pub unsafe fn catch_unwind(
2253 _try_fn: fn(*mut u8),
2254 _data: *mut u8,
2255 _catch_fn: fn(*mut u8, *mut u8),
2256) -> i32;
2252pub unsafe fn catch_unwind<Data: ptr::Thin>(
2253 _try_fn: unsafe fn(*mut Data),
2254 _data: *mut Data,
2255 _catch_fn: unsafe fn(*mut Data, *mut u8),
2256) -> bool;
22572257
22582258/// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held
22592259/// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`.
library/core/src/ptr/mod.rs+30
......@@ -2054,6 +2054,21 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
20542054/// [allocation]: crate::ptr#allocated-object
20552055/// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses
20562056///
2057/// # Load splitting
2058///
2059/// Exactly which hardware loads are performed by this function is, in general, highly target-dependent.
2060///
2061/// For a simple scalar, such as when `T` is a thin pointer, this will typically be one load assuming
2062/// your target supports a load of exactly that size and alignment.
2063///
2064/// For anything else, it will be split into multiple loads in some unspecified way.
2065/// This can happen even for scalars: notably, on many targets loading a `u128` will still need to be split,
2066/// despite being "one" scalar. On many targets loading anything larger than a pointer will need to be split.
2067/// On all current targets a load larger than 64 bytes will need to be split.
2068/// Any load whose size is not a power of two will also almost certainly need to be split.
2069///
2070/// There is no stability guarantee on how that splitting happens. It may change at any point.
2071///
20572072/// # Safety
20582073///
20592074/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of whether `T` is
......@@ -2147,6 +2162,21 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
21472162/// [allocation]: crate::ptr#allocated-object
21482163/// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses
21492164///
2165/// # Store splitting
2166///
2167/// Exactly which hardware stores are performed by this function is, in general, highly target-dependent.
2168///
2169/// For a simple scalar, such as when `T` is a thin pointer, this will typically be one store assuming
2170/// your target supports a store of exactly that size and alignment.
2171///
2172/// For anything else, it will be split into multiple stores in some unspecified way.
2173/// This can happen even for scalars: notably, on many targets storing a `u128` will still need to be split,
2174/// despite being "one" scalar. On many targets storing anything larger than a pointer will need to be split.
2175/// On all current targets a store larger than 64 bytes will need to be split.
2176/// Any store whose size is not a power of two will also almost certainly need to be split.
2177///
2178/// There is no stability guarantee on how that splitting happens. It may change at any point.
2179///
21502180/// # Safety
21512181///
21522182/// Behavior is undefined if any of the following conditions are violated:
library/core/src/slice/mod.rs+1
......@@ -4350,6 +4350,7 @@ impl<T> [T] {
43504350 ///
43514351 /// assert_eq!(&bytes, b"Hello, Wello!");
43524352 /// ```
4353 #[inline]
43534354 #[stable(feature = "copy_within", since = "1.37.0")]
43544355 #[track_caller]
43554356 pub fn copy_within<R: RangeBounds<usize>>(&mut self, src: R, dest: usize)
library/std/src/fs/tests.rs+5
......@@ -187,6 +187,7 @@ fn file_test_io_seek_and_write() {
187187 target_os = "netbsd",
188188 target_os = "openbsd",
189189 target_os = "solaris",
190 target_os = "android",
190191 target_vendor = "apple",
191192 )),
192193 should_panic
......@@ -220,6 +221,7 @@ fn file_lock_multiple_shared() {
220221 target_os = "netbsd",
221222 target_os = "openbsd",
222223 target_os = "solaris",
224 target_os = "android",
223225 target_vendor = "apple",
224226 )),
225227 should_panic
......@@ -254,6 +256,7 @@ fn file_lock_blocking() {
254256 target_os = "netbsd",
255257 target_os = "openbsd",
256258 target_os = "solaris",
259 target_os = "android",
257260 target_vendor = "apple",
258261 )),
259262 should_panic
......@@ -285,6 +288,7 @@ fn file_lock_drop() {
285288 target_os = "netbsd",
286289 target_os = "openbsd",
287290 target_os = "solaris",
291 target_os = "android",
288292 target_vendor = "apple",
289293 )),
290294 should_panic
......@@ -318,6 +322,7 @@ fn file_lock_dup() {
318322 target_os = "netbsd",
319323 target_os = "openbsd",
320324 target_os = "solaris",
325 target_os = "android",
321326 target_vendor = "apple",
322327 )),
323328 should_panic
library/std/src/os/aix/fs.rs+6-6
......@@ -322,22 +322,22 @@ impl MetadataExt for Metadata {
322322 self.as_inner().as_inner().st_size as u64
323323 }
324324 fn st_atime(&self) -> i64 {
325 self.as_inner().as_inner().st_atime.tv_sec as i64
325 self.as_inner().as_inner().st_atim.tv_sec as i64
326326 }
327327 fn st_atime_nsec(&self) -> i64 {
328 self.as_inner().as_inner().st_atime.tv_nsec as i64
328 self.as_inner().as_inner().st_atim.tv_nsec as i64
329329 }
330330 fn st_mtime(&self) -> i64 {
331 self.as_inner().as_inner().st_mtime.tv_sec as i64
331 self.as_inner().as_inner().st_mtim.tv_sec as i64
332332 }
333333 fn st_mtime_nsec(&self) -> i64 {
334 self.as_inner().as_inner().st_mtime.tv_nsec as i64
334 self.as_inner().as_inner().st_mtim.tv_nsec as i64
335335 }
336336 fn st_ctime(&self) -> i64 {
337 self.as_inner().as_inner().st_ctime.tv_sec as i64
337 self.as_inner().as_inner().st_ctim.tv_sec as i64
338338 }
339339 fn st_ctime_nsec(&self) -> i64 {
340 self.as_inner().as_inner().st_ctime.tv_nsec as i64
340 self.as_inner().as_inner().st_ctim.tv_nsec as i64
341341 }
342342 fn st_blksize(&self) -> u64 {
343343 self.as_inner().as_inner().st_blksize as u64
library/std/src/panicking.rs+8-19
......@@ -530,7 +530,6 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any +
530530 // method of calling a catch panic whilst juggling ownership.
531531 let mut data = Data { f: ManuallyDrop::new(f) };
532532
533 let data_ptr = (&raw mut data) as *mut u8;
534533 // SAFETY:
535534 //
536535 // Access to the union's fields: this is `std` and we know that the `catch_unwind`
......@@ -541,10 +540,10 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any +
541540 // - `do_catch`, the second argument, can be called with the `data_ptr` as well.
542541 // See their safety preconditions for more information
543542 unsafe {
544 return if intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
545 Ok(ManuallyDrop::into_inner(data.r))
546 } else {
543 return if intrinsics::catch_unwind(do_call, &raw mut data, do_catch) {
547544 Err(ManuallyDrop::into_inner(data.p))
545 } else {
546 Ok(ManuallyDrop::into_inner(data.r))
548547 };
549548 }
550549
......@@ -568,17 +567,12 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any +
568567 // data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
569568 // Its must contains a valid `f` (type: F) value that can be use to fill
570569 // `data.r`.
571 //
572 // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
573 // expects normal function pointers.
574570 #[inline]
575 fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
571 unsafe fn do_call<F: FnOnce() -> R, R>(data: *mut Data<F, R>) {
576572 // SAFETY: this is the responsibility of the caller, see above.
577573 unsafe {
578 let data = data as *mut Data<F, R>;
579 let data = &mut (*data);
580 let f = ManuallyDrop::take(&mut data.f);
581 data.r = ManuallyDrop::new(f());
574 let f = ManuallyDrop::take(&mut (*data).f);
575 (*data).r = ManuallyDrop::new(f());
582576 }
583577 }
584578
......@@ -590,22 +584,17 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any +
590584 // data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
591585 // Since this uses `cleanup` it also hinges on a correct implementation of
592586 // `__rustc_panic_cleanup`.
593 //
594 // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
595 // expects normal function pointers.
596587 #[inline]
597588 #[rustc_nounwind] // `intrinsic::catch_unwind` requires catch fn to be nounwind
598 fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
589 unsafe fn do_catch<F: FnOnce() -> R, R>(data: *mut Data<F, R>, payload: *mut u8) {
599590 // SAFETY: this is the responsibility of the caller, see above.
600591 //
601592 // When `__rustc_panic_cleaner` is correctly implemented we can rely
602593 // on `obj` being the correct thing to pass to `data.p` (after wrapping
603594 // in `ManuallyDrop`).
604595 unsafe {
605 let data = data as *mut Data<F, R>;
606 let data = &mut (*data);
607596 let obj = cleanup(payload);
608 data.p = ManuallyDrop::new(obj);
597 (*data).p = ManuallyDrop::new(obj);
609598 }
610599 }
611600}
library/std/src/sys/fs/unix.rs+13-3
......@@ -599,15 +599,15 @@ impl FileAttr {
599599#[cfg(target_os = "aix")]
600600impl FileAttr {
601601 pub fn modified(&self) -> io::Result<SystemTime> {
602 SystemTime::new(self.stat.st_mtime.tv_sec as i64, self.stat.st_mtime.tv_nsec as i64)
602 SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64)
603603 }
604604
605605 pub fn accessed(&self) -> io::Result<SystemTime> {
606 SystemTime::new(self.stat.st_atime.tv_sec as i64, self.stat.st_atime.tv_nsec as i64)
606 SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
607607 }
608608
609609 pub fn created(&self) -> io::Result<SystemTime> {
610 SystemTime::new(self.stat.st_ctime.tv_sec as i64, self.stat.st_ctime.tv_nsec as i64)
610 SystemTime::new(self.stat.st_ctim.tv_sec as i64, self.stat.st_ctim.tv_nsec as i64)
611611 }
612612}
613613
......@@ -1451,6 +1451,7 @@ impl File {
14511451 target_os = "cygwin",
14521452 target_os = "illumos",
14531453 target_os = "aix",
1454 target_os = "android",
14541455 target_vendor = "apple",
14551456 ))]
14561457 pub fn lock(&self) -> io::Result<()> {
......@@ -1478,6 +1479,7 @@ impl File {
14781479 target_os = "solaris",
14791480 target_os = "illumos",
14801481 target_os = "aix",
1482 target_os = "android",
14811483 target_vendor = "apple",
14821484 )))]
14831485 pub fn lock(&self) -> io::Result<()> {
......@@ -1494,6 +1496,7 @@ impl File {
14941496 target_os = "cygwin",
14951497 target_os = "illumos",
14961498 target_os = "aix",
1499 target_os = "android",
14971500 target_vendor = "apple",
14981501 ))]
14991502 pub fn lock_shared(&self) -> io::Result<()> {
......@@ -1521,6 +1524,7 @@ impl File {
15211524 target_os = "solaris",
15221525 target_os = "illumos",
15231526 target_os = "aix",
1527 target_os = "android",
15241528 target_vendor = "apple",
15251529 )))]
15261530 pub fn lock_shared(&self) -> io::Result<()> {
......@@ -1537,6 +1541,7 @@ impl File {
15371541 target_os = "cygwin",
15381542 target_os = "illumos",
15391543 target_os = "aix",
1544 target_os = "android",
15401545 target_vendor = "apple",
15411546 ))]
15421547 pub fn try_lock(&self) -> Result<(), TryLockError> {
......@@ -1580,6 +1585,7 @@ impl File {
15801585 target_os = "solaris",
15811586 target_os = "illumos",
15821587 target_os = "aix",
1588 target_os = "android",
15831589 target_vendor = "apple",
15841590 )))]
15851591 pub fn try_lock(&self) -> Result<(), TryLockError> {
......@@ -1599,6 +1605,7 @@ impl File {
15991605 target_os = "cygwin",
16001606 target_os = "illumos",
16011607 target_os = "aix",
1608 target_os = "android",
16021609 target_vendor = "apple",
16031610 ))]
16041611 pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
......@@ -1642,6 +1649,7 @@ impl File {
16421649 target_os = "solaris",
16431650 target_os = "illumos",
16441651 target_os = "aix",
1652 target_os = "android",
16451653 target_vendor = "apple",
16461654 )))]
16471655 pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
......@@ -1661,6 +1669,7 @@ impl File {
16611669 target_os = "cygwin",
16621670 target_os = "illumos",
16631671 target_os = "aix",
1672 target_os = "android",
16641673 target_vendor = "apple",
16651674 ))]
16661675 pub fn unlock(&self) -> io::Result<()> {
......@@ -1688,6 +1697,7 @@ impl File {
16881697 target_os = "solaris",
16891698 target_os = "illumos",
16901699 target_os = "aix",
1700 target_os = "android",
16911701 target_vendor = "apple",
16921702 )))]
16931703 pub fn unlock(&self) -> io::Result<()> {
src/doc/rustdoc/src/write-documentation/re-exports.md+1-1
......@@ -172,7 +172,7 @@ pub use self::private_mod::Second as Visible;
172172```
173173
174174In this case, `Visible` will have as documentation `First Second Third` and will also have as `cfg`:
175`#[cfg(a, b, c)]`.
175`#[cfg(a)]`, `#[cfg(b)]` and `#[cfg(c)]`.
176176
177177[Intra-doc links](./linking-to-items-by-name.md) are resolved relative to where the doc comment is
178178defined.
src/tools/miri/src/shims/unix/foreign_items.rs+1-1
......@@ -342,7 +342,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
342342 }
343343 "flock" => {
344344 // Currently this function does not exist on all Unixes, e.g. on Solaris.
345 this.check_target_os(&[Os::Linux, Os::FreeBsd, Os::MacOs, Os::Illumos], link_name)?;
345 this.check_target_os(&[Os::Linux, Os::Android, Os::FreeBsd, Os::MacOs, Os::Illumos], link_name)?;
346346
347347 let [fd, op] = this.check_shim_sig(
348348 shim_sig!(extern "C" fn(i32, i32) -> i32),
src/tools/miri/src/shims/unwind.rs+2-2
......@@ -68,7 +68,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
6868 let this = self.eval_context_mut();
6969
7070 // Signature:
71 // fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32
71 // fn catch_unwind(try_fn: unsafe fn(*mut Data), data: *mut Data, catch_fn: unsafe fn(*mut Data, *mut u8)) -> bool
7272 // Calls `try_fn` with `data` as argument. If that executes normally, returns 0.
7373 // If that unwinds, calls `catch_fn` with the first argument being `data` and
7474 // then second argument being a target-dependent `payload` (i.e. it is up to us to define
......@@ -129,7 +129,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
129129 );
130130
131131 // We set the return value of `catch_unwind` to 1, since there was a panic.
132 this.write_scalar(Scalar::from_i32(1), &catch_unwind.dest)?;
132 this.write_scalar(Scalar::from_bool(true), &catch_unwind.dest)?;
133133
134134 // The Thread's `panic_payload` holds what was passed to `miri_start_unwind`.
135135 // This is exactly the second argument we need to pass to `catch_fn`.
src/tools/miri/tests/fail/function_calls/check_callback_abi.rs+1-1
......@@ -11,7 +11,7 @@ fn main() {
1111 std::intrinsics::catch_unwind(
1212 //~^ ERROR: calling a function with calling convention "C" using calling convention "Rust"
1313 std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
14 std::ptr::null_mut(),
14 std::ptr::null_mut::<u8>(),
1515 |_, _| unreachable!(),
1616 );
1717 }
src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr+1-1
......@@ -4,7 +4,7 @@ error: Undefined Behavior: calling a function with calling convention "C" using
44LL | / std::intrinsics::catch_unwind(
55LL | |
66LL | | std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
7LL | | std::ptr::null_mut(),
7LL | | std::ptr::null_mut::<u8>(),
88LL | | |_, _| unreachable!(),
99LL | | );
1010 | |_________^ Undefined Behavior occurred here
src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs+1-2
......@@ -1,6 +1,5 @@
1//@ignore-target: windows # File handling is not implemented yet
1//@ignore-target: windows # no libc
22//@ignore-target: solaris # Does not have flock
3//@ignore-target: android # Does not (always?) have flock
43//@compile-flags: -Zmiri-disable-isolation
54
65use std::fs::File;
src/tools/miri/tests/pass/panic/unwind_dwarf.rs+3-3
......@@ -64,10 +64,10 @@ fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
6464
6565 let data_ptr = ptr::addr_of_mut!(data) as *mut u8;
6666 unsafe {
67 return if std::intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
68 Ok(data.r.take().unwrap())
69 } else {
67 return if std::intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) {
7068 Err(data.p.take().unwrap())
69 } else {
70 Ok(data.r.take().unwrap())
7171 };
7272 }
7373
src/tools/miri/tests/pass/shims/fs.rs+2-4
......@@ -40,7 +40,7 @@ fn main() {
4040 test_canonicalize();
4141 #[cfg(unix)]
4242 test_pread_pwrite();
43 #[cfg(not(any(target_os = "solaris", target_os = "android")))]
43 #[cfg(not(target_os = "solaris"))]
4444 test_flock();
4545 test_readv_writev();
4646 #[cfg(all(unix, not(any(target_os = "solaris", target_os = "android"))))]
......@@ -406,11 +406,9 @@ fn test_pread_pwrite() {
406406 assert_eq!(&buf1, b" m");
407407}
408408
409// The standard library does not support this operation on Android
410// (https://github.com/rust-lang/rust/issues/148325).
411409// Miri does not support the way this is implemented on Solaris
412410// (https://github.com/rust-lang/miri/issues/5038).
413#[cfg(not(any(target_os = "solaris", target_os = "android")))]
411#[cfg(not(target_os = "solaris"))]
414412fn test_flock() {
415413 let bytes = b"Hello, World!\n";
416414 let path = utils::prepare_with_content("miri_test_fs_flock.txt", bytes);
tests/assembly-llvm/wasm_exceptions.rs+1-1
......@@ -48,7 +48,7 @@ pub fn test_rtry() {
4848 |_| {
4949 may_panic();
5050 },
51 core::ptr::null_mut(),
51 core::ptr::null_mut::<u8>(),
5252 |data, exception| {
5353 log_number(data as usize);
5454 log_number(exception as usize);
tests/assembly-llvm/wasm_legacy_eh.rs+1-1
......@@ -58,7 +58,7 @@ pub fn test_rtry() {
5858 |_| {
5959 may_panic();
6060 },
61 core::ptr::null_mut(),
61 core::ptr::null_mut::<u8>(),
6262 |data, exception| {
6363 log_number(data as usize);
6464 log_number(exception as usize);
tests/codegen-llvm/emscripten-catch-unwind-js-eh.rs+8-8
......@@ -30,11 +30,11 @@ const fn size_of<T>() -> usize {
3030}
3131
3232#[rustc_intrinsic]
33unsafe fn catch_unwind(
34 try_fn: fn(_: *mut u8),
35 data: *mut u8,
36 catch_fn: fn(_: *mut u8, _: *mut u8),
37) -> i32;
33unsafe fn catch_unwind<Data>(
34 try_fn: unsafe fn(_: *mut Data),
35 data: *mut Data,
36 catch_fn: unsafe fn(_: *mut Data, _: *mut u8),
37) -> bool;
3838
3939// CHECK-LABEL: @ptr_size
4040#[no_mangle]
......@@ -46,10 +46,10 @@ pub fn ptr_size() -> usize {
4646// CHECK-LABEL: @test_catch_unwind
4747#[no_mangle]
4848pub unsafe fn test_catch_unwind(
49 try_fn: fn(_: *mut u8),
49 try_fn: unsafe fn(_: *mut u8),
5050 data: *mut u8,
51 catch_fn: fn(_: *mut u8, _: *mut u8),
52) -> i32 {
51 catch_fn: unsafe fn(_: *mut u8, _: *mut u8),
52) -> bool {
5353 // CHECK: start:
5454 // CHECK: [[ALLOCA:%.*]] = alloca
5555
tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs+10-10
......@@ -28,11 +28,11 @@ const fn size_of<T>() -> usize {
2828 loop {}
2929}
3030#[rustc_intrinsic]
31unsafe fn catch_unwind(
32 try_fn: fn(_: *mut u8),
33 data: *mut u8,
34 catch_fn: fn(_: *mut u8, _: *mut u8),
35) -> i32;
31unsafe fn catch_unwind<Data>(
32 try_fn: unsafe fn(_: *mut Data),
33 data: *mut Data,
34 catch_fn: unsafe fn(_: *mut Data, _: *mut u8),
35) -> bool;
3636
3737// CHECK-LABEL: @ptr_size
3838#[no_mangle]
......@@ -44,10 +44,10 @@ pub fn ptr_size() -> usize {
4444// CHECK-LABEL: @test_catch_unwind
4545#[no_mangle]
4646pub unsafe fn test_catch_unwind(
47 try_fn: fn(_: *mut u8),
47 try_fn: unsafe fn(_: *mut u8),
4848 data: *mut u8,
49 catch_fn: fn(_: *mut u8, _: *mut u8),
50) -> i32 {
49 catch_fn: unsafe fn(_: *mut u8, _: *mut u8),
50) -> bool {
5151 // CHECK: start:
5252 // CHECK: invoke void %try_fn(ptr %data)
5353 // CHECK: to label %__rust_try.exit unwind label %catchswitch.i
......@@ -62,8 +62,8 @@ pub unsafe fn test_catch_unwind(
6262 // CHECK: catchret from %catchpad2.i to label %__rust_try.exit
6363
6464 // CHECK: __rust_try.exit: ; preds = %start, %catchpad.i
65 // CHECK: %common.ret.op.i = phi i32 [ 0, %start ], [ 1, %catchpad.i ]
66 // CHECK: ret i32 %common.ret.op.i
65 // CHECK: %common.ret.op.i = phi i1 [ false, %start ], [ true, %catchpad.i ]
66 // CHECK: ret i1 %common.ret.op.i
6767
6868 catch_unwind(try_fn, data, catch_fn)
6969}
tests/codegen-llvm/force-frame-pointers.rs+3
......@@ -16,3 +16,6 @@
1616// Always: attributes #{{.*}} "frame-pointer"="all"
1717// NonLeaf: attributes #{{.*}} "frame-pointer"="non-leaf"
1818pub fn foo() {}
19
20// Always: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 2}
21// NonLeaf: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 1}
tests/codegen-llvm/wasm_exceptions.rs+1-1
......@@ -49,7 +49,7 @@ pub fn test_rtry() {
4949 |_| {
5050 may_panic();
5151 },
52 core::ptr::null_mut(),
52 core::ptr::null_mut::<u8>(),
5353 |data, exception| {
5454 log_number(data as usize);
5555 log_number(exception as usize);
triagebot.toml-4
......@@ -1127,10 +1127,6 @@ cc = [
11271127message = "Some changes occurred in GUI tests."
11281128cc = ["@GuillaumeGomez"]
11291129
1130[mentions."tests/auxiliary/minicore.rs"]
1131message = "This PR modifies `tests/auxiliary/minicore.rs`."
1132cc = ["@jieyouxu"]
1133
11341130[mentions."src/rustdoc-json-types"]
11351131message = """
11361132rustdoc-json-types is a **public** (although nightly-only) API. \