Skip to content

Fails compiling in rust-analyzer #771

@nooly1998

Description

@nooly1998

Compile Error in aarch64-apple-darwin target.

proj config:

[package]
name = "untitled"
version = "0.0.0"
edition = "2021"

[dependencies]
objc2 = "0.6.1"
objc2-foundation = "0.3.1"
objc2-app-kit = "0.3.1"

objc2-0.6.1 example code:

#![deny(unsafe_op_in_unsafe_fn)]
use std::cell::OnceCell;

use objc2::rc::Retained;
use objc2::runtime::ProtocolObject;
use objc2::{define_class, msg_send, DefinedClass, MainThreadOnly};
use objc2_app_kit::{
    NSApplication, NSApplicationActivationPolicy, NSApplicationDelegate, NSAutoresizingMaskOptions,
    NSBackingStoreType, NSColor, NSFont, NSTextAlignment, NSTextField, NSWindow, NSWindowDelegate,
    NSWindowStyleMask,
};
use objc2_foundation::{
    ns_string, MainThreadMarker, NSNotification, NSObject, NSObjectProtocol, NSPoint, NSRect,
    NSSize,
};

#[derive(Debug, Default)]
struct AppDelegateIvars {
    window: OnceCell<Retained<NSWindow>>,
}

define_class!(
    // SAFETY:
    // - The superclass NSObject does not have any subclassing requirements.
    // - `Delegate` does not implement `Drop`.
    #[unsafe(super = NSObject)]
    #[thread_kind = MainThreadOnly]
    #[ivars = AppDelegateIvars]
    struct Delegate;

    // SAFETY: `NSObjectProtocol` has no safety requirements.
    unsafe impl NSObjectProtocol for Delegate {}

    // SAFETY: `NSApplicationDelegate` has no safety requirements.
    unsafe impl NSApplicationDelegate for Delegate {
        // SAFETY: The signature is correct.
        #[unsafe(method(applicationDidFinishLaunching:))]
        fn did_finish_launching(&self, notification: &NSNotification) {
            let mtm = self.mtm();

            let app = unsafe { notification.object() }
                .unwrap()
                .downcast::<NSApplication>()
                .unwrap();

            let text_field = unsafe {
                let text_field = NSTextField::labelWithString(ns_string!("Hello, World!"), mtm);
                text_field.setFrame(NSRect::new(
                    NSPoint::new(5.0, 100.0),
                    NSSize::new(290.0, 100.0),
                ));
                text_field.setTextColor(Some(&NSColor::colorWithSRGBRed_green_blue_alpha(
                    0.0, 0.5, 0.0, 1.0,
                )));
                text_field.setAlignment(NSTextAlignment::Center);
                text_field.setFont(Some(&NSFont::systemFontOfSize(45.0)));
                text_field.setAutoresizingMask(
                    NSAutoresizingMaskOptions::ViewWidthSizable
                        | NSAutoresizingMaskOptions::ViewHeightSizable,
                );
                text_field
            };

            // SAFETY: We disable releasing when closed below.
            let window = unsafe {
                NSWindow::initWithContentRect_styleMask_backing_defer(
                    NSWindow::alloc(mtm),
                    NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(300.0, 300.0)),
                    NSWindowStyleMask::Titled
                        | NSWindowStyleMask::Closable
                        | NSWindowStyleMask::Miniaturizable
                        | NSWindowStyleMask::Resizable,
                    NSBackingStoreType::Buffered,
                    false,
                )
            };
            // SAFETY: Disable auto-release when closing windows.
            // This is required when creating `NSWindow` outside a window
            // controller.
            unsafe { window.setReleasedWhenClosed(false) };

            // Set various window properties.
            window.setTitle(ns_string!("A window"));
            let view = window.contentView().expect("window must have content view");
            unsafe { view.addSubview(&text_field) };
            window.center();
            unsafe { window.setContentMinSize(NSSize::new(300.0, 300.0)) };
            window.setDelegate(Some(ProtocolObject::from_ref(self)));

            // Show the window.
            window.makeKeyAndOrderFront(None);

            // Store the window in the delegate.
            self.ivars().window.set(window).unwrap();

            app.setActivationPolicy(NSApplicationActivationPolicy::Regular);

            // Activate the application.
            // Required when launching unbundled (as is done with Cargo).
            #[allow(deprecated)]
            app.activateIgnoringOtherApps(true);
        }
    }

    // SAFETY: `NSWindowDelegate` has no safety requirements.
    unsafe impl NSWindowDelegate for Delegate {
        #[unsafe(method(windowWillClose:))]
        fn window_will_close(&self, _notification: &NSNotification) {
            // Quit the application when the window is closed.
            unsafe { NSApplication::sharedApplication(self.mtm()).terminate(None) };
        }
    }
);

impl Delegate {
    fn new(mtm: MainThreadMarker) -> Retained<Self> {
        let this = Self::alloc(mtm).set_ivars(AppDelegateIvars::default());
        // SAFETY: The signature of `NSObject`'s `init` method is correct.
        unsafe { msg_send![super(this), init] }
    }
}

fn main() {
    let mtm = MainThreadMarker::new().unwrap();

    let app = NSApplication::sharedApplication(mtm);
    let delegate = Delegate::new(mtm);
    app.setDelegate(Some(ProtocolObject::from_ref(&*delegate)));

    app.run();
}
compile error:
error[E0200]: the trait `NSObjectProtocol` requires an `unsafe impl` declaration
   --> src/main.rs:22:1
    |
22  | / define_class!(
...   |
113 | | );
    | |_^
    |
    = note: the trait `NSObjectProtocol` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
    = note: this error originates in the macro `$crate::__define_class_output_impls` which comes from the expansion of the macro `define_class` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `unsafe` to this trait implementation
   --> /Users/username/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/objc2-0.6.1/src/macros/define_class.rs:862:9
    |
862 |         unsafe impl $protocol for $for {}
    |         ++++++

The same problem occurs in all unsafe implementations of the define_class! macro.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-objc2Affects the `objc2`, `objc2-exception-helper` and/or `objc2-encode` cratesbugSomething isn't working

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions