Impl Trait Everywhere Initiative
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: ITE meeting 2023-10-31 tags: impl-trait-everywhere, triage-meeting, minutes date: 2023-10-31 discussion: https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/ITE.20triage.20meeting.202023-10-31 url: https://hackmd.io/mHmsSToOSkCFP5cOezFScw --- # ITE meeting agenda - Meeting date: 2023-10-31 ## Attendance - People: TC, CE, tmandry ## Meeting roles - Minutes: TC ## Resolving #107645 ### Proposal on nested inner function restriction In the meeting yesterday, we agreed that we would all prefer to remove the restriction on defining an opaque type in a nested inner function. The new T-types restrictions make the effect of this restriction much more severe. However, T-lang reached a consensus that included this restriction, and the attempt to revise out this restriction in the 2023-06-27 T-lang triage meeting was unsuccessful. What do we do about that? *Proposal:* We resolve the concern on [#107645][] to allow the many other parts of that consensus to proceed. Then we address removing the restriction on nested inner functions as part of the T-types proposal. It makes sense to include it here as the restrictions added by T-types makes the other restriction arguably untenable. *Alternate proposal:* If, for any reason, we want to break this out from the rest of the T-types proposal, the thing to do would be to still resolve the concern on [#107645][], then open a new issue that seeks to overturn this one aspect of the earlier consensus. We would describe in that new issue how the T-types proposal affects this restriction, and we would provide analysis of the potential impact (or lack thereof) on tooling. *Consensus*: The inner function restriction from [#107645][] needs to be revised due to the new T-types restrictions. We'll resolve the [#107645][] concern about this and address it as part of the design meeting discussion for the T-types proposal. #### Motivation People write code like this: ```rust #![feature(type_alias_impl_trait)] use core::future::Future; type FooRet = impl Future<Output = String>; fn foo<T: AsRef<str>>(x: T) -> FooRet { let x = x.as_ref().to_string(); // This actually doesn't work due to #65442. async move { x } } ``` To reduced the size of the generated code due to generics (and also due to [#65442][] in this case), people idiomatically rewrite that as: ```rust #![feature(type_alias_impl_trait)] use core::future::Future; type FooRet = impl Future<Output = String>; fn foo<T: AsRef<str>>(x: T) -> FooRet { fn inner(x: &str) -> FooRet { let x = x.to_string(); async move { x } } inner(x.as_ref()) } ``` But with the T-types restrictions, this does not work, because the outer `foo` function names the opaque type within the defining scope but is not defining. [#65442]: https://github.com/rust-lang/rust/issues/65442 ### Signature restriction allows ADTs Discussion yesterday: https://hackmd.io/TsRfxTpfQGKy_zXcQm8KDA Threads of discussion: - Is this issue separable from the defines question? - If so, assuming we settle the defines question, have we settled this question? *Consensus*: Due to the T-types proposal, a decision has to be made and committed to here, as the specific rules are being relied on and cannot be changed in a backward compatible manner. In that context, and if we choose to do the signature restriction, then it would be too annoying to not allow ADTs containing the opaque type to pass the signature restriction. We'll drop this concern on [#107645][] where this rule was part of that consensus and FCP. #### Motivation 1: Constructors ```rust #![feature(type_alias_impl_trait)] use core::future::Future; type JobFut = impl Future<Output = u64>; struct Job { id: u64, fut: JobFut, } impl Job { fn new(id: u64) -> Self { Job { id: id, fut: async move { id } } } } ``` #### Motivation 2: Builder pattern ```rust #![feature(type_alias_impl_trait)] use core::future::Future; type JobFut = impl Future<Output = u64>; struct Job { id: u64, fut: JobFut, } struct JobBuilder { id: Option<u64>, n_iters: Option<u64>, } impl JobBuilder { const fn new() -> Self { Self { id: None, n_iters: None } } fn id(&mut self, id: u64) { self.id = Some(id); } fn n_iters(&mut self, iters: u64) { self.n_iters = Some(iters); } fn build(self) -> Job { let id = self.id.unwrap(); let n_iters = self.n_iters.unwrap(); Job { id, fut: async move { let mut x: u64 = 1; for _ in 0..n_iters { x *= 3; x -= 1; } x }, } } } ``` #### Motivation 3: Making the human into a compiler As the code becomes more realistic and more complicated, it becomes more difficult to refactor the code such that the type alias can be named directly in the signature, as it requires moving all captured things into named input arguments to one or more functions. This process may itself require introducing new named opaque types that would not otherwise be necessary. Those opaque types themselves may then need special handling to ensure they can be defined appropriately. This process can continue recursively. This argument was touched on earlier in the section ["Making the human into a compiler"](https://hackmd.io/oTC4J-2XRnukxC7lSq_PVA#Making-the-human-into-a-compiler). Essentially, such a rule would require the human to compile many uses of the feature down to *basic blocks*, manually. ### From the T-types meeting: Proposal :zero: (preferred) - Forever: - A function must have the TAIT (or a type that contains it) in the signature. - or some defines syntax in the future - For now (we never expect to relax): - TAITs can only be defined once modulo regions. - For now (can be relaxed later): - A function that mentions the TAIT (or a type that contains it) in the signature, it must define it. - Because of lazy norm and how the new trait solver is more complete, this is an area of difference between the old and new solver. It would be easy to break things here. And the old trait solver is underspecified here. (Oli: It is fixable in the old solver.) So we're saving space here. - [*May remove this now*:] Only one function in the defining scope can mention the TAIT (or a type that contains it) in the signature. - Can create a dedicated diagnostic for this case, avoiding all cycle errors and other hard to diagnose issues for users. - This is the most arbitrary. We have the machinery to allow this. But it prevents people from writing functions that are passthrough. It allows us to write earlier and better diagnostics. But this is an artificial restriction we could lift easily. We could put this behind a separate feature gate. - [*May remove this now by making it just work*:] Error if projection in signature (except one from the same impl, ITIAT/ATPIT) inside the defining scope normalizes to include a TAIT. - Saves space for making opaque_types_defined_by query smarter. - Properties: - All cycle errors are *real* cycle errors in the new solver. - Changes that allow more items to define the TAIT to the signature rule would be breaking changes. ### Continuations on signature restriction / defines syntax *Consensus*: Since the option of an explicit `defines` syntax was not discussed in the last T-lang design meeting on TAIT, we want to ensure it is mentioned in the next meeting. We will include it in the design document for the next meeting along with a discussion of the practical problems that would follow from choosing that option, including how it may impact the timeline for stabilizing the new 2024 lifetime capture rules in the new edition. We may leave a comment on the TAIT tracking issue noting that we want to be sure this is raised for discussion. #### Option 0: Signature restriction - Implemented today. - Least verbose and least noisy for common cases. - Strict subset of RFC behavior with no new syntax. - Most symmetric with `dyn Trait`. - Fewest open implementation or design questions. - Second-most forward compatible option. - Forward compatible with: - Option 1: Signature restriction + defines outside of defining scope - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 4: Signature restriction + optional defines in defining scope - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Backward compatible with: - Option 6: Signature restriction + mandatory defines in defining scope #### Option 1: Signature restriction + defines outside of defining scope - We can add this later. - Putting TAITs into submodule then results in the same experience as defines-only proposals (i.e. Option 9). - For this and all other defines options, we'd need to work out syntax. - There are implementation concerns with using an attribute; name resolution doesn't happen inside of attributes. - Using an attribute may be inconsistent with the decision in [#41619][]. - The tracking issue for RFC 1868 "A portability lint" completed FCP disposition close on the basis that T-lang wanted to go in the direction of using `where` clauses to express "capabilities" rather than using an attribute-based solution. For `defines`, what we're talking about is the *capability* of defining the hidden type, so there may be design and conceptual similarity here. - There are open questions on the handling of generic parameters. - If we look through normalization, the generic parameters matter. - If we don't, we're closing doors. - We have to think about the effect on `impl Trait` everywhere also. - Forward compatible with: - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Backward compatible with: - Option 0: Signature restriction - Option 6: Signature restriction + mandatory defines in defining scope - Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope E.g.: ```rust #![feature(type_alias_impl_trait)] #![feature(todo_define_tait_anywhere_in_crate)] use taits::*; mod taits { type Tait<T> = impl Sized; } fn define<T>() where constrains(Tait<T>) {} ``` [#41619]: https://github.com/rust-lang/rust/issues/41619 #### Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Forward compatible with: - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Backward compatible with: - Option 0: Signature restriction - Option 1: Signature restriction + defines outside of defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 4: Signature restriction + optional defines in defining scope - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Option 6: Signature restriction + mandatory defines in defining scope - Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope #### Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Forward compatible with: - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Backward compatible with: - Option 0: Signature restriction - Option 1: Signature restriction + defines outside of defining scope - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 4: Signature restriction + optional defines in defining scope - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Option 6: Signature restriction + mandatory defines in defining scope - Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope #### Option 4: Signature restriction + optional defines in defining scope - Forward compatible with: - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Backward compatible with: - Option 0: Signature restriction - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Option 6: Signature restriction + mandatory defines in defining scope One could actually define this as a proc macro on top of Option 1. E.g.: ```rust #[defines(Foo)] fn foo() { let _: Foo = (); } // ----------------------------------------- fn foo() where Foo: Any { let _: Foo = (); } ``` #### Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Forward compatible with: - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 4: Signature restriction + optional defines in defining scope - Backward compatible with: - Option 0: Signature restriction - Option 4: Signature restriction + optional defines in defining scope - Option 6: Signature restriction + mandatory defines in defining scope #### Option 6: Signature restriction + mandatory defines in defining scope - Maximum forward compatibility. - Maximum annoyance. - Forward compatible with: - Option 0: Signature restriction - Option 1: Signature restriction + defines outside of defining scope - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 4: Signature restriction + optional defines in defining scope - Option 5: Signature restriction + optional defines in defining scope + lint for absent defines - Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope - Option 8: Defines in defining scope - Option 9: Defines in defining scope + defines outside of defining scope - Backward compatible with: - (None) #### Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope - Forward compatible with: - Option 1: Signature restriction + defines outside of defining scope - Option 2: Signature restriction + defines outside of defining scope + optional defines in defining scope - Option 3: Signature restriction + defines outside of defining scope + optional defines in defining scope + lint for absent defines - Option 9: Defines in defining scope + defines outside of defining scope - Backward compatible with: - Option 6: Signature restriction + mandatory defines in defining scope #### Option 8: Defines in defining scope - Closes door on signature restriction options. - Not a struct subset of the RFC behavior. - Some people like the module-scoped behavior in the RFCs; we'd have to build a new consensus against this. - Forward compatible with: - Option 9: Defines in defining scope + defines outside of defining scope - Backward compatible with: - Option 6: Signature restriction + mandatory defines in defining scope #### Option 9: Defines in defining scope + defines outside of defining scope - Forward compatible with: - (None) - Backward compatible with: - Option 6: Signature restriction + mandatory defines in defining scope - Option 7: Signature restriction + mandatory defines in defining scope + defines outside of defining scope - Option 8: Defines in defining scope #### Bonus option: RTN everywhere Rather than (or in addition to) doing any of the above, we could finalize a design of RTN and extend it to type position. We would need it to support specifying generic arguments to achieve the correct quantification. #### Option matrix ```mermaid flowchart TB subgraph DefinesOnly["Defines Only"] O8["Option 8\n\nDefines in defining scope"] O9["Option 9\n\nDefines in defining scope\n+ defines outside of defining scope"] end subgraph BothRequired["Both Required"] O6["Option 6\n\nSignature restriction\n+ mandatory defines in defining scope"] O7["Option 7\n\nSignature restriction\n+ mandatory defines in defining scope\n+ defines outside of defining scope"] end subgraph SignatureRestriction["Signature Restriction"] subgraph DefinesOutside["Defines Outside of Defining Scope"] O1["Option 1\n\nSignature restriction\n+ defines outside of defining scope"] O2["Option 2\n\nSignature restriction\n+ defines outside of defining scope\n+ optional defines in defining scope"] O3["Option 3\n\nSignature restriction\n+ defines outside of defining scope\n+ optional defines in defining scope\n+ lint for absent defines"] style O3 stroke:#fff000 end O0["Option 0\n\nSignature restriction"] O4["Option 4\n\nSignature restriction\n+ optional defines in defining scope"] O5["Option 5\n\nSignature restriction\n+ optional defines in defining scope\n+ lint for absent defines"] style O5 stroke:#fff000 end O0 --> O1 O0 --> O2 O0 --> O3 O0 --> O4 O0 --> O5 O1 --> O2 O1 --> O3 O2 <--> O3 O4 --> O2 O4 --> O3 O4 <--> O5 O5 --> O2 O5 --> O3 O6 --> O0 O6 --> O1 O6 --> O2 O6 --> O3 O6 --> O4 O6 --> O5 O6 --> O7 O6 --> O8 O6 --> O9 O7 --> O1 O7 --> O2 O7 --> O3 O7 --> O9 O8 --> O9 ``` [(Better rendering)](https://mermaid.live/view#pako:eNq9VcFuozAQ_ZWR97itBARCElU9VLkjNb2t9-DCkFgFO2uMqqjqv9cGwrBqu1Tbqrc34zdvnmcseGK5LpBtgJWVfswPwli4u-GKq6a93xtxPMAWS6mwyVR1-sXZEIEPOfvNVbZy2exopVaw4q6SqzNHKig8lGoPTa6P2BesqWA9V8DVzz7lTnVrG1kg6PItWVTFX7ZvtD3c4p9WGixcQx_COe59LMnHsvexk3slbGsQDDbWyNwfdh5qoQphtTmNbt65XEqi6VeI_v8Axr631NaZIzuTfCfAFcCrrfctp4snE9uzid1oAiALaQLh3AQ-djMnGpFo9HlRz9KdmqhmFup6L6j34tt6e1ollYVSGxD3DTo4sAdfjT1V6Nw5YPQDbn6UZRkEgT8ankIWkPPgX867lxsTOZ675geHlyWkmXyB5txQhpEkr0YyDgQuL6_dEyUYEVwQjAkmXWFI7HBkuyCCq0kUEysmzXjg9EoJcZKp0rIPAoIhwYjggmBMMCGYElwRXHdNUlJOSTkl5XTKXo0BuwBWo6mFLPy_4okze8DaLXkDnBXCPHD27DmitXp3UrnLl6Jq0KXao_vG4VYK912pz_nnF1xPNbE) ## References - [2023-10-31 Attempt to resolve #107645](https://hackmd.io/mHmsSToOSkCFP5cOezFScw) (this document) - [2023-10-30 Attempt to resolve #107645](https://hackmd.io/TsRfxTpfQGKy_zXcQm8KDA) - [2023-10-26 Description of T-types proposal](https://hackmd.io/qiy4_I3WRYyhpYvjbYBrew) - [2023-10-19 Prevent opaque types being instantiated twice with different regions within the same function - #116935](https://github.com/rust-lang/rust/pull/116935) - [2023-10-16 Normalize when collecting TAITs in signature - #116819](https://github.com/rust-lang/rust/pull/116819) - [2023-10-11 T-types TAIT session minutes](https://hackmd.io/QOsEaEJtQK-XDS_xN4UyQA) - [2023-09-13 RPITIT stabilization - #115822](https://github.com/rust-lang/rust/pull/115822) - [2023-07-26 RFC 3498 - Lifetime capture rules 2024](https://github.com/rust-lang/rfcs/pull/3498) ([design meeting](https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ)) ([discussion](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/design.20meeting.202023-07-26)) - [2023-07-11 T-lang triage diffs on TAIT](https://hackmd.io/_eMqgF3JQgGEN4Y6C9C1pg#Diffs-on-TAIT-TC) - [2023-06-29 TAIT must be constrained if in signature PR](https://github.com/rust-lang/rust/pull/113169) - [2023-06-29 Oli/lcnr meeting on TAIT](https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/lcnr.20oli.20meeting/near/370710606) - [2023-06-29 TAIT mini-design meeting](https://hackmd.io/r1oqcjrzTAK5e_T1IOXeXg) ([discussion](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/TAIT.20mini-design.20meeting.202023-06-29)) - [2023-06-27 T-lang triage atempt to revise nested inner functions restriction](https://hackmd.io/hTUmwMrbSSqN1eU2k90Iwg#TAIT-nested-inner-functions-restriction-take-2-TC) - [2023-06-13 TAIT tracking issue proposed stabilization FCP canceled](https://github.com/rust-lang/rust/issues/63063#issuecomment-1588994092) - [2023-06-12 T-types TAIT in new trait solver document](https://hackmd.io/llGcGMR7SvCP1C1MulcDQw) ([discussion](https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2023-06-12.20TAIT.20in.20new.20solver/near/365570768)) - [2023-06-06 lcnr resolves concern about allowing WCs in signature restriction](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/design.20meeting.202023-05-31.20TAITs/near/363984835) - [2023-06-01 TAIT defining scope options proposed FCP](https://github.com/rust-lang/rust/issues/107645#issuecomment-1571789814) - [2023-05-31 T-lang TAIT design meeting](https://hackmd.io/IVFExd28TZWm6iyNIq66PA) ([discussion](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/design.20meeting.202023-05-31.20TAITs)) - [2023-05-31 TAIT draft stabilization report](https://hackmd.io/oTC4J-2XRnukxC7lSq_PVA) (not updated with T-types proposal) - [2023-03-20 lcnr update on new trait solver concern](https://github.com/rust-lang/rust/issues/63063#issuecomment-1476196975) - [2023-02-06 lcnr concern over new trait solver](https://github.com/rust-lang/rust/issues/63063#issuecomment-1418741032) - [2023-02-03 TAIT defining scope options - #107645](https://github.com/rust-lang/rust/issues/107645) - [2023-01-17 TAIT tracking issue concern over defining scope](https://github.com/rust-lang/rust/issues/63063#issuecomment-1386064436) - [2022-12-24 TAIT tracking issue concern over updating reference](https://github.com/rust-lang/rust/issues/63063#issuecomment-1364525286) - [2022-12-20 proposed FCP merge of TAIT stabilization](https://github.com/rust-lang/rust/issues/63063#issuecomment-1360043060) - [2022-12-16 TAIT stabilization report](https://github.com/rust-lang/rust/issues/63063#issuecomment-1354392317) - [2019-06-28 TAIT tracking issue - #63063](https://github.com/rust-lang/rust/issues/63063) - [2018-08-05 RFC 2515 - Permit impl Trait in type aliases](https://github.com/rust-lang/rfcs/pull/2515) - [2017-07-20 RFC 2071 - Named existentials and impl Trait variable declarations](https://github.com/rust-lang/rfcs/pull/2071) - [2017-03-15 RFC 1951 - Finalize syntax and parameter scoping for impl Trait, while expanding it to arguments](https://github.com/rust-lang/rfcs/pull/1951) - [2016-03-01 RFC 1522 - Minimal impl Trait](https://github.com/rust-lang/rfcs/pull/1522) - [impl Trait initiative repository](https://rust-lang.github.io/impl-trait-initiative/) - [TAIT project tracking board](https://github.com/orgs/rust-lang/projects/22/views/1) [#107645]: https://github.com/rust-lang/rust/issues/107645

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully