rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

GAT support

Open flodiebold opened this issue 2 years ago • 8 comments

Since generic associated types are on their way to stabilization, we'll need to start looking into implementing them :sweat_smile:

flodiebold avatar Jul 22 '21 08:07 flodiebold

#9602 was a step on the way there. I haven't run into other issues where they fail to parse since then, but I imagine more information can be modeled around them for refactoring and introspection.

Dessix avatar Jul 23 '21 01:07 Dessix

// I'm not sure if here is the proper place to ask about this though, One thing I'm suffered by is similar to #9602 but its rustfmt side support. rustfmt has already merged a PL to support GAT in associated type constraints, though rustfmt version is not bumped since February so the code is not yet in the released version. Is there a way to specify a certain rustfmt git commit version to use in rust-analyzer?

wada314 avatar Jul 23 '21 10:07 wada314

@wada314 we run the installed rustfmt, but you can override the command to e.g. cargo +nightly rustfmt or gat-rustfmt if that works.

lnicola avatar Jul 23 '21 10:07 lnicola

Thanks for the info! I was thinking the change is already merged into rustfmt, but actually I couldn't trigger that feature so I'm asking at their issue thread about how to use the feature.

wada314 avatar Jul 23 '21 12:07 wada314

Even in the nightly, I think rustfmt is only updated periodically and testing on play.rust-lang.org shows that it's still mangling GATs.

But you can also build your own rustfmt from source, it's easier than I expected.

lnicola avatar Jul 23 '21 13:07 lnicola

I think I'm missing some command-line config parameters to use the feature... I cloned the repository by myself and added a testcase for handling GAT in constraints, but it didn't work. I posted on their thread so I wait for the response, thanks!

wada314 avatar Jul 23 '21 13:07 wada314

Yeah, it doesn't work for me either.

lnicola avatar Jul 23 '21 13:07 lnicola

Before opening a new issue I stumbled across this one. I think my problem is either the same or related.

I'm experimenting with generic_associated_types and (min_)type_alias_impl_trait and found a few issues with type deduction. Try the following example:

    pub trait SomeTrait {
        type ResultFut: Future<Output = String>;
        type ResultWithGatFut<'a, T: 'a>: Future<Output = String> + 'a;
        fn do_it_type_alias_impl_trait(&self) -> Self::ResultFut;
        fn do_it_boxed(&self) -> Pin<Box<dyn Future<Output = String>>>;
        fn do_gat<'a, T: 'a>(&'a self, p: T) -> Self::ResultWithGatFut<'a, T>;
    }

    pub struct Impl {}

    impl SomeTrait for Impl {
        type ResultFut = impl Future<Output = String>;
        type ResultWithGatFut<'a, T: 'a> = impl Future<Output = String> + 'a;

        fn do_it_type_alias_impl_trait(&self) -> Self::ResultFut {
            async { "test".to_owned() }
        }
        fn do_it_boxed(&self) -> Pin<Box<dyn Future<Output = String>>> {
            Box::pin(async { "test".to_owned() })
        }
        fn do_gat<'a, T: 'a>(&'a self, _p: T) -> Self::ResultWithGatFut<'a, T> {
            async { "test".to_owned() }
        }
    }

    fn make_impl() -> impl SomeTrait {
        Impl {}
    }

    async fn do_it_generic<T: SomeTrait>(p: &T) {
        // correct: <T as SomeTrait>::ResultFut
        let fut = p.do_it_type_alias_impl_trait();
        // correct: String
        let _res = fut.await;
        // correct: Pin<Box<dyn Future<Output = ...>>>
        let fut = p.do_it_boxed();
        // correct: String
        let _res = fut.await;
        // INCORRECT: no type info whatsoever, no code completion
        let fut = p.do_gat(33);
        // INCORRECT: no type info whatsoever, no code completion
        let _res = fut.await;
    }

    async fn do_it_concrete(p: &Impl) {
        // INCORRECT: no type info whatsoever, no code completion
        let fut = p.do_it_type_alias_impl_trait();
        // INCORRECT: no type info whatsoever, no code completion
        let _res = fut.await;
        // correct: Pin<Box<dyn Future<Output = ...>>>
        let fut = p.do_it_boxed();
        // correct: String
        let _res = fut.await;
        // INCORRECT: no type info whatsoever, no code completion
        let fut = p.do_gat(33);
        // INCORRECT: no type info whatsoever, no code completion
        let _res = fut.await;
    }

    async fn do_it_impl_arg(p: impl SomeTrait) {
        // correct: <impl SomeTrait as SomeTrait>::ResultFut; but could be shortened to impl SomeTrait::ResultFut
        let fut = p.do_it_type_alias_impl_trait();
        // correct: String
        let _res = fut.await;
        // correct: Pin<Box<dyn Future<Output = ...>>>
        let fut = p.do_it_boxed();
        // correct: String
        let _res = fut.await;
        // INCORRECT: no type info whatsoever, no code completion
        let fut = p.do_gat(33);
        // INCORRECT: no type info whatsoever, no code completion
        let _res = fut.await;
    }

    async fn do_it_impl_local_variable() {
        let p = make_impl();
        // correct: <impl SomeTrait as SomeTrait>::ResultFut; but could be shortened to impl SomeTrait::ResultFut
        let fut = p.do_it_type_alias_impl_trait();
        // INCORRECT: <<impl SomeTrait as SomeTrait>::ResultFut as Future>::Output -- no type completion
        let _res = fut.await;
        // correct: Pin<Box<dyn Future<Output = ...>>>
        let fut = p.do_it_boxed();
        // correct: String
        let _res = fut.await;
        // INCORRECT: no type info whatsoever, no code completion
        let fut = p.do_gat(33);
        // INCORRECT: no type info whatsoever, no code completion
        let _res = fut.await;
    }

Depending on how the trait/concrete type is accessed, type hints and code completion works or not, as described in the comments (they show what rust-analyzer returns). If a type (as opposed to a lifetime) is passed as a generic to an associated trait type, then type deduction fails completely.

I hope this helps to analyze & fix the issue quickly. Thanks in advance.

schreter avatar Oct 12 '21 20:10 schreter