Repository navigation
Tracking issue for Fn traits (unboxed_closures & fn_traits feature) #29625
Copy link
Copy link
Open
Labels
B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.Blocker: Approved by a merged RFC and implemented but not stabilized.B-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-unboxed_closures`#![feature(unboxed_closures)]``#![feature(unboxed_closures)]`S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-langRelevant to the language teamRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Description
Tracks stabilization for the Fn* traits.
Random bugs:
-
FnOncedoesn't seem to support type-based dispatch (asAdd, etc. do) #45510 – type-based dispatch not working - Cannot call implementations of the
Fn*traits on references #42736 –foo()sugar doesn't work where you have&Foo: FnOnce
Reacted by Powersource, EFanZh, Dmitry Murzin, Antonio Dropulic, Stanislav Tkach, John Kugelman, tema3210, Thomas B, Ryo Ota, Gurwinder Singh and 90 more
Reacted by Felipe S. S. Schneider, Denis Kotlyarov, nyxtom, Dzenan Jupic, Andrew Hlynskyi, FlooferLand!, Luke, 9glenda, musjj, Kyle L. Davis and 5 more
Reacted by dzmitry-lahoda, Luke, Alex, Felipe S. S. Schneider, Rostyslav Lesovyi, nyxtom, Ming-Long Huang, Dzenan Jupic, Andrew Hlynskyi, Cameron Taggart and 12 more
Reacted by Felipe S. S. Schneider, Dzenan Jupic, Andrew Hlynskyi, FlooferLand!, 9glenda, musjj, Kyle L. Davis, Emilia Hane, Lee Benson, Jaanus Varus and 1 more
Reacted by Dzenan Jupic, Andrew Hlynskyi, FlooferLand!, Mahad, dbsx, LighghtEeloo, 9glenda, CGMossa, musjj, Kyle L. Davis and 7 more
Metadata
Metadata
Assignees
Labels
B-RFC-implementedBlocker: Approved by a merged RFC and implemented but not stabilized.Blocker: Approved by a merged RFC and implemented but not stabilized.B-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-unboxed_closures`#![feature(unboxed_closures)]``#![feature(unboxed_closures)]`S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-langRelevant to the language teamRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Activity
nagisa commentedon May 13, 2016
Inability to delegate calls to other FnOnce implementors like this:
is the reason I have a safety issue in libloading.
petrochenkov commentedon Jul 12, 2016
FnOnce::Outputis stabilized in #34365nrc commentedon Aug 17, 2016
Could someone summarise what is blocking stabilisation here please?
nagisa commentedon Aug 18, 2016
@nrc uncertainty about
Argsbeing the right thing given the possibility of variadic generics coming along around 2030 is the most major reason this is unstable.aturon commentedon Aug 27, 2016
@nrc also possibly some questions around the inheritance relationship, see #19032
brunoczim commentedon Jan 18, 2018
There should be a way of casting
fn(A) -> BtoFn(A) -> BSimonSapin commentedon Jan 18, 2018
@brunoczim That coercion already happens implicitly, but
Fn()as a type is a trait object so it needs to be behind some kind of pointer:Michael-F-Bryan commentedon Apr 2, 2018
One issue we've been discussing on TheDan64/inkwell#5 is the ability to mark something as
unsafeto use. What about having anUnsafeFnmarker trait which could be used to tell the compiler a callable isunsafeto call?For context,
inkwellis a wrapper around LLVM and we're trying to figure out how to return a function pointer to a JIT compiled function, when calling the function is fundamentallyunsafefor the same reasons FFI code isunsafeto call.CodeSandwich commentedon May 4, 2018
There is another reason to add
UnsafeFn: currentlyunsafe fns don't implementFn. There is no way to passunsafe fnas a function argument, they are second class citizen: example.UnsafeFncould be implemented for things implementingFn, soFns can be used whereverUnsafeFnis required. There probably also should beUnsafeFnMutandUnsafeFnOnce.alexreg commentedon Aug 20, 2018
@Michael-F-Bryan @CodeSandwich This sounds like something for which an RFC would really be appreciated. It probably wouldn't be an overly long or intricate one to write, even. I would support it, for sure, and judging by an issue I saw about this not long ago (a long-standing one), others would too.
63 remaining items
bjorn3 commentedon Dec 19, 2025
()is not a valid function name. And in any case we have three different traits. They need different method names to avoid ambiguity.EienMiku commentedon Dec 19, 2025
It is indeed illegal. But if modify the compiler to allow it, this would look better than the current syntax to me. Moreover, though we have multiple
Fn*traits, it seems that there might not be ambiguity, as it's unlikely that we would need to implement all of them for a struct.bjorn3 commentedon Dec 19, 2025
Implementing
Fnrequires implementingFnMutandFnOncetoo given that they are supertraits ofFn. If a subtrait and a supertrait have the same method name, I believe rustc doesn't allow calling the method currently for ambiguity reasons.madsmtm commentedon Dec 19, 2025
Also, doing special syntax for builtin operations isn't something that is done elsewhere, for example the
Addtrait has a method calledadd, not+.mikem8891 commentedon Jan 7, 2026
FnOnceandFnMutare supertraits ofFn, but I don't think they should be. I agree that everyFntrait needs to implementsFnMutandFnOnce, butFndoes not rely on anything special about how the other traits are implemented; therefore, they should not be prerequisites to implementingFn. In fact, it would be really annoying if they were implemented and any different than theFnimplementation. Instead, onlyFnshould be implemented and a trivial blanket implementation should be used to implementFnMutandFnOnce, see the example below. The example is theFn*traits using blanket implementations instead of supertraits.play with it (https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=cb845122a8404c17bac1d04a6bdfb20d)
bjorn3 commentedon Jan 7, 2026
I think that would be a breaking change by no longer allowing downcasting from
dyn Fn()todyn FnMut().fogti commentedon Jan 8, 2026
One could easy have both: There should be nothing that prevents one from requiring smth. as a supertrait, and still offering a blanket impl for the supertrait based upon the subtrait.
Perhaps beware of afaik resolution gotchas like #141807
Nekidev commentedon Mar 10, 2026
Is
Fn(A, B)vsFn<(A, B)>still a topic being discussed? I had quite some hard time getting in my head thatFn(A, B)is notFn<A, B>ratherFn<(A, B)>.jeffs commentedon Mar 10, 2026
@Nekidev Variadic generics aren't currently supported by the language, for a number of subtle reasons. See also rust-lang/lang-team#348.
peter-lyons-kehl commentedon Jun 15, 2026
Timeline for variadic generics: Based on how long
constgenerics, and generic associated types, took, is it not likely that this would take many years? Plus complications/interactions that we don't know about yet (with the new trait solver, or anything else new in the compiler).EDIT: Sorry, the below doesn't work (that is, it does compile with two
implthat we want to conflict). I'll investigate more.EDIT again: See the following comment for an example.
@fogti Do you mean when
Argsdepends on any generic argument(s) of the object for whichFn*is implemented? Solution is below.@bjorn3 (If I understand right, and as mentioned by others earlier), we can prevent multiple call signatures by changing
Argsto be an associative type. BUT, this associative type doesn't have to be inFn*traits (as we know them) - it could be in a parent trait(s), whose only purpose is to prevent the multiple call signatures. I believe the following should continue to work for Higher-Ranked Trait Bounds. So all current internal/nightly code could continue to work.EDIT: Sorry, the below doesn't work (that is, it does compile with two
implthat we want to conflict). I'll investigate more.EDIT again: See the following comment for an example.
Side note: I'm surprised that the first blanket impl (commented out) in the above example actually compiles. Is it likely to continue to compile with the next trait solver?
peter-lyons-kehl commentedon Jun 15, 2026
The following prevents multiple signatures/multiple
implofFnOnce/FnMut/Fnfor the same type, while keepingArgsas a generic parameter, hence supporting higher rank trait bounds.This adds an associative type
Args, but not inFnOnce/FnMut/Fntraits, because their generic instantiations are separate and having an associative type in them would not prevent multiple signatures/implementations. So the associative type needs a new trait (a parent trait, or a side kick trait; calledFnBase, orFnPreventMultipleSignaturesor similar).It's not ideal, because you need to implement one more trait. But we already have three traits, and this new one is tiny.
That does involve duplication of
ArgsFnOnce/FnMut/Fn, andFnBase.Unfortunately, I don't see a way to have blanket
implforFnBasefor any type that implementsFnOnce.Nadrieril commentedon Jun 15, 2026
Hi all, tracking issues are normally reserved for updates about the development of a feature. To discuss the feature and/or propose extensions, the appropriate venues are the internals forum, Zulip, the RFC PR if it's still open (which isn't the case here), or writing your own RFC.
If you open a relevant Zulip/Internals topic, do post it here so that interested people can come and discuss with you over there.
peter-lyons-kehl commentedon Jun 16, 2026
Please discuss at https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Fn.20traits.20.28unboxed_closures.20.26.20fn_traits.20feature.29.