-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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 function delegation (fn_delegation
, RFC 3530)
#118212
Comments
cc @Bryanskiy |
Delegation implementation: step 1 See rust-lang#118212 for more details. r? `@petrochenkov`
…ov,lcnr Delegation implementation: step 1 See rust-lang#118212 for more details. r? `@petrochenkov`
…,lcnr Delegation implementation: step 1 See rust-lang#118212 for more details. r? `@petrochenkov`
…,lcnr Delegation implementation: step 1 See rust-lang#118212 for more details. r? `@petrochenkov`
…,lcnr Delegation implementation: step 1 See rust-lang#118212 for more details. r? `@petrochenkov`
Delegation implementation: step 1 See rust-lang/rust#118212 for more details. r? `@petrochenkov`
Delegation implementation: step 1 See rust-lang/rust#118212 for more details. r? `@petrochenkov`
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions Also allow delegating to functions with opaque types (`impl Trait`). The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior. (Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.) Part of rust-lang#118212.
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions Also allow delegating to functions with opaque types (`impl Trait`). The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior. (Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.) Part of rust-lang#118212.
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions Also allow delegating to functions with opaque types (`impl Trait`). The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior. (Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.) Part of rust-lang#118212.
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions Also allow delegating to functions with opaque types (`impl Trait`). The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior. (Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.) Part of rust-lang/rust#118212.
delegation: Support renaming, and async, const, extern "ABI" and C-variadic functions Also allow delegating to functions with opaque types (`impl Trait`). The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created, which seems like a reasonable behavior. (Such delegation items will cause query cycles when used in trait impls, but it can be fixed later.) Part of rust-lang/rust#118212.
delegation: Implement list delegation ```rust reuse prefix::{a, b, c}; ``` Using design described in rust-lang/rfcs#3530 (comment) (the lists are desugared at macro expansion time). List delegations are expanded eagerly when encountered, similarly to `#[cfg]`s, and not enqueued for later resolution/expansion like regular macros or glob delegation (rust-lang#124135). Part of rust-lang#118212.
I was looking through the code of the experimental implementation today (#117978), and I found something that surprised me. The experimental implementation of delegation has an id in it: However, a Delegation is used as an ItemKind, and any ItemKind is associated with an Item. Now every Item already has an ID associated with it: I looked through all the code, and I think for delegation the Item id is never used, and the Delegation specific one is always used but seems redundant. Let me know if I'm misunderstanding something here, maybe I am, but I just wanted to let you know in case it's redundant. |
trait Trait { fn method(); }
impl Trait for Struct {
reuse some::method;
} the same The |
I'll update the list of subtasks in the issue a bit later, but for now I'll just post one of them for @Bryanskiy . Suppose we want to delegate implementation of a whole trait with 10 methods, 5 of them are by ref and 5 are by mutable ref. struct Wrapper(Inner);
impl Trait for Wrapper {
fn ref1() { Trait::ref1(&self.0) }
fn ref2() { Trait::ref2(&self.0) }
fn ref3() { Trait::ref3(&self.0) }
fn ref4() { Trait::ref4(&self.0) }
fn ref5() { Trait::ref5(&self.0) }
fn mut1() { Trait::mut1(&mut self.0) }
fn mut2() { Trait::mut2(&mut self.0) }
fn mut3() { Trait::mut3(&mut self.0) }
fn mut4() { Trait::mut4(&mut self.0) }
fn mut5() { Trait::mut5(&mut self.0) }
} Right now we cannot do it using glob delegation and an explicit path, due to the difference between impl Trait for Wrapper {
reuse Trait::* { &self.0 }
reuse Trait::{mut1, mut2, mut3, mut4, mut5} { &mut self.0 }
} Ideally we would use just impl Trait for Wrapper {
reuse Trait::* { self.0 }
} and For that in the generated body (This was mentioned in the RFC in application to a different case - https://github.com/petrochenkov/rfcs/blob/delegation/text/0000-fn-delegation.md#the-proposed-algorithm.) |
@petrochenkov that makes sense. Would you like it if I gave it a comment or a slightly more descriptive name? |
The separate table approach may actually be a better way. |
delegation: Implement glob delegation Support delegating to all trait methods in one go. Overriding globs with explicit definitions is also supported. The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in rust-lang#123413 we cannot expand glob delegation eagerly. We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob. Glob delegation is only allowed in impls, and can only point to traits. Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity. Part of rust-lang#118212.
delegation: Implement glob delegation Support delegating to all trait methods in one go. Overriding globs with explicit definitions is also supported. The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in rust-lang#123413 we cannot expand glob delegation eagerly. We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob. Glob delegation is only allowed in impls, and can only point to traits. Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity. Part of rust-lang#118212.
Rollup merge of rust-lang#124135 - petrochenkov:deleglob, r=fmease delegation: Implement glob delegation Support delegating to all trait methods in one go. Overriding globs with explicit definitions is also supported. The implementation is generally based on the design from rust-lang/rfcs#3530 (comment), but unlike with list delegation in rust-lang#123413 we cannot expand glob delegation eagerly. We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob. Glob delegation is only allowed in impls, and can only point to traits. Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity. Part of rust-lang#118212.
…etrochenkov Delegation: support coercion for target expression (solves rust-lang#118212 (comment)) The implementation consist of 3 parts. Firstly, method call is generated instead of fully qualified call in AST->HIR lowering if there were no generic arguments or `Qpath` were provided. These restrictions are imposed due to the loss of information after desugaring. For example in ```rust trait Trait { fn foo(&self) {} } reuse <u8 as Trait>::foo; ``` We would like to generate such a code: ```rust fn foo<u8: Trait>(x: &u8) { x.foo(x) } ``` however, the signature is inherited during HIR analysis where `u8` was discarded. Secondly, traits found in the callee path are also added to `trait_map`. This is done to avoid the side effects of converting body into method calls: ```rust mod inner { pub trait Trait { fn foo(&self) {} } } reuse inner::Trait::foo; // Ok, `Trait` is in scope for implicit method call. ``` Finally, applicable candidates are filtered with pre-resolved method during method lookup. P.S In the future, we would like to avoid restrictions on the callee path by `Self` autoref/autoderef in fully qualified calls, but at the moment it didn't work out. r? `@petrochenkov`
…ompiler-errors Delegation: support coercion for target expression (solves rust-lang#118212 (comment)) The implementation consist of 2 parts. Firstly, method call is generated instead of fully qualified call in AST->HIR lowering if there were no generic arguments or `Qpath` were provided. These restrictions are imposed due to the loss of information after desugaring. For example in ```rust trait Trait { fn foo(&self) {} } reuse <u8 as Trait>::foo; ``` We would like to generate such a code: ```rust fn foo<u8: Trait>(x: &u8) { x.foo(x) } ``` however, the signature is inherited during HIR analysis where `u8` was discarded. Then, we probe the single pre-resolved method. P.S In the future, we would like to avoid restrictions on the callee path by `Self` autoref/autoderef in fully qualified calls, but at the moment it didn't work out. r? `@petrochenkov`
Rollup merge of rust-lang#126699 - Bryanskiy:delegation-coercion, r=compiler-errors Delegation: support coercion for target expression (solves rust-lang#118212 (comment)) The implementation consist of 2 parts. Firstly, method call is generated instead of fully qualified call in AST->HIR lowering if there were no generic arguments or `Qpath` were provided. These restrictions are imposed due to the loss of information after desugaring. For example in ```rust trait Trait { fn foo(&self) {} } reuse <u8 as Trait>::foo; ``` We would like to generate such a code: ```rust fn foo<u8: Trait>(x: &u8) { x.foo(x) } ``` however, the signature is inherited during HIR analysis where `u8` was discarded. Then, we probe the single pre-resolved method. P.S In the future, we would like to avoid restrictions on the callee path by `Self` autoref/autoderef in fully qualified calls, but at the moment it didn't work out. r? `@petrochenkov`
This is a tracking issue for the RFC "Implement function delegation in rustc" (rust-lang/rfcs#3530).
The feature gate for the issue is
#![feature(fn_delegation)]
.The feature was accepted for experimentation in #117978 (comment).
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
const
,extern
,async
#[inline]
unless specified otherwiseSelf
type mapping (in RFC)impl Trait
in traitsUnresolved Questions
Many of them in the RFC draft.
Implementation history
https://github.com/rust-lang/rust/pulls?q=is%3Apr+label%3AF-fn_delegation
The text was updated successfully, but these errors were encountered: