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

Enum support for pin_project! macro #28

Merged
merged 5 commits into from
Oct 24, 2020
Merged

Enum support for pin_project! macro #28

merged 5 commits into from
Oct 24, 2020

Conversation

taiki-e
Copy link
Owner

@taiki-e taiki-e commented Sep 20, 2020

Like pin-project, by passing an argument with the same name as the method to the attribute, you can name the projection type returned from the method. This allows you to use pattern matching on the projected types.

use pin_project_lite::pin_project;
use std::pin::Pin;

pin_project! {
    // The `#[project]` (and `#[project_ref]`) attribute must precede the other attributes except for `#[doc]`:
    #[project = EnumProj] 
    #[project_ref = EnumProjRef]
    #[derive(Debug)]
    enum Enum<T, U> {
        Struct {
            #[pin]
            pinned: T,
            unpinned: U,
        },
        Unit,
    }
}

impl<T, U> Enum<T, U> {
    fn method(self: Pin<&mut Self>) {
        match self.project() {
            EnumProj::Struct { pinned, unpinned } => {
                let _: Pin<&mut T> = pinned;
                let _: &mut U = unpinned;
            }
            EnumProj::Unit => {}
        }
    }
}

Also, this does not provide support to tuple variants for the same reason that it does not support tuple structs.

@taiki-e taiki-e added C-enhancement Category: A new feature or an improvement for an existing one relnotes labels Sep 20, 2020
@taiki-e
Copy link
Owner Author

taiki-e commented Oct 1, 2020

I'm wondering what syntax is preferable, so I would appreciate any feedback.

@ghost
Copy link

ghost commented Oct 1, 2020

What if the attribute syntax was used, similar to the one in pin-project?

So perhaps something like #[project = EnumProj] above the enum definition.

@taiki-e
Copy link
Owner Author

taiki-e commented Oct 1, 2020

Ah, that looks like a good idea. There may be a limitation like #3, but I'll try it.

@taiki-e taiki-e force-pushed the enum branch 8 times, most recently from 3b9ec82 to 4eadb74 Compare October 1, 2020 13:56
@taiki-e
Copy link
Owner Author

taiki-e commented Oct 1, 2020

I've tried the attribute syntax and it looks good overall. (Thanks @stjepang for the suggestion!)

Limitations of the current implementation I know of are:

  • The #[project] (and #[project_ref]) attribute must precede the other attributes except for #[doc]:

    pin_project! {
        /// documents (`#[doc]`) can be placed before `#[project]`.
        #[derive(Clone)] // <--- Error
        #[project = EnumProj] 
        #[derive(Debug)] // <--- Ok
        enum Enum<T, U> {
            Struct {
                #[pin]
                pinned: T,
                unpinned: U,
            },
            Unit,
        }
    }

    This is probably impossible to fix, but I don't think it's too bad.

  • The diagnostics got worse. In most case, the error message is always "no rules expected the token [" 😅
    This seems to be caused by first parsing the option. This is bad, but it may be fixed in some way.

@ghost
Copy link

ghost commented Oct 1, 2020

It's okay if there are a few limitations with known workarounds. I think it's amazing that you managed to pull this off at all without procedural macros :)

@taiki-e taiki-e force-pushed the enum branch 3 times, most recently from 4d58c2f to 08fbe17 Compare October 4, 2020 01:11
@taiki-e taiki-e changed the title [wip] Enum support Enum support for pin_project! macro Oct 4, 2020
@taiki-e taiki-e force-pushed the enum branch 2 times, most recently from 6377bdb to bbd40ed Compare October 6, 2020 15:22
@taiki-e
Copy link
Owner Author

taiki-e commented Oct 6, 2020

I think the implementation is now basically complete, but I'll look into limitations and minor bugs before the merge.

@taiki-e
Copy link
Owner Author

taiki-e commented Oct 24, 2020

Filed #36 to track diagnostics issues. I'm okay with merge this.

bors r+

@bors
Copy link
Contributor

bors bot commented Oct 24, 2020

Build succeeded:

@bors bors bot merged commit fd18d9d into master Oct 24, 2020
@bors bors bot deleted the enum branch October 24, 2020 13:38
@taiki-e taiki-e mentioned this pull request Nov 8, 2020
@taiki-e taiki-e added breaking-change This proposes a breaking change and removed breaking-change This proposes a breaking change labels Nov 8, 2020
bors bot added a commit that referenced this pull request Nov 13, 2020
38: Release 0.2.0 r=taiki-e a=taiki-e

[Changes](https://github.com/taiki-e/pin-project-lite/blob/2d8bba1905bfc2da22a16c7e40703cd02d141916/CHANGELOG.md#020---2020-11-13)

#28 has made significant changes to the existing parsing and may cause some breakage, so bump minor version.

Co-authored-by: Taiki Endo <te316e89@gmail.com>
@taiki-e
Copy link
Owner Author

taiki-e commented Nov 13, 2020

Published in 0.2.0.

@taiki-e taiki-e removed the C-enhancement Category: A new feature or an improvement for an existing one label Jan 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant