Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trying to get pointer to extern typed field causes runtime panic #126800

Open
lolbinarycat opened this issue Jun 21, 2024 · 6 comments
Open

trying to get pointer to extern typed field causes runtime panic #126800

lolbinarycat opened this issue Jun 21, 2024 · 6 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. F-extern_types `#![feature(extern_types)]`

Comments

@lolbinarycat
Copy link
Contributor

I tried this code:

#![feature(extern_types)]
extern {
    type Opaque;
}

struct Thing {
    _pad: u8,
    o: Opaque,
}

fn main() {
    let v = b"a";
    let x: &Thing = unsafe { std::mem::transmute(&v) };
    let field_ptr = &x.o as *const Opaque;
    println!("{:X}", field_ptr as usize)
}

I expected to see this happen: printing a stack address

Instead, this happened: panic: attempted to compute the size or alignment of extern type

Context

one of the main usecases for extern types is representing trailing fields of variable size for C ffi. this bug completely makes this impossible. it also panics during a piece of safe code that should be infallible. this panic does not occur if the extern type is the only field.

Meta

rustc --version --verbose:

rustc 1.80.0-nightly (debd22da6 2024-05-29)
binary: rustc
commit-hash: debd22da66cfa97c74040ebf68e420672ac8560e
commit-date: 2024-05-29
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.6
Backtrace

Compiling playground v0.0.1 (/playground)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s
     Running `target/debug/playground`
thread 'main' panicked at library/core/src/panicking.rs:221:5:
attempted to compute the size or alignment of extern type `Opaque`
stack backtrace:
   0: rust_begin_unwind
             at /rustc/684b3553f70148ded97a80371c2405984d4f6aa7/library/std/src/panicking.rs:661:5
   1: core::panicking::panic_nounwind_fmt::runtime
             at /rustc/684b3553f70148ded97a80371c2405984d4f6aa7/library/core/src/panicking.rs:112:18
   2: core::panicking::panic_nounwind_fmt
             at /rustc/684b3553f70148ded97a80371c2405984d4f6aa7/library/core/src/panicking.rs:122:5
   3: core::panicking::panic_nounwind
             at /rustc/684b3553f70148ded97a80371c2405984d4f6aa7/library/core/src/panicking.rs:221:5
   4: playground::main
             at ./[src/main.rs:14](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021#):21
   5: core::ops::function::FnOnce::call_once
             at /rustc/684b3553f70148ded97a80371c2405984d4f6aa7/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread caused non-unwinding panic. aborting.

@lolbinarycat lolbinarycat added the C-bug Category: This is a bug. label Jun 21, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 21, 2024
@saethlin
Copy link
Member

The code you want cannot be allowed because the offset of the extern type field depends on the alignment of the extern type, which is unknowable.

@lolbinarycat
Copy link
Contributor Author

hmm, this is an odd situation. it does seem like this should be impossible, since the alignment cannot be known, but it is also one of the primary usecases laid out in the RFC (see the OpaqueTail example).

perhaps there should be some way to explicitly "opt in" to the extern type having a known alignment (maybe just by using #[align]?)

@lolbinarycat
Copy link
Contributor Author

behavior of trailing extern type fields should be added to the list of unresolved questions in the tracking issue #43467

@saethlin
Copy link
Member

You can feel free to comment on the tracking issue, but the behavior you are observing here is very intentional and not a bug in the implementation. We even have a test that the above code pattern panics: https://github.com/rust-lang/rust/blob/c1b336cb6b491b3be02cd821774f03af4992f413/tests/ui/extern/extern-types-field-offset.rs

@saethlin saethlin added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 21, 2024
@lolbinarycat
Copy link
Contributor Author

then i would contend that the RFC was merged before it was ready, since it contains contradictory examples. indeed, the "Detailed Design" section does not contain many details at all.

@Wasabi375
Copy link

I get an similar error when I use repr(packed) and addr_of!(x.o):

attempted to compute the size or alignment of extern type Opaque

Correct me if I'm wrong, but packed implies that the alignment is ignored. So in this case it should not be required to get a pointer.

@tmiasko tmiasko added the F-extern_types `#![feature(extern_types)]` label Jul 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. F-extern_types `#![feature(extern_types)]`
Projects
None yet
Development

No branches or pull requests

5 participants