-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking Issue for return type notation #109417
Comments
feature(return_type_notation)
)#![feature(return_type_notation)]
)
Limited syntactic support for experimental return type notations. rust-lang/rust#109417
Limited syntax support for return type notations (RTN) Experimental RTN bound support was recently merged into rustc (rust-lang/rust#109417), the goal of this PR is to allow experimentation without syntax errors everywhere. The parsing implemented currently aligns with the state of the tracking issue, it only supports the form `T<foo(..): Bounds>`. The parser always checks for the presence of `..` to disambiguate from `Fn*()` types, this is not ideal but I didn't want to spend too much time as it is an experimental feature.
hey Is there a way to use this the following way? #![feature(async_fn_in_trait)]
#![feature(return_type_notation)]
use std::future::Future;
trait Inner: Send + Sync {
async fn do_async(&self);
}
trait Outer {
type In: Inner<do_async(): Send>;
}
fn foo<T>(inner: T::In) -> impl Future + Send
where
T: Outer,
{
async move {
inner.do_async().await;
}
} |
#![feature(return_type_notation)]
)
somewhat related: we may want to change |
…estebank Change return-type-notation to use `(..)` Aligns the syntax with the current wording of [RFC 3654](rust-lang/rfcs#3654). Also implements rustfmt support (along with making a match exhaustive). Tracking: * rust-lang#109417
Rollup merge of rust-lang#127092 - compiler-errors:rtn-dots-redux, r=estebank Change return-type-notation to use `(..)` Aligns the syntax with the current wording of [RFC 3654](rust-lang/rfcs#3654). Also implements rustfmt support (along with making a match exhaustive). Tracking: * rust-lang#109417
…kh726 Implement Return Type Notation (RTN)'s path form in where clauses Implement return type notation (RTN) in path position for where clauses. We already had RTN in associated type position ([e.g.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=627a4fb8e2cb334863fbd08ed3722c09)), but per [the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#where-rtn-can-be-used-for-now): > As a standalone type, RTN can only be used as the Self type of a where-clause [...] Specifically, in order to enable code like: ```rust trait Foo { fn bar() -> impl Sized; } fn is_send(_: impl Send) {} fn test<T>() where T: Foo, T::bar(..): Send, { is_send(T::bar()); } ``` * In the resolver, when we see a `TyKind::Path` whose final segment is `GenericArgs::ParenthesizedElided` (i.e. `(..)`), resolve that path in the *value* namespace, since we're looking for a method. * When lowering where clauses in HIR lowering, we first try to intercept an RTN self type via `lower_ty_maybe_return_type_notation`. If we find an RTN type, we lower it manually in a way that respects its higher-ranked-ness (see below) and resolves to the corresponding RPITIT. Anywhere else, we'll emit the same "return type notation not allowed in this position yet" error we do when writing RTN in every other position. * In `resolve_bound_vars`, we add some special treatment for RTN types in where clauses. Specifically, we need to add new lifetime variables to our binders for the early- and late-bound vars we encounter on the method. This implements the higher-ranked desugaring [laid out in the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds). This PR also adds a bunch of tests, mostly negative ones (testing error messages). In a follow-up PR, I'm going to mark RTN as no longer incomplete, since this PR basically finishes the impl surface that we should initially stabilize, and the RFC was accepted. cc [RFC 3654](rust-lang/rfcs#3654) and rust-lang#109417
…kh726 Implement Return Type Notation (RTN)'s path form in where clauses Implement return type notation (RTN) in path position for where clauses. We already had RTN in associated type position ([e.g.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=627a4fb8e2cb334863fbd08ed3722c09)), but per [the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#where-rtn-can-be-used-for-now): > As a standalone type, RTN can only be used as the Self type of a where-clause [...] Specifically, in order to enable code like: ```rust trait Foo { fn bar() -> impl Sized; } fn is_send(_: impl Send) {} fn test<T>() where T: Foo, T::bar(..): Send, { is_send(T::bar()); } ``` * In the resolver, when we see a `TyKind::Path` whose final segment is `GenericArgs::ParenthesizedElided` (i.e. `(..)`), resolve that path in the *value* namespace, since we're looking for a method. * When lowering where clauses in HIR lowering, we first try to intercept an RTN self type via `lower_ty_maybe_return_type_notation`. If we find an RTN type, we lower it manually in a way that respects its higher-ranked-ness (see below) and resolves to the corresponding RPITIT. Anywhere else, we'll emit the same "return type notation not allowed in this position yet" error we do when writing RTN in every other position. * In `resolve_bound_vars`, we add some special treatment for RTN types in where clauses. Specifically, we need to add new lifetime variables to our binders for the early- and late-bound vars we encounter on the method. This implements the higher-ranked desugaring [laid out in the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds). This PR also adds a bunch of tests, mostly negative ones (testing error messages). In a follow-up PR, I'm going to mark RTN as no longer incomplete, since this PR basically finishes the impl surface that we should initially stabilize, and the RFC was accepted. cc [RFC 3654](rust-lang/rfcs#3654) and rust-lang#109417
Rollup merge of rust-lang#129629 - compiler-errors:rtn-in-path, r=jackh726 Implement Return Type Notation (RTN)'s path form in where clauses Implement return type notation (RTN) in path position for where clauses. We already had RTN in associated type position ([e.g.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=627a4fb8e2cb334863fbd08ed3722c09)), but per [the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#where-rtn-can-be-used-for-now): > As a standalone type, RTN can only be used as the Self type of a where-clause [...] Specifically, in order to enable code like: ```rust trait Foo { fn bar() -> impl Sized; } fn is_send(_: impl Send) {} fn test<T>() where T: Foo, T::bar(..): Send, { is_send(T::bar()); } ``` * In the resolver, when we see a `TyKind::Path` whose final segment is `GenericArgs::ParenthesizedElided` (i.e. `(..)`), resolve that path in the *value* namespace, since we're looking for a method. * When lowering where clauses in HIR lowering, we first try to intercept an RTN self type via `lower_ty_maybe_return_type_notation`. If we find an RTN type, we lower it manually in a way that respects its higher-ranked-ness (see below) and resolves to the corresponding RPITIT. Anywhere else, we'll emit the same "return type notation not allowed in this position yet" error we do when writing RTN in every other position. * In `resolve_bound_vars`, we add some special treatment for RTN types in where clauses. Specifically, we need to add new lifetime variables to our binders for the early- and late-bound vars we encounter on the method. This implements the higher-ranked desugaring [laid out in the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds). This PR also adds a bunch of tests, mostly negative ones (testing error messages). In a follow-up PR, I'm going to mark RTN as no longer incomplete, since this PR basically finishes the impl surface that we should initially stabilize, and the RFC was accepted. cc [RFC 3654](rust-lang/rfcs#3654) and rust-lang#109417
Implement Return Type Notation (RTN)'s path form in where clauses Implement return type notation (RTN) in path position for where clauses. We already had RTN in associated type position ([e.g.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=627a4fb8e2cb334863fbd08ed3722c09)), but per [the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#where-rtn-can-be-used-for-now): > As a standalone type, RTN can only be used as the Self type of a where-clause [...] Specifically, in order to enable code like: ```rust trait Foo { fn bar() -> impl Sized; } fn is_send(_: impl Send) {} fn test<T>() where T: Foo, T::bar(..): Send, { is_send(T::bar()); } ``` * In the resolver, when we see a `TyKind::Path` whose final segment is `GenericArgs::ParenthesizedElided` (i.e. `(..)`), resolve that path in the *value* namespace, since we're looking for a method. * When lowering where clauses in HIR lowering, we first try to intercept an RTN self type via `lower_ty_maybe_return_type_notation`. If we find an RTN type, we lower it manually in a way that respects its higher-ranked-ness (see below) and resolves to the corresponding RPITIT. Anywhere else, we'll emit the same "return type notation not allowed in this position yet" error we do when writing RTN in every other position. * In `resolve_bound_vars`, we add some special treatment for RTN types in where clauses. Specifically, we need to add new lifetime variables to our binders for the early- and late-bound vars we encounter on the method. This implements the higher-ranked desugaring [laid out in the RFC](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds). This PR also adds a bunch of tests, mostly negative ones (testing error messages). In a follow-up PR, I'm going to mark RTN as no longer incomplete, since this PR basically finishes the impl surface that we should initially stabilize, and the RFC was accepted. cc [RFC 3654](rust-lang/rfcs#3654) and rust-lang/rust#109417
This comment has been minimized.
This comment has been minimized.
The parentheses clearly indicates it's the eval result (output, return type) of the function, not the function itself. |
…=pnkfelix Robustify and genericize return-type-notation resolution in `resolve_bound_vars` rust-lang#129629 implemented return-type-notation (RTN) in its path form, like `where T::method(..): Bound`. As part of lowering, we must record the late-bound vars for the where clause introduced by the method (namely, its early- and late-bound lifetime arguments, since `where T::method(..)` turns into a higher-ranked where clause over all of the lifetimes according to [RFC 3654](https://rust-lang.github.io/rfcs/3654-return-type-notation.html#converting-to-higher-ranked-trait-bounds)). However, this logic was only looking at the where clauses of the parent item that the `T::method(..)` bound was written on, and not any parent items. This PR generalizes that logic to look at the parent item (i.e. the outer impl or trait) instead and fixes a (debug only) assertion as an effect. This logic is also more general and likely easier to adapt to more interesting (though likely very far off) cases like non-lifetime binder `for<T: Trait> T::method(..): Send` bounds. Tracking: - rust-lang#109417
I wonder if a more discoverable and comfortable syntax for this idea would be the An example then would be: trait SomeTrait {
async fn some_func()
}
impl<T> SomeStruct<T>
where
T: SomeTrait,
ReturnType<T::some_func>: SomeBound,
{
} I think it would be usable in all the same places as If we want to indicate these are not regular generic types, something like In some sense, generic instantiation is a function that takes types and produces types, and that's what the return type syntax is trying to do. The only difference is that the output is less complex than the input, which is usually not true for generics. (Originally I mistakenly commented this on the initial support issue before, my mistake) |
How would that look for dyn Trait (or impl Trait) like: I think |
I don't think bounds on associated types are supported in that way are they? In that situation I think you'd do a separate trait for use with dyn that is auto implemented and has the specified bounds. How is that resolved with the currently proposed syntax? |
Return type notation is definitely supported in associated type bound syntax. It's not allowed in dyn, but I expect it could be in the future. I don't think requiring a user to make a new trait (even if we had trait aliases) is an acceptable solution. I don't think that the proposed Secondly, the generic parameter it would take (e.g. Setting aside a totally different syntax for RTN is part of what makes it easier to implement and understand. It's distinct. Also, I don't really understand the parallel to |
I suppose my intention is to highlight that a type-system level construct for specifying the return type of a function type is an operation that belongs to class of type-manipulations which may make sense to anticipate growing in number. Expressing "the return type of a function type" has a very specific syntax right now that may make the addition of something like "the tuple type of arguments to a function type", or even more exotic things like "the tuple you get when you omit the first item" necessarily inconsistent from a syntax perspective. My suggestion is not that the proposed syntax is bad on its own, but that opting for a more general "function that operates on types" style syntax would be more extensible should those other extensions be added later. If the type system becomes more generally expressive, having a very application specific syntax for this feature may result in forced future language inconsistency. This syntax change suggestion could be implemented in an edition (I think?) should those other extensions be considered, so I'm probably bike-shedding here anyway. |
This is a tracking issue for the feature return type notation specified in rust-lang/rfcs#3654.
The feature gate for the issue is
#![feature(return_type_notation)]
.About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
where T::method(): Send
) Implement Return Type Notation (RTN)'s path form in where clauses #129629Unresolved questions
T::foo(..)
notation as a standalone type create a confusing inconsistency with-> ()
shorthand?Experimental results
Part of the goal of the experimental process is to identify benefits but also concerns that need to be addressed in the RFC.
typeof
syntax.Implementation history
The text was updated successfully, but these errors were encountered: