Skip to content

UnwindSafe is unergonomic #40628

Open
Open
@dpc

Description

@dpc

As I expressed on IRC, I feel like, unless quickly taken care of, UnwindSafe is going to be a "failed feature". I've seen now quite a bit of people that told me that "they just wrap everything in AssertUnwindSafe" defeating the whole purpose of it. I've also seen comments that UnwindSafe is a PITA - sentiment that I'm beginning to share. I am tempted to ignore UnwindSafe completely as well, even though I'd like to do stuff properly. Please hear me out.

UnwindSafe and RefUnwindSafe are not too complicated, but they force people into writing a lot of boilerplate, and the worst part once used ... force that boilerplate on all other users, that might not even know what is it all about.

Static dispatch works OK, since similarly to Send and Sync any struct will get UnwindSafe and RefUnwindSafe if all fields of it satisfy it.

The problem is dynamic dispatch, trait object and trait bounds. Any time someone has to use eg. Box<TraitObject>, even if it's only due to lack of impl Trait on stable, that person most probably should have done Box<Trait + RefUnwindSafe>. Otherwise that Box<Trait> does not satisfy SafeUnwind, even though most probably that would be the intention. After all "This trait is namely not implemented by UnsafeCell, the root of all interior mutability".

And even if that person is aware of "unwind safety", after putting +RefUnwindSafe it won't work because:

only Send/Sync traits can be used as additional traits in a trait object 

To get this working a lot of boilerplate needs to be added. Example in my code which is just a PITA. And the worst part: after putting UnwindSafe bound in types used in open-traits (to be implemented by users of a library), now all users have to satisfy that bound. They will have to remember about it, add blanket implementations adding UnwindSafe for every type used as trait object, and get libraries they might want to use it, to do the same...

I don't know. Maybe I'm missing something here, but I feel like at least +UnwindSafe should work just like +Send and +Sync.

Also, I think if the default would be different, there would be almost no problem. Box<Trait> should mean Box<Trait + RefUnwindSafe>, and users should be able to opt-out of it with Box<Trait + !RefUnwindSafe>. This way, unaware uses would get their types UnwindSafe without knowing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions