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

Fix improper_ctypes warnings in Rust Nightly #24684

Closed
SimonSapin opened this issue Nov 7, 2019 · 13 comments
Closed

Fix improper_ctypes warnings in Rust Nightly #24684

SimonSapin opened this issue Nov 7, 2019 · 13 comments
Labels

Comments

@SimonSapin
Copy link
Member

@SimonSapin SimonSapin commented Nov 7, 2019

Steps:

  • Make a branch up to date with origin/master
  • Run ./mach rustup, which updates the rust-toolchain file
  • Run ./mach build
  • See many warnings like
    warning: `extern` fn uses type `script_runtime::JSContext`, which is not FFI-safe
       --> components/script/script_runtime.rs:829:56
        |
    829 | unsafe extern "C" fn report_stream_error_callback(_cx: *mut JSContext, error_code: usize) {
        |                                                        ^^^^^^^^^^^^^^ not FFI-safe
        |
        = note: `#[warn(improper_ctypes)]` on by default
        = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
        = note: this struct has unspecified layout
  • Find a way to fix them. This may involve upgrading rust-bindgen, or making changes rust-bindgen and then upgrading to a version with those changes
  • Revert the rust-toolchain change
  • Submit a PR

We don’t need to upgrade the Rust version yet, but the next time we do those warnings would block landing the upgrade unless we change CI to allow build warnings.

Is suspect that rust-lang/rust#65134 is what introduced these warnings.

@jdm
Copy link
Member

@jdm jdm commented Nov 7, 2019

JSContext is indeed not FFI-safe. It should be a jsapi::JSContext instead, and #24653 fixes that.

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 12, 2019

The Rust team is (kindly) waiting on us to be able to upgrade before landing rust-lang/rust#66344. I have a branch ready for that, but it requires a Nightly more recent than these new warnings.

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 13, 2019

I’ve looked into this. Unfortunately there is no accidental bug here: the lint was intentionally changed to warn against a pattern that is in pervasive use in our DOM bindings.

Specifically: when an extern fn function (meant to be called by C++ or JIT’ed code in SpiderMonkey) takes as parameter a raw pointer to a Rust struct that is not FFI-safe.

Our DOM objects are based on many Rust structs that are not “FFI-safe”: non-Rust code cannot relay on their exact memory layout. Making a struct FFI-safe involves using #[repr(C)], but it shouldn’t be necessary for DOM objects that are only manipulated directly in Rust code, or through pointers in non-Rust code.

Currently, raw pointers to a non-FFI-safe type are themselves not considered FFI-safe by the improper_ctypes lint. I’ve commented in rust-lang/rust#66220 (comment) about potentially reconsidering this.

In the meantime, we could unblock the upgrade by adding #[allow(improper_ctypes)] to large parts of our FFI, but that seems rather counter-productive.

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 13, 2019

we could unblock the upgrade by adding #[allow(improper_ctypes)] to large parts of our FFI

@jdm, @nox, how would you feel about doing this and keeping this issue open to track fixing it later? Though there’s a risk it falls through the cracks…

@jdm
Copy link
Member

@jdm jdm commented Nov 13, 2019

I'm fine with being pragmatic when we're blocking the Rust project from making progress. That being said, our DOM objects should already be repr(C). Which types are actually being warned about?

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 13, 2019

We use repr(C) to preserve field order (and have the "parent" at the same memory address through being the first field), but many of these structs contain fields that are not FFI-safe themeselves: HashMap, RefCell, etc.

@nox
Copy link
Member

@nox nox commented Nov 13, 2019

One other solution would be to make the various extern "C" functions for which the lint is triggered take some sort of *mut c_void instead, which we then cast to the proper type inside the function.

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 13, 2019

It’s possible. I started doing it for the this parameter of methods generated by CGSpecializedMethod in components/script/dom/bindings/codegen/CodegenRust.py, which cut the number of warnings in ~half.

But there are a number of other cases. It’s hard to say without doing it, but I wonder if pushing this to completion would lead us to having c_void almost everywhere, reducing type safety.

@CryZe
Copy link

@CryZe CryZe commented Nov 13, 2019

Yeah while that would work, that would be pretty unfortunate. At the moment I‘m making heavy use of stuff like Option<&mut SomeRustType> as parameters in my C FFI, as it both allows for super clean safe handling from Rust‘s side and also nice automatically generated high level bindings for the other side. Reducing it to raw void pointers only would significantly hurt both.

@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented Nov 13, 2019

(Did you mean that comment for rust-lang/rust#66220?)

@camelid
Copy link
Contributor

@camelid camelid commented May 29, 2020

Is this still an issue?

@jdm
Copy link
Member

@jdm jdm commented May 29, 2020

We do not appear to have blanket allow_ctypes in most of our code (based on https://github.com/servo/servo/search?q=improper_ctypes&unscoped_q=improper_ctypes), so I think the answer is no.

@jdm jdm closed this May 29, 2020
@SimonSapin
Copy link
Member Author

@SimonSapin SimonSapin commented May 30, 2020

This was an issue because we run CI with RUSTFLAGS="-D warnings", but it’s not anymore because this new warning was reverted in rust-lang/rust#66378.

There is ongoing work at rust-lang/rust#72700 to add it again, but this time:

  • Under a dedicated improper_ctypes_definitions lint name, separate from improper_ctypes, so we could #[allow] it without disabling previously-fine lints.
  • It considers *const T, *mut T, &T and &mut T to be FFI-safe if T: Sized, even if T is not FFI-safe

With the latter change this lint should not be as much of an issue for as the initial version was.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.