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

utils: implement AsAny only on OpaqueObject #4157

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kchibisov
Copy link
Member

Given that AsAny was implemented for pretty much anything, it was really easy to use it on objects that were not really implementing AsAny.

@kchibisov
Copy link
Member Author

That ensures that the we cast to the right thing, since in some cases it was able to cast to wrapping container instead of the type that is wrapped. It's a bit annoying, but should help with random bugs.

Given that `AsAny` was implemented for pretty much anything, it was
really easy to use it on objects that were not really implementing
AsAny.
Copy link
Member

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't really see the value of this, so will neither "approve" nor "request changes" (if you're really blocked by this, then I'm fine with merging it).

The plan is to get rid of the platform modules anyhow, right? When would you hit this otherwise? In user code? If so, then I'd rather expose something like the following:

impl dyn Window {
    pub fn as_inner<T: 'static + Window>(&self) -> Option<&T> {
        let this: &(dyn std::any::Any + '_) = self.as_any();
        this.downcast_ref::<T>()
    }
}

// Similarly for ActiveEventLoop, MonitorHandle, etc.

This is also a bit cleaner than the self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap() that we do everywhere now, would simplify to self.as_inner::<crate::platform_impl::Window>().unwrap().

(I consider AsAny a hack anyhow, and one that we'll be able to remove once we have MSRV 1.86, since by then rust-lang/rust#65991 will have landed).

@kchibisov
Copy link
Member Author

The problem here is that T: Any implements AsAny for e.g. Arc, and when you call the method as_any on that Arc the cast will fail, since you'd need a manual deref() because the Arc had as_any implemented for it, because it implements Any. By using OpaqueObject we avoid that issue and when calling as_any on Arc we call the as_any on the T inside the Arc, thus lowering the odds of casting incorrectly, because of nested containers.

It's mostly to not make a mistake in internal code, since AsAny was implemented for all rust types.

@madsmtm
Copy link
Member

madsmtm commented Mar 9, 2025

I've opened #4160, I prefer that alternative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants