| author | bors <bors@rust-lang.org> 2026-05-29 09:59:05 UTC |
| committer | bors <bors@rust-lang.org> 2026-05-29 09:59:05 UTC |
| log | b5d1746e7d25465729706ac5a0004b035e219d01 |
| tree | 1ff23f2e1d9fa6f5dea88612781b51eca738b533 |
| parent | dc375db7d8df0aa450e622c529147c95eee756f5 |
| parent | 6b29e581c45d3620d0d8125b2a627fd176fd1307 |
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 |
| 57 | 57 | ----- |
| 58 | 58 | - [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"`). |
| 59 | 59 | - [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) | |
| 61 | 61 | |
| 62 | 62 | <a id="1.96.0-Compatibility-Notes"></a> |
| 63 | 63 |
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs+6-6| ... | ... | @@ -1365,8 +1365,8 @@ fn codegen_regular_intrinsic_call<'tcx>( |
| 1365 | 1365 | { |
| 1366 | 1366 | fx.bcx.ins().call_indirect(f_sig, f, &[data]); |
| 1367 | 1367 | |
| 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); | |
| 1370 | 1370 | ret.write_cvalue(fx, ret_val); |
| 1371 | 1371 | |
| 1372 | 1372 | fx.bcx.ins().jump(ret_block, &[]); |
| ... | ... | @@ -1399,8 +1399,8 @@ fn codegen_regular_intrinsic_call<'tcx>( |
| 1399 | 1399 | |
| 1400 | 1400 | fx.bcx.seal_block(fallthrough_block); |
| 1401 | 1401 | 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); | |
| 1404 | 1404 | ret.write_cvalue(fx, ret_val); |
| 1405 | 1405 | fx.bcx.ins().jump(ret_block, &[]); |
| 1406 | 1406 | |
| ... | ... | @@ -1409,8 +1409,8 @@ fn codegen_regular_intrinsic_call<'tcx>( |
| 1409 | 1409 | fx.bcx.set_cold_block(catch_block); |
| 1410 | 1410 | let exception = fx.bcx.append_block_param(catch_block, pointer_ty(fx.tcx)); |
| 1411 | 1411 | 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); | |
| 1414 | 1414 | ret.write_cvalue(fx, ret_val); |
| 1415 | 1415 | fx.bcx.ins().jump(ret_block, &[]); |
| 1416 | 1416 | } |
compiler/rustc_codegen_gcc/src/intrinsic/mod.rs+7-7| ... | ... | @@ -1364,7 +1364,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( |
| 1364 | 1364 | bx.call(fn_type, None, None, try_func, &[data], None, None); |
| 1365 | 1365 | // Return 0 unconditionally from the intrinsic call; |
| 1366 | 1366 | // we can never unwind. |
| 1367 | OperandValue::Immediate(bx.const_i32(0)).store(bx, dest); | |
| 1367 | OperandValue::Immediate(bx.const_bool(false)).store(bx, dest); | |
| 1368 | 1368 | } else { |
| 1369 | 1369 | if wants_msvc_seh(bx.sess()) { |
| 1370 | 1370 | unimplemented!(); |
| ... | ... | @@ -1421,7 +1421,7 @@ fn codegen_gnu_try<'gcc, 'tcx>( |
| 1421 | 1421 | let current_block = bx.block; |
| 1422 | 1422 | |
| 1423 | 1423 | bx.switch_to_block(then); |
| 1424 | bx.ret(bx.const_i32(0)); | |
| 1424 | bx.ret(bx.const_bool(false)); | |
| 1425 | 1425 | |
| 1426 | 1426 | // Type indicator for the exception being thrown. |
| 1427 | 1427 | // |
| ... | ... | @@ -1435,7 +1435,7 @@ fn codegen_gnu_try<'gcc, 'tcx>( |
| 1435 | 1435 | let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]); |
| 1436 | 1436 | let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); |
| 1437 | 1437 | 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)); | |
| 1439 | 1439 | |
| 1440 | 1440 | // NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not |
| 1441 | 1441 | // generate a try/catch. |
| ... | ... | @@ -1468,7 +1468,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( |
| 1468 | 1468 | // Define the type up front for the signature of the rust_try function. |
| 1469 | 1469 | let tcx = cx.tcx; |
| 1470 | 1470 | let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8); |
| 1471 | // `unsafe fn(*mut i8) -> ()` | |
| 1471 | // `unsafe fn(*mut Data) -> ()` | |
| 1472 | 1472 | let try_fn_ty = Ty::new_fn_ptr( |
| 1473 | 1473 | tcx, |
| 1474 | 1474 | ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( |
| ... | ... | @@ -1477,7 +1477,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( |
| 1477 | 1477 | rustc_hir::Safety::Unsafe, |
| 1478 | 1478 | )), |
| 1479 | 1479 | ); |
| 1480 | // `unsafe fn(*mut i8, *mut i8) -> ()` | |
| 1480 | // `unsafe fn(*mut Data, *mut i8) -> ()` | |
| 1481 | 1481 | let catch_fn_ty = Ty::new_fn_ptr( |
| 1482 | 1482 | tcx, |
| 1483 | 1483 | ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( |
| ... | ... | @@ -1486,10 +1486,10 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( |
| 1486 | 1486 | rustc_hir::Safety::Unsafe, |
| 1487 | 1487 | )), |
| 1488 | 1488 | ); |
| 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` | |
| 1490 | 1490 | let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi( |
| 1491 | 1491 | [try_fn_ty, i8p, catch_fn_ty], |
| 1492 | tcx.types.i32, | |
| 1492 | tcx.types.bool, | |
| 1493 | 1493 | rustc_hir::Safety::Unsafe, |
| 1494 | 1494 | )); |
| 1495 | 1495 | 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> { |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | 341 | impl ExtraBackendMethods for GccCodegenBackend { |
| 342 | fn supports_parallel(&self) -> bool { | |
| 343 | false | |
| 344 | } | |
| 342 | type Module = GccContext; | |
| 345 | 343 | |
| 346 | 344 | fn codegen_allocator( |
| 347 | 345 | &self, |
| ... | ... | @@ -424,6 +422,10 @@ impl WriteBackendMethods for GccCodegenBackend { |
| 424 | 422 | type ModuleBuffer = ModuleBuffer; |
| 425 | 423 | type ThinData = (); |
| 426 | 424 | |
| 425 | fn supports_parallel(&self) -> bool { | |
| 426 | false | |
| 427 | } | |
| 428 | ||
| 427 | 429 | fn target_machine_factory( |
| 428 | 430 | &self, |
| 429 | 431 | _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>) |
| 171 | 171 | llvm::CreateUWTableAttr(llcx, async_unwind) |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | pub(crate) fn frame_pointer_type_attr<'ll>( | |
| 175 | cx: &SimpleCx<'ll>, | |
| 176 | sess: &Session, | |
| 177 | ) -> Option<&'ll Attribute> { | |
| 174 | pub(crate) fn frame_pointer(sess: &Session) -> FramePointer { | |
| 178 | 175 | let mut fp = sess.target.frame_pointer; |
| 179 | 176 | let opts = &sess.opts; |
| 180 | 177 | // "mcount" function relies on stack pointer. |
| ... | ... | @@ -183,6 +180,14 @@ pub(crate) fn frame_pointer_type_attr<'ll>( |
| 183 | 180 | fp.ratchet(FramePointer::Always); |
| 184 | 181 | } |
| 185 | 182 | fp.ratchet(opts.cg.force_frame_pointers); |
| 183 | fp | |
| 184 | } | |
| 185 | ||
| 186 | pub(crate) fn frame_pointer_type_attr<'ll>( | |
| 187 | cx: &SimpleCx<'ll>, | |
| 188 | sess: &Session, | |
| 189 | ) -> Option<&'ll Attribute> { | |
| 190 | let fp = frame_pointer(sess); | |
| 186 | 191 | let attr_value = match fp { |
| 187 | 192 | FramePointer::Always => "all", |
| 188 | 193 | FramePointer::NonLeaf => "non-leaf", |
compiler/rustc_codegen_llvm/src/context.rs+17-6| ... | ... | @@ -28,7 +28,8 @@ use rustc_session::config::{ |
| 28 | 28 | use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, sym}; |
| 29 | 29 | use rustc_symbol_mangling::mangle_internal_symbol; |
| 30 | 30 | use 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, | |
| 32 | 33 | }; |
| 33 | 34 | use smallvec::SmallVec; |
| 34 | 35 | |
| ... | ... | @@ -489,6 +490,20 @@ pub(crate) unsafe fn create_module<'ll>( |
| 489 | 490 | } |
| 490 | 491 | } |
| 491 | 492 | |
| 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 | ||
| 492 | 507 | if sess.opts.unstable_opts.indirect_branch_cs_prefix { |
| 493 | 508 | llvm::add_module_flag_u32( |
| 494 | 509 | llmod, |
| ... | ... | @@ -960,11 +975,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { |
| 960 | 975 | fn intrinsic_call_expects_place_always(&self, name: Symbol) -> bool { |
| 961 | 976 | matches!( |
| 962 | 977 | 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 | |
| 968 | 979 | ) |
| 969 | 980 | } |
| 970 | 981 | } |
compiler/rustc_codegen_llvm/src/intrinsic.rs+33-44| ... | ... | @@ -288,18 +288,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { |
| 288 | 288 | } |
| 289 | 289 | } |
| 290 | 290 | sym::catch_unwind => { |
| 291 | let result = PlaceRef { | |
| 292 | val: result_place.unwrap(), | |
| 293 | layout: result_layout, | |
| 294 | }; | |
| 295 | 291 | catch_unwind_intrinsic( |
| 296 | 292 | self, |
| 297 | 293 | args[0].immediate(), |
| 298 | 294 | args[1].immediate(), |
| 299 | 295 | args[2].immediate(), |
| 300 | result, | |
| 301 | ); | |
| 302 | return IntrinsicResult::WroteIntoPlace; | |
| 296 | ) | |
| 303 | 297 | } |
| 304 | 298 | sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]), |
| 305 | 299 | sym::va_arg => { |
| ... | ... | @@ -1351,22 +1345,21 @@ fn catch_unwind_intrinsic<'ll, 'tcx>( |
| 1351 | 1345 | try_func: &'ll Value, |
| 1352 | 1346 | data: &'ll Value, |
| 1353 | 1347 | catch_func: &'ll Value, |
| 1354 | dest: PlaceRef<'tcx, &'ll Value>, | |
| 1355 | ) { | |
| 1348 | ) -> &'ll Value { | |
| 1356 | 1349 | if !bx.sess().panic_strategy().unwinds() { |
| 1357 | 1350 | let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void()); |
| 1358 | 1351 | bx.call(try_func_ty, None, None, try_func, &[data], None, None); |
| 1359 | 1352 | // Return 0 unconditionally from the intrinsic call; |
| 1360 | 1353 | // we can never unwind. |
| 1361 | OperandValue::Immediate(bx.const_i32(0)).store(bx, dest); | |
| 1354 | bx.const_bool(false) | |
| 1362 | 1355 | } 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) | |
| 1364 | 1357 | } 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) | |
| 1366 | 1359 | } 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) | |
| 1368 | 1361 | } else { |
| 1369 | codegen_gnu_try(bx, try_func, data, catch_func, dest); | |
| 1362 | codegen_gnu_try(bx, try_func, data, catch_func) | |
| 1370 | 1363 | } |
| 1371 | 1364 | } |
| 1372 | 1365 | |
| ... | ... | @@ -1382,8 +1375,7 @@ fn codegen_msvc_try<'ll, 'tcx>( |
| 1382 | 1375 | try_func: &'ll Value, |
| 1383 | 1376 | data: &'ll Value, |
| 1384 | 1377 | catch_func: &'ll Value, |
| 1385 | dest: PlaceRef<'tcx, &'ll Value>, | |
| 1386 | ) { | |
| 1378 | ) -> &'ll Value { | |
| 1387 | 1379 | let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { |
| 1388 | 1380 | bx.set_personality_fn(bx.eh_personality()); |
| 1389 | 1381 | |
| ... | ... | @@ -1399,12 +1391,12 @@ fn codegen_msvc_try<'ll, 'tcx>( |
| 1399 | 1391 | |
| 1400 | 1392 | // We're generating an IR snippet that looks like: |
| 1401 | 1393 | // |
| 1402 | // declare i32 @rust_try(%try_func, %data, %catch_func) { | |
| 1394 | // declare bool @rust_try(%try_func, %data, %catch_func) { | |
| 1403 | 1395 | // %slot = alloca i8* |
| 1404 | 1396 | // invoke %try_func(%data) to label %normal unwind label %catchswitch |
| 1405 | 1397 | // |
| 1406 | 1398 | // normal: |
| 1407 | // ret i32 0 | |
| 1399 | // ret i1 false | |
| 1408 | 1400 | // |
| 1409 | 1401 | // catchswitch: |
| 1410 | 1402 | // %cs = catchswitch within none [%catchpad_rust, %catchpad_foreign] unwind to caller |
| ... | ... | @@ -1421,7 +1413,7 @@ fn codegen_msvc_try<'ll, 'tcx>( |
| 1421 | 1413 | // catchret from %tok to label %caught |
| 1422 | 1414 | // |
| 1423 | 1415 | // caught: |
| 1424 | // ret i32 1 | |
| 1416 | // ret i1 true | |
| 1425 | 1417 | // } |
| 1426 | 1418 | // |
| 1427 | 1419 | // This structure follows the basic usage of throw/try/catch in LLVM. |
| ... | ... | @@ -1459,7 +1451,7 @@ fn codegen_msvc_try<'ll, 'tcx>( |
| 1459 | 1451 | bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None); |
| 1460 | 1452 | |
| 1461 | 1453 | bx.switch_to_block(normal); |
| 1462 | bx.ret(bx.const_i32(0)); | |
| 1454 | bx.ret(bx.const_bool(false)); | |
| 1463 | 1455 | |
| 1464 | 1456 | bx.switch_to_block(catchswitch); |
| 1465 | 1457 | let cs = bx.catch_switch(None, None, &[catchpad_rust, catchpad_foreign]); |
| ... | ... | @@ -1516,13 +1508,13 @@ fn codegen_msvc_try<'ll, 'tcx>( |
| 1516 | 1508 | bx.catch_ret(&funclet, caught); |
| 1517 | 1509 | |
| 1518 | 1510 | bx.switch_to_block(caught); |
| 1519 | bx.ret(bx.const_i32(1)); | |
| 1511 | bx.ret(bx.const_bool(true)); | |
| 1520 | 1512 | }); |
| 1521 | 1513 | |
| 1522 | 1514 | // Note that no invoke is used here because by definition this function |
| 1523 | 1515 | // can't panic (that's what it's catching). |
| 1524 | 1516 | let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); |
| 1525 | OperandValue::Immediate(ret).store(bx, dest); | |
| 1517 | ret | |
| 1526 | 1518 | } |
| 1527 | 1519 | |
| 1528 | 1520 | // WASM's definition of the `rust_try` function. |
| ... | ... | @@ -1531,8 +1523,7 @@ fn codegen_wasm_try<'ll, 'tcx>( |
| 1531 | 1523 | try_func: &'ll Value, |
| 1532 | 1524 | data: &'ll Value, |
| 1533 | 1525 | catch_func: &'ll Value, |
| 1534 | dest: PlaceRef<'tcx, &'ll Value>, | |
| 1535 | ) { | |
| 1526 | ) -> &'ll Value { | |
| 1536 | 1527 | let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { |
| 1537 | 1528 | bx.set_personality_fn(bx.eh_personality()); |
| 1538 | 1529 | |
| ... | ... | @@ -1547,12 +1538,12 @@ fn codegen_wasm_try<'ll, 'tcx>( |
| 1547 | 1538 | |
| 1548 | 1539 | // We're generating an IR snippet that looks like: |
| 1549 | 1540 | // |
| 1550 | // declare i32 @rust_try(%try_func, %data, %catch_func) { | |
| 1541 | // declare i1 @rust_try(%try_func, %data, %catch_func) { | |
| 1551 | 1542 | // %slot = alloca i8* |
| 1552 | 1543 | // invoke %try_func(%data) to label %normal unwind label %catchswitch |
| 1553 | 1544 | // |
| 1554 | 1545 | // normal: |
| 1555 | // ret i32 0 | |
| 1546 | // ret i1 false | |
| 1556 | 1547 | // |
| 1557 | 1548 | // catchswitch: |
| 1558 | 1549 | // %cs = catchswitch within none [%catchpad] unwind to caller |
| ... | ... | @@ -1565,14 +1556,14 @@ fn codegen_wasm_try<'ll, 'tcx>( |
| 1565 | 1556 | // catchret from %tok to label %caught |
| 1566 | 1557 | // |
| 1567 | 1558 | // caught: |
| 1568 | // ret i32 1 | |
| 1559 | // ret i1 true | |
| 1569 | 1560 | // } |
| 1570 | 1561 | // |
| 1571 | 1562 | let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void()); |
| 1572 | 1563 | bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None); |
| 1573 | 1564 | |
| 1574 | 1565 | bx.switch_to_block(normal); |
| 1575 | bx.ret(bx.const_i32(0)); | |
| 1566 | bx.ret(bx.const_bool(false)); | |
| 1576 | 1567 | |
| 1577 | 1568 | bx.switch_to_block(catchswitch); |
| 1578 | 1569 | let cs = bx.catch_switch(None, None, &[catchpad]); |
| ... | ... | @@ -1589,13 +1580,13 @@ fn codegen_wasm_try<'ll, 'tcx>( |
| 1589 | 1580 | bx.catch_ret(&funclet, caught); |
| 1590 | 1581 | |
| 1591 | 1582 | bx.switch_to_block(caught); |
| 1592 | bx.ret(bx.const_i32(1)); | |
| 1583 | bx.ret(bx.const_bool(true)); | |
| 1593 | 1584 | }); |
| 1594 | 1585 | |
| 1595 | 1586 | // Note that no invoke is used here because by definition this function |
| 1596 | 1587 | // can't panic (that's what it's catching). |
| 1597 | 1588 | let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); |
| 1598 | OperandValue::Immediate(ret).store(bx, dest); | |
| 1589 | ret | |
| 1599 | 1590 | } |
| 1600 | 1591 | |
| 1601 | 1592 | // Definition of the standard `try` function for Rust using the GNU-like model |
| ... | ... | @@ -1614,8 +1605,7 @@ fn codegen_gnu_try<'ll, 'tcx>( |
| 1614 | 1605 | try_func: &'ll Value, |
| 1615 | 1606 | data: &'ll Value, |
| 1616 | 1607 | catch_func: &'ll Value, |
| 1617 | dest: PlaceRef<'tcx, &'ll Value>, | |
| 1618 | ) { | |
| 1608 | ) -> &'ll Value { | |
| 1619 | 1609 | let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { |
| 1620 | 1610 | // Codegens the shims described above: |
| 1621 | 1611 | // |
| ... | ... | @@ -1639,7 +1629,7 @@ fn codegen_gnu_try<'ll, 'tcx>( |
| 1639 | 1629 | bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None); |
| 1640 | 1630 | |
| 1641 | 1631 | bx.switch_to_block(then); |
| 1642 | bx.ret(bx.const_i32(0)); | |
| 1632 | bx.ret(bx.const_bool(false)); | |
| 1643 | 1633 | |
| 1644 | 1634 | // Type indicator for the exception being thrown. |
| 1645 | 1635 | // |
| ... | ... | @@ -1655,13 +1645,13 @@ fn codegen_gnu_try<'ll, 'tcx>( |
| 1655 | 1645 | let ptr = bx.extract_value(vals, 0); |
| 1656 | 1646 | let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void()); |
| 1657 | 1647 | 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)); | |
| 1659 | 1649 | }); |
| 1660 | 1650 | |
| 1661 | 1651 | // Note that no invoke is used here because by definition this function |
| 1662 | 1652 | // can't panic (that's what it's catching). |
| 1663 | 1653 | let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); |
| 1664 | OperandValue::Immediate(ret).store(bx, dest); | |
| 1654 | ret | |
| 1665 | 1655 | } |
| 1666 | 1656 | |
| 1667 | 1657 | // Variant of codegen_gnu_try used for emscripten where Rust panics are |
| ... | ... | @@ -1672,8 +1662,7 @@ fn codegen_emcc_try<'ll, 'tcx>( |
| 1672 | 1662 | try_func: &'ll Value, |
| 1673 | 1663 | data: &'ll Value, |
| 1674 | 1664 | catch_func: &'ll Value, |
| 1675 | dest: PlaceRef<'tcx, &'ll Value>, | |
| 1676 | ) { | |
| 1665 | ) -> &'ll Value { | |
| 1677 | 1666 | let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| { |
| 1678 | 1667 | // Codegens the shims described above: |
| 1679 | 1668 | // |
| ... | ... | @@ -1702,7 +1691,7 @@ fn codegen_emcc_try<'ll, 'tcx>( |
| 1702 | 1691 | bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None); |
| 1703 | 1692 | |
| 1704 | 1693 | bx.switch_to_block(then); |
| 1705 | bx.ret(bx.const_i32(0)); | |
| 1694 | bx.ret(bx.const_bool(false)); | |
| 1706 | 1695 | |
| 1707 | 1696 | // Type indicator for the exception being thrown. |
| 1708 | 1697 | // |
| ... | ... | @@ -1737,13 +1726,13 @@ fn codegen_emcc_try<'ll, 'tcx>( |
| 1737 | 1726 | |
| 1738 | 1727 | let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void()); |
| 1739 | 1728 | 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)); | |
| 1741 | 1730 | }); |
| 1742 | 1731 | |
| 1743 | 1732 | // Note that no invoke is used here because by definition this function |
| 1744 | 1733 | // can't panic (that's what it's catching). |
| 1745 | 1734 | let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None); |
| 1746 | OperandValue::Immediate(ret).store(bx, dest); | |
| 1735 | ret | |
| 1747 | 1736 | } |
| 1748 | 1737 | |
| 1749 | 1738 | // 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>( |
| 1782 | 1771 | // Define the type up front for the signature of the rust_try function. |
| 1783 | 1772 | let tcx = cx.tcx; |
| 1784 | 1773 | let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8); |
| 1785 | // `unsafe fn(*mut i8) -> ()` | |
| 1774 | // `unsafe fn(*mut Data) -> ()` | |
| 1786 | 1775 | let try_fn_ty = Ty::new_fn_ptr( |
| 1787 | 1776 | tcx, |
| 1788 | 1777 | ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p], tcx.types.unit, hir::Safety::Unsafe)), |
| 1789 | 1778 | ); |
| 1790 | // `unsafe fn(*mut i8, *mut i8) -> ()` | |
| 1779 | // `unsafe fn(*mut Data, *mut i8) -> ()` | |
| 1791 | 1780 | let catch_fn_ty = Ty::new_fn_ptr( |
| 1792 | 1781 | tcx, |
| 1793 | 1782 | ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p, i8p], tcx.types.unit, hir::Safety::Unsafe)), |
| 1794 | 1783 | ); |
| 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` | |
| 1796 | 1785 | let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi( |
| 1797 | 1786 | [try_fn_ty, i8p, catch_fn_ty], |
| 1798 | tcx.types.i32, | |
| 1787 | tcx.types.bool, | |
| 1799 | 1788 | hir::Safety::Unsafe, |
| 1800 | 1789 | )); |
| 1801 | 1790 | 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 { |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | impl ExtraBackendMethods for LlvmCodegenBackend { |
| 96 | type Module = ModuleLlvm; | |
| 97 | ||
| 96 | 98 | fn codegen_allocator<'tcx>( |
| 97 | 99 | &self, |
| 98 | 100 | tcx: TyCtxt<'tcx>, |
| ... | ... | @@ -121,6 +123,7 @@ impl WriteBackendMethods for LlvmCodegenBackend { |
| 121 | 123 | type ModuleBuffer = back::lto::ModuleBuffer; |
| 122 | 124 | type TargetMachine = OwnedTargetMachine; |
| 123 | 125 | type ThinData = back::lto::ThinData; |
| 126 | ||
| 124 | 127 | fn thread_profiler() -> Box<dyn Any> { |
| 125 | 128 | Box::new(TimeTraceProfiler::new()) |
| 126 | 129 | } |
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+12| ... | ... | @@ -251,6 +251,18 @@ pub(crate) enum UWTableKind { |
| 251 | 251 | Async = 2, |
| 252 | 252 | } |
| 253 | 253 | |
| 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")] | |
| 258 | pub(crate) enum FramePointerKind { | |
| 259 | None = 0, | |
| 260 | NonLeaf = 1, | |
| 261 | All = 2, | |
| 262 | Reserved = 3, | |
| 263 | NonLeafNoReserve = 4, | |
| 264 | } | |
| 265 | ||
| 254 | 266 | /// Must match the layout of `LLVMRustAttributeKind`. |
| 255 | 267 | /// Semantically a subset of the C++ enum llvm::Attribute::AttrKind, |
| 256 | 268 | /// 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 { |
| 352 | 352 | pub incr_comp_session_dir: Option<PathBuf>, |
| 353 | 353 | /// `true` if the codegen should be run in parallel. |
| 354 | 354 | /// |
| 355 | /// Depends on [`ExtraBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`. | |
| 355 | /// Depends on [`WriteBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`. | |
| 356 | 356 | pub parallel: bool, |
| 357 | 357 | } |
| 358 | 358 | |
| ... | ... | @@ -416,7 +416,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { |
| 416 | 416 | } |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | pub(crate) fn start_async_codegen<B: ExtraBackendMethods>( | |
| 419 | pub(crate) fn start_async_codegen<B: WriteBackendMethods>( | |
| 420 | 420 | backend: B, |
| 421 | 421 | tcx: TyCtxt<'_>, |
| 422 | 422 | allocator_module: Option<ModuleCodegen<B::Module>>, |
| ... | ... | @@ -1115,18 +1115,6 @@ fn do_thin_lto<B: WriteBackendMethods>( |
| 1115 | 1115 | compiled_modules |
| 1116 | 1116 | } |
| 1117 | 1117 | |
| 1118 | fn 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 | ||
| 1130 | 1118 | /// Messages sent to the coordinator. |
| 1131 | 1119 | pub(crate) enum Message<B: WriteBackendMethods> { |
| 1132 | 1120 | /// A jobserver token has become available. Sent from the jobserver helper |
| ... | ... | @@ -1208,7 +1196,7 @@ enum MainThreadState { |
| 1208 | 1196 | Lending, |
| 1209 | 1197 | } |
| 1210 | 1198 | |
| 1211 | fn start_executing_work<B: ExtraBackendMethods>( | |
| 1199 | fn start_executing_work<B: WriteBackendMethods>( | |
| 1212 | 1200 | backend: B, |
| 1213 | 1201 | tcx: TyCtxt<'_>, |
| 1214 | 1202 | shared_emitter: SharedEmitter, |
| ... | ... | @@ -1891,7 +1879,8 @@ fn spawn_thin_lto_work<B: WriteBackendMethods>( |
| 1891 | 1879 | execute_copy_from_cache_work_item(&cgcx, &prof, shared_emitter, m) |
| 1892 | 1880 | } |
| 1893 | 1881 | 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) | |
| 1895 | 1884 | } |
| 1896 | 1885 | })); |
| 1897 | 1886 |
compiler/rustc_codegen_ssa/src/base.rs+7-1| ... | ... | @@ -688,7 +688,13 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec<Allo |
| 688 | 688 | methods |
| 689 | 689 | } |
| 690 | 690 | |
| 691 | pub fn codegen_crate<B: ExtraBackendMethods>(backend: B, tcx: TyCtxt<'_>) -> OngoingCodegen<B> { | |
| 691 | pub fn codegen_crate< | |
| 692 | B: ExtraBackendMethods<Module = M> + WriteBackendMethods<Module = M>, | |
| 693 | M: Send, | |
| 694 | >( | |
| 695 | backend: B, | |
| 696 | tcx: TyCtxt<'_>, | |
| 697 | ) -> OngoingCodegen<B> { | |
| 692 | 698 | if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() { |
| 693 | 699 | // The target has no default cpu, but none is set explicitly |
| 694 | 700 | 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}; |
| 14 | 14 | use rustc_span::Symbol; |
| 15 | 15 | |
| 16 | 16 | use super::CodegenObject; |
| 17 | use super::write::WriteBackendMethods; | |
| 18 | 17 | use crate::back::archive::ArArchiveBuilderBuilder; |
| 19 | 18 | use crate::back::link::link_binary; |
| 20 | 19 | use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; |
| ... | ... | @@ -162,9 +161,9 @@ pub trait CodegenBackend { |
| 162 | 161 | } |
| 163 | 162 | } |
| 164 | 163 | |
| 165 | pub trait ExtraBackendMethods: | |
| 166 | WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync | |
| 167 | { | |
| 164 | pub trait ExtraBackendMethods: Send + Sync + DynSend + DynSync { | |
| 165 | type Module; | |
| 166 | ||
| 168 | 167 | fn codegen_allocator<'tcx>( |
| 169 | 168 | &self, |
| 170 | 169 | tcx: TyCtxt<'tcx>, |
| ... | ... | @@ -179,11 +178,4 @@ pub trait ExtraBackendMethods: |
| 179 | 178 | tcx: TyCtxt<'_>, |
| 180 | 179 | cgu_name: Symbol, |
| 181 | 180 | ) -> (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 | } | |
| 189 | 181 | } |
compiler/rustc_codegen_ssa/src/traits/write.rs+13| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | use std::any::Any; |
| 2 | use std::convert::Infallible; | |
| 2 | 3 | use std::path::PathBuf; |
| 3 | 4 | |
| 4 | 5 | use rustc_data_structures::profiling::SelfProfilerRef; |
| ... | ... | @@ -18,6 +19,12 @@ pub trait WriteBackendMethods: Clone + 'static { |
| 18 | 19 | type ModuleBuffer: ModuleBufferMethods; |
| 19 | 20 | type ThinData: Send + Sync; |
| 20 | 21 | |
| 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 | } | |
| 21 | 28 | fn thread_profiler() -> Box<dyn Any> { |
| 22 | 29 | Box::new(()) |
| 23 | 30 | } |
| ... | ... | @@ -76,3 +83,9 @@ pub trait WriteBackendMethods: Clone + 'static { |
| 76 | 83 | pub trait ModuleBufferMethods: Send + Sync { |
| 77 | 84 | fn data(&self) -> &[u8]; |
| 78 | 85 | } |
| 86 | ||
| 87 | impl 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( |
| 637 | 637 | } |
| 638 | 638 | |
| 639 | 639 | sym::catch_unwind => { |
| 640 | let mut_data = Ty::new_mut_ptr(tcx, param(0)); | |
| 640 | 641 | let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8); |
| 641 | 642 | 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 | ); | |
| 645 | 647 | ( |
| 648 | 1, | |
| 646 | 649 | 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, | |
| 650 | 652 | ) |
| 651 | 653 | } |
| 652 | 654 |
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}; |
| 9 | 9 | use rustc_middle::span_bug; |
| 10 | 10 | use rustc_middle::ty::{self, TyCtxt}; |
| 11 | 11 | use rustc_session::lint; |
| 12 | use rustc_span::{Span, Symbol, kw}; | |
| 12 | use rustc_span::{Span, kw, sym}; | |
| 13 | 13 | use tracing::{debug, instrument}; |
| 14 | 14 | |
| 15 | 15 | use crate::middle::resolve_bound_vars as rbv; |
| ... | ... | @@ -328,22 +328,18 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { |
| 328 | 328 | { |
| 329 | 329 | // See `ClosureArgsParts`, `CoroutineArgsParts`, and `CoroutineClosureArgsParts` |
| 330 | 330 | // 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, | |
| 342 | 338 | }; |
| 343 | 339 | |
| 344 | own_params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef { | |
| 340 | own_params.extend((0..len).map(|_| ty::GenericParamDef { | |
| 345 | 341 | index: next_index(), |
| 346 | name: Symbol::intern(arg), | |
| 342 | name: sym::empty, // dummy; exact value doesn't matter | |
| 347 | 343 | def_id: def_id.to_def_id(), |
| 348 | 344 | pure_wrt_drop: false, |
| 349 | 345 | 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> { |
| 175 | 175 | NonScalar, |
| 176 | 176 | UnknownExprPtrKind, |
| 177 | 177 | UnknownCastPtrKind, |
| 178 | CastEnumDrop, | |
| 178 | 179 | /// Cast of int to (possibly) wide raw pointer. |
| 179 | 180 | /// |
| 180 | 181 | /// Argument is the specific name of the metadata in plain words, such as "a vtable" |
| ... | ... | @@ -635,6 +636,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 635 | 636 | }; |
| 636 | 637 | fcx.dcx().emit_err(errors::CastUnknownPointer { span, to: unknown_cast_to, sub }); |
| 637 | 638 | } |
| 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 | } | |
| 638 | 645 | CastError::ForeignNonExhaustiveAdt => { |
| 639 | 646 | make_invalid_casting_error( |
| 640 | 647 | self.span, |
| ... | ... | @@ -870,11 +877,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 870 | 877 | // fn-ptr-cast |
| 871 | 878 | (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt), |
| 872 | 879 | |
| 880 | // enum -> int | |
| 881 | (Int(CEnum), Int(_)) => self.check_enum_cast(fcx), | |
| 882 | ||
| 873 | 883 | // prim -> prim |
| 874 | (Int(CEnum), Int(_)) => { | |
| 875 | self.err_if_cenum_impl_drop(fcx); | |
| 876 | Ok(CastKind::EnumCast) | |
| 877 | } | |
| 878 | 884 | (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), |
| 879 | 885 | |
| 880 | 886 | (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), |
| ... | ... | @@ -1109,21 +1115,20 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 1109 | 1115 | } |
| 1110 | 1116 | } |
| 1111 | 1117 | |
| 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>> { | |
| 1120 | 1119 | if let ty::Adt(d, _) = self.expr_ty.kind() |
| 1121 | 1120 | && d.has_dtor(fcx.tcx) |
| 1122 | 1121 | { |
| 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 | } | |
| 1125 | 1127 | |
| 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), | |
| 1127 | 1132 | } |
| 1128 | 1133 | } |
| 1129 | 1134 |
compiler/rustc_middle/src/ty/context.rs+9| ... | ... | @@ -2361,6 +2361,15 @@ impl<'tcx> TyCtxt<'tcx> { |
| 2361 | 2361 | self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe)) |
| 2362 | 2362 | } |
| 2363 | 2363 | |
| 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 | ||
| 2364 | 2373 | pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output |
| 2365 | 2374 | where |
| 2366 | 2375 | I: Iterator<Item = T>, |
compiler/rustc_session/src/filesearch.rs+1-1| ... | ... | @@ -102,7 +102,7 @@ fn current_dll_path() -> Result<PathBuf, String> { |
| 102 | 102 | loop { |
| 103 | 103 | if libc::loadquery( |
| 104 | 104 | libc::L_GETINFO, |
| 105 | buffer.as_mut_ptr() as *mut u8, | |
| 105 | buffer.as_mut_ptr() as *mut libc::c_void, | |
| 106 | 106 | (size_of::<libc::ld_info>() * buffer.len()) as u32, |
| 107 | 107 | ) >= 0 |
| 108 | 108 | { |
compiler/rustc_span/src/lib.rs+38| ... | ... | @@ -34,6 +34,7 @@ use derive_where::derive_where; |
| 34 | 34 | use rustc_data_structures::stable_hash::StableHashCtxt; |
| 35 | 35 | use rustc_data_structures::{AtomicRef, outline}; |
| 36 | 36 | use rustc_macros::{Decodable, Encodable, StableHash}; |
| 37 | use rustc_serialize::opaque::mem_encoder::MemEncoder; | |
| 37 | 38 | use rustc_serialize::opaque::{FileEncoder, MemDecoder}; |
| 38 | 39 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; |
| 39 | 40 | use tracing::debug; |
| ... | ... | @@ -1398,6 +1399,43 @@ impl SpanEncoder for FileEncoder { |
| 1398 | 1399 | } |
| 1399 | 1400 | } |
| 1400 | 1401 | |
| 1402 | impl 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 | ||
| 1401 | 1439 | impl<E: SpanEncoder> Encodable<E> for Span { |
| 1402 | 1440 | fn encode(&self, s: &mut E) { |
| 1403 | 1441 | 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 |
| 2232 | 2232 | |
| 2233 | 2233 | /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the |
| 2234 | 2234 | /// 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. | |
| 2236 | 2236 | /// |
| 2237 | 2237 | /// `catch_fn` must not unwind. |
| 2238 | 2238 | /// |
| ... | ... | @@ -2249,11 +2249,11 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina |
| 2249 | 2249 | /// version of this intrinsic, `std::panic::catch_unwind`. |
| 2250 | 2250 | #[rustc_intrinsic] |
| 2251 | 2251 | #[rustc_nounwind] |
| 2252 | pub unsafe fn catch_unwind( | |
| 2253 | _try_fn: fn(*mut u8), | |
| 2254 | _data: *mut u8, | |
| 2255 | _catch_fn: fn(*mut u8, *mut u8), | |
| 2256 | ) -> i32; | |
| 2252 | pub 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; | |
| 2257 | 2257 | |
| 2258 | 2258 | /// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held |
| 2259 | 2259 | /// 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) { |
| 2054 | 2054 | /// [allocation]: crate::ptr#allocated-object |
| 2055 | 2055 | /// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses |
| 2056 | 2056 | /// |
| 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 | /// | |
| 2057 | 2072 | /// # Safety |
| 2058 | 2073 | /// |
| 2059 | 2074 | /// 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 { |
| 2147 | 2162 | /// [allocation]: crate::ptr#allocated-object |
| 2148 | 2163 | /// [atomic]: crate::sync::atomic#memory-model-for-atomic-accesses |
| 2149 | 2164 | /// |
| 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 | /// | |
| 2150 | 2180 | /// # Safety |
| 2151 | 2181 | /// |
| 2152 | 2182 | /// 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] { |
| 4350 | 4350 | /// |
| 4351 | 4351 | /// assert_eq!(&bytes, b"Hello, Wello!"); |
| 4352 | 4352 | /// ``` |
| 4353 | #[inline] | |
| 4353 | 4354 | #[stable(feature = "copy_within", since = "1.37.0")] |
| 4354 | 4355 | #[track_caller] |
| 4355 | 4356 | 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() { |
| 187 | 187 | target_os = "netbsd", |
| 188 | 188 | target_os = "openbsd", |
| 189 | 189 | target_os = "solaris", |
| 190 | target_os = "android", | |
| 190 | 191 | target_vendor = "apple", |
| 191 | 192 | )), |
| 192 | 193 | should_panic |
| ... | ... | @@ -220,6 +221,7 @@ fn file_lock_multiple_shared() { |
| 220 | 221 | target_os = "netbsd", |
| 221 | 222 | target_os = "openbsd", |
| 222 | 223 | target_os = "solaris", |
| 224 | target_os = "android", | |
| 223 | 225 | target_vendor = "apple", |
| 224 | 226 | )), |
| 225 | 227 | should_panic |
| ... | ... | @@ -254,6 +256,7 @@ fn file_lock_blocking() { |
| 254 | 256 | target_os = "netbsd", |
| 255 | 257 | target_os = "openbsd", |
| 256 | 258 | target_os = "solaris", |
| 259 | target_os = "android", | |
| 257 | 260 | target_vendor = "apple", |
| 258 | 261 | )), |
| 259 | 262 | should_panic |
| ... | ... | @@ -285,6 +288,7 @@ fn file_lock_drop() { |
| 285 | 288 | target_os = "netbsd", |
| 286 | 289 | target_os = "openbsd", |
| 287 | 290 | target_os = "solaris", |
| 291 | target_os = "android", | |
| 288 | 292 | target_vendor = "apple", |
| 289 | 293 | )), |
| 290 | 294 | should_panic |
| ... | ... | @@ -318,6 +322,7 @@ fn file_lock_dup() { |
| 318 | 322 | target_os = "netbsd", |
| 319 | 323 | target_os = "openbsd", |
| 320 | 324 | target_os = "solaris", |
| 325 | target_os = "android", | |
| 321 | 326 | target_vendor = "apple", |
| 322 | 327 | )), |
| 323 | 328 | should_panic |
library/std/src/os/aix/fs.rs+6-6| ... | ... | @@ -322,22 +322,22 @@ impl MetadataExt for Metadata { |
| 322 | 322 | self.as_inner().as_inner().st_size as u64 |
| 323 | 323 | } |
| 324 | 324 | 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 | |
| 326 | 326 | } |
| 327 | 327 | 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 | |
| 329 | 329 | } |
| 330 | 330 | 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 | |
| 332 | 332 | } |
| 333 | 333 | 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 | |
| 335 | 335 | } |
| 336 | 336 | 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 | |
| 338 | 338 | } |
| 339 | 339 | 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 | |
| 341 | 341 | } |
| 342 | 342 | fn st_blksize(&self) -> u64 { |
| 343 | 343 | 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 + |
| 530 | 530 | // method of calling a catch panic whilst juggling ownership. |
| 531 | 531 | let mut data = Data { f: ManuallyDrop::new(f) }; |
| 532 | 532 | |
| 533 | let data_ptr = (&raw mut data) as *mut u8; | |
| 534 | 533 | // SAFETY: |
| 535 | 534 | // |
| 536 | 535 | // 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 + |
| 541 | 540 | // - `do_catch`, the second argument, can be called with the `data_ptr` as well. |
| 542 | 541 | // See their safety preconditions for more information |
| 543 | 542 | 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) { | |
| 547 | 544 | Err(ManuallyDrop::into_inner(data.p)) |
| 545 | } else { | |
| 546 | Ok(ManuallyDrop::into_inner(data.r)) | |
| 548 | 547 | }; |
| 549 | 548 | } |
| 550 | 549 | |
| ... | ... | @@ -568,17 +567,12 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + |
| 568 | 567 | // data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>` |
| 569 | 568 | // Its must contains a valid `f` (type: F) value that can be use to fill |
| 570 | 569 | // `data.r`. |
| 571 | // | |
| 572 | // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind` | |
| 573 | // expects normal function pointers. | |
| 574 | 570 | #[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>) { | |
| 576 | 572 | // SAFETY: this is the responsibility of the caller, see above. |
| 577 | 573 | 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()); | |
| 582 | 576 | } |
| 583 | 577 | } |
| 584 | 578 | |
| ... | ... | @@ -590,22 +584,17 @@ pub unsafe fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + |
| 590 | 584 | // data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>` |
| 591 | 585 | // Since this uses `cleanup` it also hinges on a correct implementation of |
| 592 | 586 | // `__rustc_panic_cleanup`. |
| 593 | // | |
| 594 | // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind` | |
| 595 | // expects normal function pointers. | |
| 596 | 587 | #[inline] |
| 597 | 588 | #[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) { | |
| 599 | 590 | // SAFETY: this is the responsibility of the caller, see above. |
| 600 | 591 | // |
| 601 | 592 | // When `__rustc_panic_cleaner` is correctly implemented we can rely |
| 602 | 593 | // on `obj` being the correct thing to pass to `data.p` (after wrapping |
| 603 | 594 | // in `ManuallyDrop`). |
| 604 | 595 | unsafe { |
| 605 | let data = data as *mut Data<F, R>; | |
| 606 | let data = &mut (*data); | |
| 607 | 596 | let obj = cleanup(payload); |
| 608 | data.p = ManuallyDrop::new(obj); | |
| 597 | (*data).p = ManuallyDrop::new(obj); | |
| 609 | 598 | } |
| 610 | 599 | } |
| 611 | 600 | } |
library/std/src/sys/fs/unix.rs+13-3| ... | ... | @@ -599,15 +599,15 @@ impl FileAttr { |
| 599 | 599 | #[cfg(target_os = "aix")] |
| 600 | 600 | impl FileAttr { |
| 601 | 601 | 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) | |
| 603 | 603 | } |
| 604 | 604 | |
| 605 | 605 | 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) | |
| 607 | 607 | } |
| 608 | 608 | |
| 609 | 609 | 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) | |
| 611 | 611 | } |
| 612 | 612 | } |
| 613 | 613 | |
| ... | ... | @@ -1451,6 +1451,7 @@ impl File { |
| 1451 | 1451 | target_os = "cygwin", |
| 1452 | 1452 | target_os = "illumos", |
| 1453 | 1453 | target_os = "aix", |
| 1454 | target_os = "android", | |
| 1454 | 1455 | target_vendor = "apple", |
| 1455 | 1456 | ))] |
| 1456 | 1457 | pub fn lock(&self) -> io::Result<()> { |
| ... | ... | @@ -1478,6 +1479,7 @@ impl File { |
| 1478 | 1479 | target_os = "solaris", |
| 1479 | 1480 | target_os = "illumos", |
| 1480 | 1481 | target_os = "aix", |
| 1482 | target_os = "android", | |
| 1481 | 1483 | target_vendor = "apple", |
| 1482 | 1484 | )))] |
| 1483 | 1485 | pub fn lock(&self) -> io::Result<()> { |
| ... | ... | @@ -1494,6 +1496,7 @@ impl File { |
| 1494 | 1496 | target_os = "cygwin", |
| 1495 | 1497 | target_os = "illumos", |
| 1496 | 1498 | target_os = "aix", |
| 1499 | target_os = "android", | |
| 1497 | 1500 | target_vendor = "apple", |
| 1498 | 1501 | ))] |
| 1499 | 1502 | pub fn lock_shared(&self) -> io::Result<()> { |
| ... | ... | @@ -1521,6 +1524,7 @@ impl File { |
| 1521 | 1524 | target_os = "solaris", |
| 1522 | 1525 | target_os = "illumos", |
| 1523 | 1526 | target_os = "aix", |
| 1527 | target_os = "android", | |
| 1524 | 1528 | target_vendor = "apple", |
| 1525 | 1529 | )))] |
| 1526 | 1530 | pub fn lock_shared(&self) -> io::Result<()> { |
| ... | ... | @@ -1537,6 +1541,7 @@ impl File { |
| 1537 | 1541 | target_os = "cygwin", |
| 1538 | 1542 | target_os = "illumos", |
| 1539 | 1543 | target_os = "aix", |
| 1544 | target_os = "android", | |
| 1540 | 1545 | target_vendor = "apple", |
| 1541 | 1546 | ))] |
| 1542 | 1547 | pub fn try_lock(&self) -> Result<(), TryLockError> { |
| ... | ... | @@ -1580,6 +1585,7 @@ impl File { |
| 1580 | 1585 | target_os = "solaris", |
| 1581 | 1586 | target_os = "illumos", |
| 1582 | 1587 | target_os = "aix", |
| 1588 | target_os = "android", | |
| 1583 | 1589 | target_vendor = "apple", |
| 1584 | 1590 | )))] |
| 1585 | 1591 | pub fn try_lock(&self) -> Result<(), TryLockError> { |
| ... | ... | @@ -1599,6 +1605,7 @@ impl File { |
| 1599 | 1605 | target_os = "cygwin", |
| 1600 | 1606 | target_os = "illumos", |
| 1601 | 1607 | target_os = "aix", |
| 1608 | target_os = "android", | |
| 1602 | 1609 | target_vendor = "apple", |
| 1603 | 1610 | ))] |
| 1604 | 1611 | pub fn try_lock_shared(&self) -> Result<(), TryLockError> { |
| ... | ... | @@ -1642,6 +1649,7 @@ impl File { |
| 1642 | 1649 | target_os = "solaris", |
| 1643 | 1650 | target_os = "illumos", |
| 1644 | 1651 | target_os = "aix", |
| 1652 | target_os = "android", | |
| 1645 | 1653 | target_vendor = "apple", |
| 1646 | 1654 | )))] |
| 1647 | 1655 | pub fn try_lock_shared(&self) -> Result<(), TryLockError> { |
| ... | ... | @@ -1661,6 +1669,7 @@ impl File { |
| 1661 | 1669 | target_os = "cygwin", |
| 1662 | 1670 | target_os = "illumos", |
| 1663 | 1671 | target_os = "aix", |
| 1672 | target_os = "android", | |
| 1664 | 1673 | target_vendor = "apple", |
| 1665 | 1674 | ))] |
| 1666 | 1675 | pub fn unlock(&self) -> io::Result<()> { |
| ... | ... | @@ -1688,6 +1697,7 @@ impl File { |
| 1688 | 1697 | target_os = "solaris", |
| 1689 | 1698 | target_os = "illumos", |
| 1690 | 1699 | target_os = "aix", |
| 1700 | target_os = "android", | |
| 1691 | 1701 | target_vendor = "apple", |
| 1692 | 1702 | )))] |
| 1693 | 1703 | 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; |
| 172 | 172 | ``` |
| 173 | 173 | |
| 174 | 174 | In 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)]`. | |
| 176 | 176 | |
| 177 | 177 | [Intra-doc links](./linking-to-items-by-name.md) are resolved relative to where the doc comment is |
| 178 | 178 | defined. |
src/tools/miri/src/shims/unix/foreign_items.rs+1-1| ... | ... | @@ -342,7 +342,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 342 | 342 | } |
| 343 | 343 | "flock" => { |
| 344 | 344 | // 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)?; | |
| 346 | 346 | |
| 347 | 347 | let [fd, op] = this.check_shim_sig( |
| 348 | 348 | 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> { |
| 68 | 68 | let this = self.eval_context_mut(); |
| 69 | 69 | |
| 70 | 70 | // 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 | |
| 72 | 72 | // Calls `try_fn` with `data` as argument. If that executes normally, returns 0. |
| 73 | 73 | // If that unwinds, calls `catch_fn` with the first argument being `data` and |
| 74 | 74 | // 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> { |
| 129 | 129 | ); |
| 130 | 130 | |
| 131 | 131 | // 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)?; | |
| 133 | 133 | |
| 134 | 134 | // The Thread's `panic_payload` holds what was passed to `miri_start_unwind`. |
| 135 | 135 | // 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() { |
| 11 | 11 | std::intrinsics::catch_unwind( |
| 12 | 12 | //~^ ERROR: calling a function with calling convention "C" using calling convention "Rust" |
| 13 | 13 | std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn), |
| 14 | std::ptr::null_mut(), | |
| 14 | std::ptr::null_mut::<u8>(), | |
| 15 | 15 | |_, _| unreachable!(), |
| 16 | 16 | ); |
| 17 | 17 | } |
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 |
| 4 | 4 | LL | / std::intrinsics::catch_unwind( |
| 5 | 5 | LL | | |
| 6 | 6 | LL | | std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn), |
| 7 | LL | | std::ptr::null_mut(), | |
| 7 | LL | | std::ptr::null_mut::<u8>(), | |
| 8 | 8 | LL | | |_, _| unreachable!(), |
| 9 | 9 | LL | | ); |
| 10 | 10 | | |_________^ 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 | |
| 2 | 2 | //@ignore-target: solaris # Does not have flock |
| 3 | //@ignore-target: android # Does not (always?) have flock | |
| 4 | 3 | //@compile-flags: -Zmiri-disable-isolation |
| 5 | 4 | |
| 6 | 5 | use 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>> { |
| 64 | 64 | |
| 65 | 65 | let data_ptr = ptr::addr_of_mut!(data) as *mut u8; |
| 66 | 66 | 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>) { | |
| 70 | 68 | Err(data.p.take().unwrap()) |
| 69 | } else { | |
| 70 | Ok(data.r.take().unwrap()) | |
| 71 | 71 | }; |
| 72 | 72 | } |
| 73 | 73 |
src/tools/miri/tests/pass/shims/fs.rs+2-4| ... | ... | @@ -40,7 +40,7 @@ fn main() { |
| 40 | 40 | test_canonicalize(); |
| 41 | 41 | #[cfg(unix)] |
| 42 | 42 | test_pread_pwrite(); |
| 43 | #[cfg(not(any(target_os = "solaris", target_os = "android")))] | |
| 43 | #[cfg(not(target_os = "solaris"))] | |
| 44 | 44 | test_flock(); |
| 45 | 45 | test_readv_writev(); |
| 46 | 46 | #[cfg(all(unix, not(any(target_os = "solaris", target_os = "android"))))] |
| ... | ... | @@ -406,11 +406,9 @@ fn test_pread_pwrite() { |
| 406 | 406 | assert_eq!(&buf1, b" m"); |
| 407 | 407 | } |
| 408 | 408 | |
| 409 | // The standard library does not support this operation on Android | |
| 410 | // (https://github.com/rust-lang/rust/issues/148325). | |
| 411 | 409 | // Miri does not support the way this is implemented on Solaris |
| 412 | 410 | // (https://github.com/rust-lang/miri/issues/5038). |
| 413 | #[cfg(not(any(target_os = "solaris", target_os = "android")))] | |
| 411 | #[cfg(not(target_os = "solaris"))] | |
| 414 | 412 | fn test_flock() { |
| 415 | 413 | let bytes = b"Hello, World!\n"; |
| 416 | 414 | 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() { |
| 48 | 48 | |_| { |
| 49 | 49 | may_panic(); |
| 50 | 50 | }, |
| 51 | core::ptr::null_mut(), | |
| 51 | core::ptr::null_mut::<u8>(), | |
| 52 | 52 | |data, exception| { |
| 53 | 53 | log_number(data as usize); |
| 54 | 54 | log_number(exception as usize); |
tests/assembly-llvm/wasm_legacy_eh.rs+1-1| ... | ... | @@ -58,7 +58,7 @@ pub fn test_rtry() { |
| 58 | 58 | |_| { |
| 59 | 59 | may_panic(); |
| 60 | 60 | }, |
| 61 | core::ptr::null_mut(), | |
| 61 | core::ptr::null_mut::<u8>(), | |
| 62 | 62 | |data, exception| { |
| 63 | 63 | log_number(data as usize); |
| 64 | 64 | 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 { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | #[rustc_intrinsic] |
| 33 | unsafe fn catch_unwind( | |
| 34 | try_fn: fn(_: *mut u8), | |
| 35 | data: *mut u8, | |
| 36 | catch_fn: fn(_: *mut u8, _: *mut u8), | |
| 37 | ) -> i32; | |
| 33 | unsafe 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; | |
| 38 | 38 | |
| 39 | 39 | // CHECK-LABEL: @ptr_size |
| 40 | 40 | #[no_mangle] |
| ... | ... | @@ -46,10 +46,10 @@ pub fn ptr_size() -> usize { |
| 46 | 46 | // CHECK-LABEL: @test_catch_unwind |
| 47 | 47 | #[no_mangle] |
| 48 | 48 | pub unsafe fn test_catch_unwind( |
| 49 | try_fn: fn(_: *mut u8), | |
| 49 | try_fn: unsafe fn(_: *mut u8), | |
| 50 | 50 | data: *mut u8, |
| 51 | catch_fn: fn(_: *mut u8, _: *mut u8), | |
| 52 | ) -> i32 { | |
| 51 | catch_fn: unsafe fn(_: *mut u8, _: *mut u8), | |
| 52 | ) -> bool { | |
| 53 | 53 | // CHECK: start: |
| 54 | 54 | // CHECK: [[ALLOCA:%.*]] = alloca |
| 55 | 55 |
tests/codegen-llvm/emscripten-catch-unwind-wasm-eh.rs+10-10| ... | ... | @@ -28,11 +28,11 @@ const fn size_of<T>() -> usize { |
| 28 | 28 | loop {} |
| 29 | 29 | } |
| 30 | 30 | #[rustc_intrinsic] |
| 31 | unsafe fn catch_unwind( | |
| 32 | try_fn: fn(_: *mut u8), | |
| 33 | data: *mut u8, | |
| 34 | catch_fn: fn(_: *mut u8, _: *mut u8), | |
| 35 | ) -> i32; | |
| 31 | unsafe 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; | |
| 36 | 36 | |
| 37 | 37 | // CHECK-LABEL: @ptr_size |
| 38 | 38 | #[no_mangle] |
| ... | ... | @@ -44,10 +44,10 @@ pub fn ptr_size() -> usize { |
| 44 | 44 | // CHECK-LABEL: @test_catch_unwind |
| 45 | 45 | #[no_mangle] |
| 46 | 46 | pub unsafe fn test_catch_unwind( |
| 47 | try_fn: fn(_: *mut u8), | |
| 47 | try_fn: unsafe fn(_: *mut u8), | |
| 48 | 48 | data: *mut u8, |
| 49 | catch_fn: fn(_: *mut u8, _: *mut u8), | |
| 50 | ) -> i32 { | |
| 49 | catch_fn: unsafe fn(_: *mut u8, _: *mut u8), | |
| 50 | ) -> bool { | |
| 51 | 51 | // CHECK: start: |
| 52 | 52 | // CHECK: invoke void %try_fn(ptr %data) |
| 53 | 53 | // CHECK: to label %__rust_try.exit unwind label %catchswitch.i |
| ... | ... | @@ -62,8 +62,8 @@ pub unsafe fn test_catch_unwind( |
| 62 | 62 | // CHECK: catchret from %catchpad2.i to label %__rust_try.exit |
| 63 | 63 | |
| 64 | 64 | // 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 | |
| 67 | 67 | |
| 68 | 68 | catch_unwind(try_fn, data, catch_fn) |
| 69 | 69 | } |
tests/codegen-llvm/force-frame-pointers.rs+3| ... | ... | @@ -16,3 +16,6 @@ |
| 16 | 16 | // Always: attributes #{{.*}} "frame-pointer"="all" |
| 17 | 17 | // NonLeaf: attributes #{{.*}} "frame-pointer"="non-leaf" |
| 18 | 18 | pub 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() { |
| 49 | 49 | |_| { |
| 50 | 50 | may_panic(); |
| 51 | 51 | }, |
| 52 | core::ptr::null_mut(), | |
| 52 | core::ptr::null_mut::<u8>(), | |
| 53 | 53 | |data, exception| { |
| 54 | 54 | log_number(data as usize); |
| 55 | 55 | log_number(exception as usize); |
triagebot.toml-4| ... | ... | @@ -1127,10 +1127,6 @@ cc = [ |
| 1127 | 1127 | message = "Some changes occurred in GUI tests." |
| 1128 | 1128 | cc = ["@GuillaumeGomez"] |
| 1129 | 1129 | |
| 1130 | [mentions."tests/auxiliary/minicore.rs"] | |
| 1131 | message = "This PR modifies `tests/auxiliary/minicore.rs`." | |
| 1132 | cc = ["@jieyouxu"] | |
| 1133 | ||
| 1134 | 1130 | [mentions."src/rustdoc-json-types"] |
| 1135 | 1131 | message = """ |
| 1136 | 1132 | rustdoc-json-types is a **public** (although nightly-only) API. \ |