FFI and targets
The host, target, linker, ABI, or libc changes the result.
This page lists all 127 records in this family. 126 of them have a failing and a repaired fixture, and 32 are keyed to a compiler error code. Use the Atlas search to filter by mechanism, first check, or evidence.
Below the application layer
These cases in this family depend on the linker, a native toolchain, the target, a Cargo profile, the test harness, or the runtime. They are also featured on the Atlas front page.
- RFA-039 · Native symbol-matrix evidenceWhy a Rust FFI Symbol Disappeared After Enabling LTOBuilds a Rust staticlib with and without thin LTO, reads both symbol tables with nm, and links a C host against the result.
- RFA-125 · Linker evidenceWhy an extern Function Compiles but Fails With an Undefined SymbolCompiles and links one file. The failing file must stop at the final link with the recorded error and the repaired file must link and run.
- RFA-707 · Compiler evidenceA Rust Runtime Symbol Is More Than an Exported NameExporting a name such as memset defines a symbol the standard library itself calls with a fixed ABI.
- RFA-041 · Native target-matrix evidenceA Rust Native Dependency Built for the Host Instead of the TargetRuns the build script with HOST and TARGET set for a cross build and reads the machine type of the produced object with readelf.
- RFA-046 · Allocator sanitizer evidenceMemory Allocated on One Side of Rust FFI Was Freed on the OtherLinks a Rust staticlib into a C host built with clang AddressSanitizer, which reports a free through the wrong allocator.
- RFA-044 · Cargo workspace evidenceA Rust Enum Crossed C Safely Until a New Variant Was AddedAn enum crossing a C boundary needs a fixed representation and a plan for values the Rust side does not know.
- RFA-045 · Runtime evidenceWhat Happens When a Rust Panic Reaches an extern BoundaryWhether a panic may unwind through foreign frames depends on the ABI string and the panic strategy.
- RFA-695 · Cargo workspace evidenceA no_std Rust Binary Needs Exactly One Panic HandlerWithout std there is no panic runtime, so a no_std binary must define exactly one panic handler.
Complete symptom directory
Case identifiers and anchors are stable. Records whose page is not published yet are listed without a link. Records marked “no fixture yet” link to an article and have no executable fixture.
- RFA-023 — An FFI struct has `repr(C)` but values are still corrupted across the boundary.No fixture yet
- RFA-031 — Reading a `repr(packed)` field by value compiles, but printing or borrowing it fails with E0793.
- RFA-039 — A Rust function which appeared in a no-LTO symbol table disappears under LTO, and a foreign host reports that its expected entry point is undefined.
- RFA-041 — A native dependency compiles successfully during cross-compilation but produces code for the build host instead of the Rust target.
- RFA-044 — A Rust enum passed through C works until a new variant is added or another compiler chooses a different representation.
- RFA-045 — A panic reaches an extern boundary and the process aborts or enters behavior the caller cannot safely recover from.
- RFA-046 — Memory allocated by Rust or a native library corrupts the heap when the other side releases it.
- RFA-094 — Taking a reference to a field of `#[repr(packed)]` produces E0793 even inside unsafe code.
- RFA-095 — Reading a Rust union field fails E0133 because the compiler cannot know which field currently contains valid data.
- RFA-096 — Calling an `unsafe extern "C" fn` from ordinary Rust code produces E0133.
- RFA-097 — A C-variadic declaration using the Rust ABI fails E0045 because that calling convention does not support variadic arguments.
- RFA-116 — Calling a function annotated with an extra CPU target feature produces E0133 at an ordinary call site.
- RFA-117 — A struct using both packed and align representation modifiers fails E0587 with conflicting hints.
- RFA-118 — A repr(transparent) wrapper with two stored numeric fields fails E0690 because both fields contribute non-zero size.
- RFA-124 — A const assertion expects a repr(C) u8-plus-u32 structure to use five bytes, but target alignment makes it eight.
- RFA-125 — An unsafe extern function declaration type-checks, but final linking fails with an undefined native symbol.
- RFA-165 — CStr::from_bytes_with_nul rejects a byte slice containing a valid early NUL terminator because additional bytes follow that terminator.
- RFA-171 — Path::join with an absolute candidate discards the intended base on Unix, producing /etc/passwd instead of a path beneath the application directory.
- RFA-173 — Command::output returns Ok(Output) for a child that exits with status 7, while application code interpreted Ok as command success.
- RFA-177 — BufRead::read_line preserves old String contents and appends the next line, producing prefix:hello instead of replacing the buffer.
- RFA-178 — Read::read_exact returns UnexpectedEof after changing part of the destination buffer that application code expected to remain untouched.
- RFA-179 — Opening an existing file with File::create reduces its length to zero before the application writes replacement data.
- RFA-180 — Path::exists returns false for a path whose existence cannot be determined because resolving a self-referential symlink fails.
- RFA-186 — Two consecutive BufRead::fill_buf calls return the same unread bytes although application code expected the second call to advance the stream.
- RFA-194 — Path::starts_with returns false for /srv/application-cache against /srv/application although the raw text begins with that string.
- RFA-195 — Reading two bytes through a File returned by try_clone begins at byte three rather than at the start of the file.
- RFA-196 — OpenOptions configured with truncate and create still refuses an existing file and leaves its original bytes unchanged.
- RFA-199 — Path::parent returns Some containing an empty path for config.toml instead of returning None for the one-component relative path.
- RFA-200 — Splitting a newline-terminated string with str::lines produces no final empty item, so a record count is one smaller than expected.
- RFA-202 — After File::set_len shrinks a file, stream_position still reports the old end and the cursor is now beyond the new file length.
- RFA-203 — A write through an append-mode File lands at the end even after the handle was successfully seeked to byte zero.
- RFA-211 — str::match_indices finds the first aba in ababa but does not report the equally valid overlapping match beginning at byte two.
- RFA-212 — BufWriter::get_ref returns an empty underlying Vec immediately after write_all accepted three bytes into the writer.
- RFA-213 — A Drop implementation that writes a cleanup marker runs when main returns but never runs when the child calls process::exit.
- RFA-215 — Uppercasing one Rust char produces two output chars, breaking code that reserved or validated exactly one scalar value per input scalar.
- RFA-216 — str::trim removes ideographic spaces surrounding a token although the parser intended to strip only ASCII protocol whitespace.
- RFA-217 — Path::extension returns None for .env and only gz for archive.tar.gz, contradicting a parser that treated every suffix after the first dot as an extension.
- RFA-219 — fs::copy succeeds when the destination already exists and replaces its old bytes instead of returning AlreadyExists.
- RFA-221 — Splitting a two-character string with an empty pattern returns four fields instead of two.
- RFA-222 — A character passes is_numeric but to_digit(10) returns None during parsing.
- RFA-224 — Writing one byte at cursor position five over a two-byte Vec creates three zero bytes before the new byte.
- RFA-229 — Calling elapsed on a SystemTime one hour in the future returns SystemTimeError instead of a negative or zero duration.
- RFA-232 — Parsing the text TRUE as bool returns ParseBoolError although a human reads it as true.
- RFA-237 — The mapped address ::ffff:127.0.0.1 returns false from Ipv6Addr::is_loopback even though its embedded IPv4 address is loopback.
- RFA-238 — A String reserved for two units grows when two non-ASCII characters are pushed into it.
- RFA-239 — String::from_utf8_lossy returns Cow::Borrowed for valid bytes although caller code expected an owned String.
- RFA-240 — str::get returns None for byte offset 1 in a non-empty string even though the offset is below len.
- RFA-242 — char::from_u32 returns None for 0xD800 even though the number is below char::MAX and occurs in UTF-16 data.
- RFA-247 — starts_with returns true for banana with the char slice ['a', 'b'], although banana does not begin with the sequence ab.
- RFA-251 — str::splitn with n equal to zero returns an empty iterator instead of one unsplit copy of the original string.
- RFA-256 — char::encode_utf8 panics when encoding an accented scalar into a one-byte destination buffer.
- RFA-262 — Parsing the two-byte ASCII string ab as char returns an error, while one multibyte scalar such as accented e succeeds.
- RFA-263 — Stripping prefix aa from aaaa returns aa instead of removing every repeated copy and returning an empty string.
- RFA-267 — Reading from a Cursor positioned beyond its buffer returns zero bytes and leaves the position beyond the end.
- RFA-268 — Path::components normalizes an internal current-directory marker but still yields ParentDir for a parent marker.
- RFA-271 — char::from_digit returns Option for an invalid digit value but panics when the caller supplies a radix greater than 36.
- RFA-272 — u32::from_str_radix panics for radix one even though malformed digits and overflow are returned through ParseIntError.
- RFA-275 — Truncating a Cursor's backing Vec through get_mut changes its length from three to one but leaves the independent cursor position at three.
- RFA-276 — OpenOptions with read and create enabled fails with InvalidInput because create does not implicitly grant write or append access.
- RFA-277 — After three bytes are read through take(4), the next three-byte read returns only one byte and following reads report EOF.
- RFA-278 — Popping accented e from a Rust String shortens len by two because pop removes one char while String::len reports UTF-8 bytes.
- RFA-279 — After set_extension removes gz from archive.tar.gz, Path::extension returns tar because the earlier dotted suffix becomes the new final extension.
- RFA-280 — Read::chain permanently switches to its second reader after the first reader returns Ok(0), even if that reader would produce data on a later call.
- RFA-281 — write_all through Cursor<&mut [u8]> writes the fitting prefix, then returns WriteZero when the cursor reaches the fixed slice boundary.
- RFA-282 — split_inclusive on a string ending with its separator attaches that separator to the preceding item and does not return a final empty item.
- RFA-289 — Parsing ::1:8080 as SocketAddrV6 fails even though its intended IPv6 host and port are individually valid.
- RFA-290 — BufRead::skip_until on abc| returns four, although code treated the count as the three-byte payload length before the delimiter.
- RFA-298 — A child launched with Command::output reads immediate EOF from stdin instead of inheriting input from its parent.
- RFA-299 — str::lines splits CRLF but keeps a lone carriage return inside the surrounding line instead of treating it as a boundary.
- RFA-305 — Metadata queried for a symbolic link reports a regular file type because the query describes the link destination.
- RFA-306 — A second logical process request built from the same Command retains the argument configured for the first request.
- RFA-316 — Clearing the portable readonly flag on a Unix file changes mode 0444 to 0666 instead of restoring only owner write permission.
- RFA-317 — DirEntry metadata identifies a symbolic link while fs::metadata on the same entry path identifies its regular-file destination.
- RFA-318 — BufWriter::into_inner delivers its buffered bytes but a wrapped probe records no call to the underlying flush method.
- RFA-319 — A child aborts and produces an unsuccessful ExitStatus, but code returns None rather than a shell-style integer exit code.
- RFA-326 — A valid Unix operating-system string cannot be borrowed as str because one of its bytes is not valid UTF-8.
- RFA-330 — After one logical byte is consumed and BufReader is unwrapped, the returned inner reader is already at end of input.
- RFA-331 — A direct write through BufWriter::get_mut appears before older output still held in the wrapper's pending buffer.
- RFA-337 — UTF-8 validation reports a valid prefix but no invalid-sequence length when a chunk ends partway through a possible scalar value.
- RFA-338 — CString::new rejects bytes containing zero instead of treating the first zero as a terminator and silently ignoring the suffix.
- RFA-340 — BufReader reports logical position one, yet the seekable reader returned by into_inner exposes position six after read-ahead.
- RFA-345 — A file opens and its bytes are readable, but fs::read_to_string fails when one stored byte is not valid UTF-8.
- RFA-346 — Reading a Unix symlink through an absolute path returns target.txt rather than the absolute target path.
- RFA-347 — decode_utf16 yields an error for an unpaired surrogate and then continues to yield later valid characters.
- RFA-352 — Calling char::escape_debug on printable non-ASCII text keeps the Unicode scalar visible instead of producing a hexadecimal escape.
- RFA-354 — After three bytes are read through a five-byte Take adapter, set_limit(5) permits five more bytes rather than only two.
- RFA-355 — BufReader::buffer returns an empty slice immediately after construction even though the underlying reader contains bytes.
- RFA-361 — String::split_off(1) panics on éclair because byte one lies inside the two-byte UTF-8 encoding of é.
- RFA-365 — After Child::wait returns, child.stdin is None because Rust took and closed the piped handle before blocking for process exit.
- RFA-366 — Collecting env::vars panics after the process environment contains a Unix byte sequence that is not valid Unicode.
- RFA-367 — After String::from_utf8 rejects one invalid byte, FromUtf8Error still exposes and can return the complete owned input vector.
- RFA-374 — Adding repr(C) to an empty Rust enum produces E0084 instead of creating a C-compatible uninhabited type.
- RFA-379 — env::join_paths returns JoinPathsError when one Unix path contains a colon instead of escaping the colon.
- RFA-389 — OsString::into_string returns Err with the original owned value when Unix bytes are not valid UTF-8.
- RFA-401 — A packed outer structure fails with E0588 because one nested field type declares repr(align(8)).
- RFA-402 — An enum mixing an explicit discriminant with a data-carrying variant fails E0732 until an integer representation is specified.
- RFA-407 — Seeking a BufWriter causes the wrapped writer to receive its buffered write before it receives the seek operation.
- RFA-408 — BufRead::read_until leaves an existing prefix in the destination and appends bytes through and including the delimiter.
- RFA-414 — BufRead::split over a,b, yields a and b without commas and without a final empty field.
- RFA-415 — LineWriter keeps an unterminated abc buffered but sends abc plus newline to its inner writer as soon as the newline arrives.
- RFA-416 — BufReader::seek to its current logical position empties two unread bytes from the internal buffer, yet the next read still returns the correct byte.
- RFA-514 — Destructuring a tuple in an extern C function declaration fails with E0130 because foreign declarations accept parameter names and types, not Rust body patterns.
- RFA-558 — Annotating Header with repr(network) fails with E0539 because network is not a representation hint understood by rustc.
- RFA-561 — Annotating Status with repr(u16, u32) fails with E0566 because one enum cannot promise two incompatible discriminant representations simultaneously.
- RFA-569 — Annotating CacheLine with repr(align(24)) fails with E0589 because explicit alignment must be a supported power of two.
- RFA-571 — Transmuting a named function directly to fn() fails with E0591 because its function-item type is zero-sized and is not the function-pointer value.
- RFA-585 — Passing f32 through printf's variadic arguments fails with E0617 because the C variadic ABI expects the promoted double representation.
- RFA-592 — Combining repr(packed) with repr(packed(2)) fails with E0634 because one type cannot promise two packing constraints.
- RFA-594 — Casting zero to *const _ fails with E0641 because no context tells rustc what kind of pointee the raw pointer addresses.
- RFA-598 — An export_name containing an embedded NUL fails with E0648 because object-file and linker symbol naming cannot preserve that requested identity.
- RFA-603 — A transparent Measurement containing f32 and unconstrained U fails with E0690 because U could be a second non-zero-sized field.
- RFA-604 — Annotating RequestId with repr(transparent, C) fails with E0692 because transparent delegation and C struct layout are incompatible representation contracts.
- RFA-605 — Writing repr(align = 16) fails with E0539 because the alignment hint requires nested-list syntax align(16).
- RFA-609 — Declaring extern service fails with E0703 because service is a domain label, not a calling convention recognised by rustc.
- RFA-618 — Applying repr(transparent) to Status with Ready and Failed fails with E0731 because representation cannot delegate through two alternatives.
- RFA-619 — Combining an explicit Empty = 0 discriminant with Data(u8) fails with E0732 until the enum declares an integer representation.
- RFA-622 — Applying track_caller to an extern C function fails with E0737 because the implicit caller-location argument belongs to the Rust ABI.
- RFA-623 — Putting String directly in a union fails with E0740 because Rust cannot know which overlapping field needs destruction.
- RFA-637 — Constructing a union with both integer and float fields fails with E0784 because all fields overlap and one expression must select exactly one interpretation to initialise.
- RFA-639 — Formatting a u32 field from a packed header fails with E0793 even though the source contains no visible ampersand.
- RFA-676 — CString::new returns NulError for bytes containing zero before the end instead of preserving the complete Rust byte sequence.
- RFA-677 — The extension of archive.tar.gz is gz rather than tar.gz, so a compound-format check does not match.
- RFA-695 — A no_std executable with an entry symbol still fails because no #[panic_handler] function exists in its dependency graph.
- RFA-696 — Vec is unavailable in a no_std library even though slices, Option, and other core types still compile.
- RFA-706 — An extern C function returning core::ffi::c_void triggers c_void_returns even though the intent was to model a C function returning void.
- RFA-707 — A no_mangle function named memset is rejected even though the Rust function itself is syntactically valid and has an extern C ABI.
- RFA-720 — An exported extern C function named strlen is rejected under deny(suspicious_runtime_symbol_definitions) because it accepts *mut f32 instead of *const c_char.