Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4b5d544
Implement `core::arch::return_address` and tests
chorman0773 Apr 26, 2026
706d098
Fix cfg use for disabling test on miri
chorman0773 Apr 28, 2026
06cb86d
fix closure HIR span context mismatch
cijiugechu Apr 30, 2026
c876de4
Final attempt at making miri work
chorman0773 May 3, 2026
dfc5fd5
Add `getsockname` shim for connecting and connected sockets
WhySoBad Apr 29, 2026
fdab736
Prepare for merging from rust-lang/rust
May 4, 2026
a1d0754
Merge ref '045b17737dab' from rust-lang/rust
May 4, 2026
eb5adcc
Merge pull request #5002 from rust-lang/rustup-2026-05-04
oli-obk May 4, 2026
8948418
Merge pull request #4985 from WhySoBad/network-socket-getsockname-for…
RalfJung May 4, 2026
c79b2c4
avoid underflow in std::Instant when computing times before program s…
RalfJung May 4, 2026
342fd9e
Merge pull request #5003 from RalfJung/time-underflow
RalfJung May 4, 2026
8e91dd7
fix: remove `WSAESHUTDOWN` workaround for socket writes
WhySoBad May 4, 2026
8b1b282
Merge pull request #5004 from WhySoBad/network-socket-remove-wsa-erro…
RalfJung May 4, 2026
df26762
core: Replace `ptr::slice_from_raw_parts` with `slice::from_raw_parts`
xtqqczze May 5, 2026
38f567f
Add epoll integration for network sockets
WhySoBad Apr 20, 2026
5e796af
Merge pull request #4973 from WhySoBad/network-socket-epoll-new
RalfJung May 6, 2026
b7548cb
Reformat `string_enum!`
Zalathar May 2, 2026
bd0533d
Replace `pass_mode` and `fail_mode` fields with `pass_fail_mode`
Zalathar Apr 30, 2026
78c27e9
Migrate from `PassMode`/`FailMode` to `PassFailMode`
Zalathar Apr 30, 2026
529a4ec
Use a `match` for checking UI test run results
Zalathar May 6, 2026
81d92de
Add `getaddrinfo` and `freeaddrinfo` shims
WhySoBad Apr 28, 2026
8e9c315
Merge pull request #4984 from WhySoBad/network-socket-dns
RalfJung May 6, 2026
27def62
Prepare for merging from rust-lang/rust
May 7, 2026
a7313f1
Merge ref '4ddd4538a881' from rust-lang/rust
May 7, 2026
cdc427a
fmt
May 7, 2026
172929a
bless genmc tests
RalfJung May 7, 2026
5721600
Merge pull request #5006 from rust-lang/rustup-2026-05-07
oli-obk May 7, 2026
f9bc18d
try to remove generic normalization from backtraces
RalfJung May 7, 2026
289b5af
Prepare for merging from rust-lang/rust
RalfJung May 7, 2026
4a44dc0
Merge ref '32bd660612bf' from rust-lang/rust
RalfJung May 7, 2026
4a771e4
remove QueryPerformanceCounter work-around
RalfJung May 7, 2026
c5d2ac9
Merge pull request #5008 from RalfJung/remove-windows-time-workaround
RalfJung May 7, 2026
e986232
Prepare for merging from rust-lang/rust
May 8, 2026
faa7656
Merge ref '63b1dfc0e00f' from rust-lang/rust
May 8, 2026
38f3687
Merge pull request #5010 from rust-lang/rustup-2026-05-08
oli-obk May 8, 2026
bba4079
Add simple `getsockopt` shim for TTL and SO_ERROR
WhySoBad Apr 21, 2026
c2ab95f
Handle --print=backend-has-mnemonic in cg_clif
bjorn3 May 8, 2026
5505d77
Merge pull request #5005 from WhySoBad/network-socket-getsockopt
RalfJung May 8, 2026
29852b2
cargo: Remove deprecated package authors field
xtqqczze May 8, 2026
d3a8c27
Merge pull request #5007 from RalfJung/backtrace-generics
oli-obk May 8, 2026
556645f
Merge pull request #5011 from xtqqczze/cargo-authors
RalfJung May 9, 2026
b2afb17
rename and adjust some libc utils for better consistency with std
RalfJung May 8, 2026
be7dece
Merge pull request #5012 from RalfJung/libc-helpers
RalfJung May 9, 2026
ea6eaab
fstat: expose permissions in 'mode' field
RalfJung May 9, 2026
773af23
stream_send_recv_stress tests: wait for threads to finish
RalfJung May 9, 2026
9c42644
support chmod and fchmod on unix hosts
RalfJung May 9, 2026
e549493
try_errnum_to_io_error: better support for unix targets on unix hosts
RalfJung May 9, 2026
c2bb45e
Merge pull request #5014 from RalfJung/permissions
RalfJung May 9, 2026
f48ca58
Merge pull request #5016 from RalfJung/try_errnum_to_io_error
RalfJung May 9, 2026
ef282ff
rustdoc: Reify emission types
fmease Apr 23, 2026
498c850
std_miri_test hack is not needed any more
RalfJung May 10, 2026
6f0005e
add gnu_get_libc_version stub for getaddrinfo error path
RalfJung May 10, 2026
2c1e114
./miri install: add --locked by default
RalfJung May 10, 2026
5c0718b
fix(reborrow): invalid unreachable in is_known_valid_scrutinee
aapoalas May 9, 2026
5b80eda
Merge pull request #5021 from RalfJung/gnu_get_libc_version
RalfJung May 10, 2026
1dca18d
Merge pull request #5020 from RalfJung/locked
RalfJung May 10, 2026
a0298aa
std fs tests: avoid matching on OS-provided error string
RalfJung May 10, 2026
f83b976
try_errnum_to_io_error: support all POSIX error codes
RalfJung May 10, 2026
46d2c71
Merge pull request #5022 from RalfJung/direct-errno-translation
RalfJung May 10, 2026
084bc48
Rollup merge of #156394 - RalfJung:miri, r=RalfJung
JonathanBrouwer May 10, 2026
30ec142
Rollup merge of #154972 - chorman0773:return_address, r=Mark-Simulacrum
JonathanBrouwer May 10, 2026
63e70d5
Rollup merge of #155679 - fmease:rustdoc-reify-emission-types, r=notr…
JonathanBrouwer May 10, 2026
2996170
Rollup merge of #155982 - cijiugechu:gio-ice-repro, r=chenyukang
JonathanBrouwer May 10, 2026
5246f6e
Rollup merge of #156323 - bjorn3:clif_has_mnemonic, r=wesleywiser
JonathanBrouwer May 10, 2026
dd38e55
Rollup merge of #156387 - RalfJung:fs-error-str, r=ChrisDenton
JonathanBrouwer May 10, 2026
e2b3f7e
Rollup merge of #156129 - Zalathar:pass-fail, r=jieyouxu
JonathanBrouwer May 10, 2026
06ccbc1
Rollup merge of #156192 - xtqqczze:slice-from-raw-parts, r=Mark-Simul…
JonathanBrouwer May 10, 2026
4d2f9ca
Rollup merge of #156365 - RalfJung:stream_send_recv_stress, r=nia-e
JonathanBrouwer May 10, 2026
cfd0d4c
Rollup merge of #156368 - aapoalas:reborrow-in-match-statement, r=Nad…
JonathanBrouwer May 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,12 @@ fn codegen_regular_intrinsic_call<'tcx>(
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
}

sym::return_address => {
let val = fx.bcx.ins().get_return_address(fx.pointer_type);
let val = CValue::by_val(val, ret.layout());
ret.write_cvalue(fx, val);
}

// Unimplemented intrinsics must have a fallback body. The fallback body is obtained
// by converting the `InstanceKind::Intrinsic` to an `InstanceKind::Item`.
_ => {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ impl CodegenBackend for CraneliftCodegenBackend {
println!("Cranelift version: {}", cranelift_codegen::VERSION);
}

fn has_mnemonic(&self, sess: &Session, mnemonic: &str) -> bool {
// All Cranelift supported targets support ret except for s390x
mnemonic == "ret" && sess.target.arch != Arch::S390x
}

fn target_cpu(&self, sess: &Session) -> String {
// FIXME handle `-Ctarget-cpu=native`
match sess.opts.cg.target_cpu {
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,22 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
}

sym::return_address => {
match self.sess().target.arch {
// Expand this list as needed
| Arch::Wasm32
| Arch::Wasm64 => {
let ty = self.type_ptr();
self.const_null(ty)
}
_ => {
let ty = self.type_ix(32);
let val = self.const_int(ty, 0);
self.call_intrinsic("llvm.returnaddress", &[], &[val])
}
}
}

_ => {
debug!("unknown intrinsic '{}' -- falling back to default body", name);
// Call the fallback body instead of generating the intrinsic code
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ impl CodegenBackend for LlvmCodegenBackend {
llvm::LLVMRustLLVMHasZstdCompression()
}

fn has_mnemonic(&self, sess: &Session, mnemonic: &str) -> bool {
llvm_util::target_has_mnemonic(sess, mnemonic)
}

fn target_config(&self, sess: &Session) -> TargetConfig {
target_config(sess)
}
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,6 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
match req.kind {
PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
PrintKind::BackendHasMnemonic => {
let mnemonic = req.arg.as_deref().expect("BackendHasMnemonic requires arg");
print_target_has_mnemonic(tm.raw(), mnemonic, out)
}
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
}
}
Expand Down Expand Up @@ -746,9 +742,9 @@ pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
Some(handle_native(name))
}

fn print_target_has_mnemonic(tm: &llvm::TargetMachine, mnemonic: &str, out: &mut String) {
use std::fmt::Write;
pub(crate) fn target_has_mnemonic(sess: &Session, mnemonic: &str) -> bool {
require_inited();
let tm = create_informational_target_machine(sess, false);
let cstr = SmallCStr::new(mnemonic);
let has_mnemonic = unsafe { llvm::LLVMRustTargetHasMnemonic(tm, cstr.as_ptr()) };
writeln!(out, "{}", has_mnemonic).unwrap();
unsafe { llvm::LLVMRustTargetHasMnemonic(tm.raw(), cstr.as_ptr()) }
}
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
| sym::contract_checks
| sym::atomic_fence
| sym::atomic_singlethreadfence
| sym::caller_location => {}
| sym::caller_location
| sym::return_address => {}
_ => {
span_bug!(
span,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ pub trait CodegenBackend {
false
}

/// Value printed by `--print=backend-has-mnemonic:...`.
///
/// Used by compiletest to determine whether tests involving `asm!()` should
/// be executed or skipped.
fn has_mnemonic(&self, _sess: &Session, _mnemonic: &str) -> bool {
false
}

/// The metadata loader used to load rlib and dylib metadata.
///
/// Alternative codegen backends may want to use different rlib or dylib formats than the
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,9 @@ fn print_crate_info(
println_info!("{}", calling_conventions.join("\n"));
}
BackendHasMnemonic => {
codegen_backend.print(req, &mut crate_info, sess);
let has_mnemonic: bool =
codegen_backend.has_mnemonic(sess, req.arg.as_ref().unwrap());
println_info!("{has_mnemonic}");
}
BackendHasZstd => {
let has_zstd: bool = codegen_backend.has_zstd();
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::ptr_guaranteed_cmp
| sym::ptr_mask
| sym::ptr_metadata
| sym::return_address
| sym::rotate_left
| sym::rotate_right
| sym::round_ties_even_f16
Expand Down Expand Up @@ -793,6 +794,8 @@ pub(crate) fn check_intrinsic_type(
| sym::atomic_xor => (2, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(1)], param(0)),
sym::atomic_fence | sym::atomic_singlethreadfence => (0, 1, Vec::new(), tcx.types.unit),

sym::return_address => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),

other => {
tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
return;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,8 @@ impl<'tcx> TyCtxt<'tcx> {
span,
..
}) => {
// Ensure that the returned span has the item's SyntaxContext.
fn_decl_span.find_ancestor_inside(*span).unwrap_or(*span)
// Ensure that the returned span has the closure expression's SyntaxContext.
fn_decl_span.find_ancestor_inside_same_ctxt(*span).unwrap_or(*span)
}
_ => self.hir_span_with_body(hir_id),
};
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,13 +363,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
| UpvarRef { .. }
| VarRef { .. }
| ZstLiteral { .. }
| Yield { .. } => true,
ExprKind::Reborrow { .. } => {
// FIXME(reborrow): matching on a Reborrow expression should be impossible
// currently. Whether this remains to be true, and if the reborrow result then is a
// known valid scrutinee requires further thought.
unreachable!("Reborrow expression in match")
}
| Yield { .. }
| Reborrow { .. } => true,
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,7 @@ symbols! {
residual,
result,
result_ffi_guarantees,
return_address,
return_position_impl_trait_in_trait,
return_type_notation,
riscv32,
Expand Down
30 changes: 30 additions & 0 deletions library/core/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,33 @@ pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?
pub fn breakpoint() {
core::intrinsics::breakpoint();
}

/// The `core::arch::return_address!()` macro returns a pointer with an address that corresponds to the caller of the function that invoked the `return_address!()` macro.
/// The pointer has no provenance, as if created by `core::ptr::without_provenance`. It cannot be used to read memory (other than ZSTs).
///
/// The value returned by the macro depends highly on the architecture and compiler (including any options set).
/// In particular, it is allowed to be wrong (particularly if inlining is involved), or even contain a nonsense value.
/// The result of this macro must not be relied upon for soundness or correctness, only for debugging purposes.
///
/// As a best effort, if a useful value cannot be determined (for example, due to limitations on the current codegen),
/// this macro tries to return a null pointer instead of nonsense (this cannot be relied upon for correctness, however).
///
/// Formally, this function returns a pointer with a non-deterministic address and no provenance.
///
/// This is equivalent to the gcc `__builtin_return_address(0)` intrinsic (other forms of the intrinsic are not supported).
/// Because the operation can be always performed by the compiler without crashing or causing undefined behaviour, invoking the macro is a safe operation.
///
/// ## Example
/// ```
/// #![feature(return_address)]
///
/// # fn run_test() {
/// let addr = core::arch::return_address!();
/// println!("Caller is {addr:p}");
/// # }
/// # #[cfg(not(miri))] // FIXME: Figure out how to make miri work before stabilizing this macro
/// # run_test()
/// ```
#[unstable(feature = "return_address", issue = "154966")]
#[allow_internal_unstable(core_intrinsics)]
pub macro return_address() {{ core::intrinsics::return_address() }}
13 changes: 13 additions & 0 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3598,3 +3598,16 @@ pub const fn va_copy<'f>(src: &VaList<'f>) -> VaList<'f> {
pub const unsafe fn va_end(ap: &mut VaList<'_>) {
/* deliberately does nothing */
}

/// Returns the return address of the caller function (after inlining) in a best-effort manner or a null pointer if it is not supported on the current backend.
/// Returning an accurate value is a quality-of-implementation concern, but no hard guarantees are
/// made about the return value: formally, the intrinsic non-deterministically returns
/// an arbitrary pointer without provenance.
///
/// Note that unlike most intrinsics, this is safe to call. This is because it only finds the return address of the immediate caller, which is guaranteed to be possible.
/// Other forms of the corresponding gcc or llvm intrinsic (which can have wildly unpredictable results or even crash at runtime) are not exposed.
#[rustc_intrinsic]
#[rustc_nounwind]
pub fn return_address() -> *const () {
core::ptr::null()
}
16 changes: 5 additions & 11 deletions library/core/src/slice/sort/shared/smallsort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ fn small_sort_general_with_scratch<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
// permutation of the input through drop_guard. This technique is similar
// to ping-pong merging.
bidirectional_merge(
&*ptr::slice_from_raw_parts(drop_guard.src, drop_guard.len),
slice::from_raw_parts(drop_guard.src, drop_guard.len),
drop_guard.dst,
is_less,
);
Expand Down Expand Up @@ -332,7 +332,7 @@ where
let v_base = v.as_mut_ptr();
let initial_region_len = if no_merge { len } else { len_div_2 };
// SAFETY: Both possible values of `initial_region_len` are in-bounds.
let mut region = unsafe { &mut *ptr::slice_from_raw_parts_mut(v_base, initial_region_len) };
let mut region = unsafe { slice::from_raw_parts_mut(v_base, initial_region_len) };

// Avoid compiler unrolling, we *really* don't want that to happen here for binary-size reasons.
loop {
Expand All @@ -357,21 +357,15 @@ where
}

// SAFETY: The right side of `v` based on `len_div_2` is guaranteed in-bounds.
unsafe {
region = &mut *ptr::slice_from_raw_parts_mut(v_base.add(len_div_2), len - len_div_2)
};
unsafe { region = slice::from_raw_parts_mut(v_base.add(len_div_2), len - len_div_2) };
}

// SAFETY: We checked that T is Freeze and thus observation safe.
// Should is_less panic v was not modified in parity_merge and retains it's original input.
// scratch and v must not alias and scratch has v.len() space.
unsafe {
let scratch_base = stack_array.as_mut_ptr() as *mut T;
bidirectional_merge(
&mut *ptr::slice_from_raw_parts_mut(v_base, len),
scratch_base,
is_less,
);
bidirectional_merge(slice::from_raw_parts_mut(v_base, len), scratch_base, is_less);
ptr::copy_nonoverlapping(scratch_base, v_base, len);
}
}
Expand Down Expand Up @@ -675,7 +669,7 @@ unsafe fn sort8_stable<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
// SAFETY: scratch_base[0..8] is now initialized, allowing us to merge back
// into dst.
unsafe {
bidirectional_merge(&*ptr::slice_from_raw_parts(scratch_base, 8), dst, is_less);
bidirectional_merge(slice::from_raw_parts(scratch_base, 8), dst, is_less);
}
}

Expand Down
55 changes: 10 additions & 45 deletions library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,6 @@ macro_rules! check {
};
}

#[cfg(windows)]
macro_rules! error {
($e:expr, $s:expr) => {
match $e {
Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
Err(ref err) => {
assert!(err.raw_os_error() == Some($s), "`{}` did not have a code of `{}`", err, $s)
}
}
};
}

#[cfg(unix)]
macro_rules! error {
($e:expr, $s:expr) => {
error_contains!($e, $s)
};
}

macro_rules! error_contains {
($e:expr, $s:expr) => {
match $e {
Expand Down Expand Up @@ -105,29 +86,17 @@ fn file_test_io_smoke_test() {
fn invalid_path_raises() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_that_does_not_exist.txt");
let result = File::open(filename);

#[cfg(all(unix, not(target_os = "vxworks")))]
error!(result, "No such file or directory");
#[cfg(target_os = "vxworks")]
error!(result, "no such file or directory");
#[cfg(windows)]
error!(result, 2); // ERROR_FILE_NOT_FOUND
let err = File::open(filename).unwrap_err();
assert_eq!(err.kind(), ErrorKind::NotFound);
}

#[test]
fn file_test_iounlinking_invalid_path_should_raise_condition() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");

let result = fs::remove_file(filename);

#[cfg(all(unix, not(target_os = "vxworks")))]
error!(result, "No such file or directory");
#[cfg(target_os = "vxworks")]
error!(result, "no such file or directory");
#[cfg(windows)]
error!(result, 2); // ERROR_FILE_NOT_FOUND
let err = fs::remove_file(filename).unwrap_err();
assert_eq!(err.kind(), ErrorKind::NotFound);
}

#[test]
Expand Down Expand Up @@ -939,12 +908,8 @@ fn recursive_rmdir_of_file_fails() {
let tmpdir = tmpdir();
let canary = tmpdir.join("do_not_delete");
check!(check!(File::create(&canary)).write(b"foo"));
let result = fs::remove_dir_all(&canary);
#[cfg(unix)]
error!(result, "Not a directory");
#[cfg(windows)]
error!(result, 267); // ERROR_DIRECTORY - The directory name is invalid.
assert!(result.is_err());
let err = fs::remove_dir_all(&canary).unwrap_err();
assert_eq!(err.kind(), ErrorKind::NotADirectory);
assert!(canary.exists());
}

Expand Down Expand Up @@ -1404,6 +1369,7 @@ fn open_flavors() {
let mut ra = OO::new();
ra.read(true).append(true);

// This error string is set by std itself so we are not at the whim of the OS here.
let invalid_options = "creating or truncating a file requires write or append access";

// Test various combinations of creation modes and access modes.
Expand Down Expand Up @@ -2148,7 +2114,6 @@ fn test_hidden_file_truncation() {

// See https://github.com/rust-lang/rust/pull/131072 for more details about why
// these two tests are disabled under Windows 7 here.
#[cfg(windows)]
#[test]
#[cfg_attr(target_vendor = "win7", ignore = "Unsupported under Windows 7.")]
fn test_rename_file_over_open_file() {
Expand All @@ -2174,10 +2139,9 @@ fn test_rename_file_over_open_file() {
}

#[test]
#[cfg(windows)]
#[cfg_attr(target_vendor = "win7", ignore = "Unsupported under Windows 7.")]
fn test_rename_directory_to_non_empty_directory() {
// Renaming a directory over a non-empty existing directory should fail on Windows.
// Renaming a directory over a non-empty existing directory should fail.
let tmpdir: TempDir = tmpdir();

let source_path = tmpdir.join("source_directory");
Expand All @@ -2188,7 +2152,8 @@ fn test_rename_directory_to_non_empty_directory() {

fs::write(target_path.join("target_file.txt"), b"target hello world").unwrap();

error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY
let err = fs::rename(source_path, target_path).unwrap_err();
assert_eq!(err.kind(), ErrorKind::DirectoryNotEmpty);
}

#[test]
Expand Down
Loading
Loading