Rust Lang Team
      • 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
      • Invitee
    • 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
    • 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 Sharing URL Help
Menu
Options
Versions and GitHub Sync 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
Invitee
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: "Planning meeting 2023-12-06" tags: ["T-lang", "planning-meeting", "minutes"] date: 2023-12-06 discussion: https://rust-lang.zulipchat.com/#narrow/stream/410673-t-lang.2Fmeetings/topic/Planning.20meeting.202023-12-06 url: https://hackmd.io/jNCHJnQrQGiXwVPAmmdYCg --- # T-lang planning meeting agenda - Meeting date: 2023-12-06 ## Attendance - People: TC, tmandry, eholk, waffle, Josh, scottmcm, eholk ## Meeting roles - Minutes, driver: TC ## Availabiliy - December 13: Everyone present is available. - Let's do match ergonomics. - December 20: Everyone present is available. - Let's do lang-team#235. - December 27: rule out due to holiday - Between Christmas and New Years. - Let's cancel. ## Proposed meetings - "We need to settle the behaviour of floating-point in `const`" [#222](https://github.com/rust-lang/lang-team/issues/222) - "discuss/resolve `fn { mod { (use) super::...; } }` and its interaction with derive patterns" [#193](https://github.com/rust-lang/lang-team/issues/193) - "Design meeting: Rust issues encountered by new Rust users in the Bevy project" [#229](https://github.com/rust-lang/lang-team/issues/229) - "Design meeting: resolve ABI issues around target-feature" [#235](https://github.com/rust-lang/lang-team/issues/235) - "Nail down cargo-script syntax proposal" [#232](https://github.com/rust-lang/lang-team/issues/232) - Might be able to settle this in a triage meeting, depending on async discussion and proposal updates. Other pending proposals include: - Standing proposal: Work on the 2024 edition. - Discussing the needs and use cases of Rust for Linux. - Trevor Gross mentioned he's writing something up for this and asked to be kept in mind. - He's now proposed a design meeting (posted during this meeting): https://github.com/rust-lang/lang-team/issues/240 - Flexible Unsize and CoerceUnsize traits - [pre-RFC](https://internals.rust-lang.org/t/pre-rfc-flexible-unsize-and-coerceunsize-traits/18789). - Improvements to match ergonomics - [proposal in issue](https://github.com/rust-lang/rust/issues/64586#issuecomment-1837919844). - Seems like we wouldn't get through this in a triage meeting, might want to use a design meeting for it. - P-high lang issue, incorrect UB when when a ! place is constructed (but not loaded!) [#117288](https://github.com/rust-lang/rust/issues/117288) Please update these in https://github.com/orgs/rust-lang/projects/31/views/7. ## Discussion tmandry: We should schedule Rust for Linux if there will be a doc for it. Not clear whether that would happen yet or not. Josh: Could also follow through with inviting someone from Bevy to talk about their list of issues new users encounter. TC: The lang-team#235 has a doc ready from RalfJ. tmandry: Making a short list, lang-team#235 should probably be discussed. Also RFL. tmandry: Looking at the match ergonomics, some of those are edition-related, so we should prioritize. tmandry: I'd propose we schedule that and the doc that RalfJ prepared. And we should tell the RFL folks that we definitely want to talk about that. TC: Thoughts? Hearing none, sounds like consensus. TC: Propose the match ergonomics first, as it's edition sensitive, then RalfJ's the week after. ## Planning for 2024 edition Project board: https://github.com/orgs/rust-lang/projects/43 ### Disallow *references* to static mut [Edition Idea] - #114447 **Link:** https://github.com/rust-lang/rust/issues/114447 TC: I'm meaning to write an RFC about this. tmandry: One question is do we need one. scottmcm: I'd probably hope for an RFC here, but hopefully a short one. (It's something that people have been using in stable for a while, so it feels like "more" than just an issue, in a sense.) Josh: We may want a `&raw` syntax, so there could be churn here. Not a blocker, since we could suggest one thing, then later suggest another, just a consideration. scottmcm: We really just want people to use `SyncUnsafeCell` or to define their own type. Josh: Should we reopen the discussion of forbidding `static mut`? scottmcm: Yes, but not for the 2024 edition. scottmcm: I like RalfJ's suggestion here. We can discourage `static mut`, but in the meantime to maybe later removing it, we can do this. tmandry: Sounds like we want an RFC. I'll unnominate this. Josh: Note that `SyncUnsafeCell` only implements `Sync` if `T` implements `Sync`. We may want an unsafe type that always implements `Sync`. scottmcm: That's surprising, since `SyncUnsafeCell` was, I thought, designed for this use case. ### Fix whitespace escaping behavior in string literals (No issue link.) Some background: https://github.com/rust-lang/reference/pull/1042 Josh: So in the edition, we'd remove the behavior of removing multiple newlines. tmandry: There's also something about only skipping increments of 4. Josh: We should fix this. waffle: This is probably complicated enough to merit an RFC. waffle: Do we want a special syntax for multiline strings, like what Zig does? tmandry: Anyone disagree this needs an RFC? Josh: It needs clear documentation at least. I'd take it with a patch for the reference, or an RFC if others prefer that. ### "incorrect UB when when a `!` place is constructed (but not loaded!)" rust#117288 **Link:** https://github.com/rust-lang/rust/issues/117288 (TC: We deferred this from triage to maybe discuss in the planning meeting.) TC: @RalfJ found some interesting examples where `rustc` generates SIGILL on code that shouldn't have UB. T-compiler marked this P-high. RalfJ: > Nominating this to get first vibes on which of the following lines should be accepted, and which should be UB. (Currently they are all accepted and all UB but that's a bug.) > ```rust #![feature(never_type)] fn deref_never<T>() { unsafe { let x = 3u8; let x: *const ! = &x as *const u8 as *const _; let _val = addr_of!(*x); // must be OK let _ = *x; // should probably be OK since we said `_` discards the place (and is UB-equivalent to `addr_of!`) let _: ! = *x; // does a no-op type annotation force the place to be loaded and hence cause UB? let _: () = *x; // is this UB? should we even accept such code? let _: String = *x; // what about this? let _: T = *x; // is this UB even if T = ! ? } } ``` TC: I asked RalfJ for a proposal for the right behavior on the ones with question marks. RalfJ: > I don't know how to arrive at a principled answer to this. There's no obvious "correct" here, it's a judgment call. > > If you are asking for my personal preference ignoring backwards compatibility constraints, then my immediate gut feeling is that _places_ of type `!` should not be subject to never-to-any coercions (the coercion should apply only to _values_, matching the comment that justifies the coercion in the first place). So: > ```rust let _: ! = *x; // OK, not UB let _: () = *x; // does not compile let _: String = *x; // does not compile let _: T = *x; // does not compile ``` TC: What do we think? Josh: Why do we allow?: ```rust let x: *const ! = &x as *const u8 as *const _; ``` scottmcm: You can create any pointer and it's inhabited. The pointer is fine, but the read is invalid. Josh: But that's not true at the type level. Any time you have a never is code that will never be run. scottmcm: If you have a byte that is `3`, and you can have a `*const bool` to it. So the pointer is fine, but it's a pointer you can't read without invoking UB. So that's entirely normal for raw pointers. TC: +1 to scottmcm. tmandry: +1 to scottmcm. scottmcm: We can't even make a post-mono error, as it could be under an `if false`. It's legal Rust code, just UB. waffle: We shouldn't make these more special. It'd be worth making them less special. scottmcm: Consider tuples and partial initialization. Josh: If you have a `*const (u32, !)`, can you dereference it if you only look at the `u32` and never create a `!`? scottmcm: The question is, do we enforce validity rules on place creation or on place reading? waffle: We really want to say that `let _ = *x` does not make a read. We enforce validity when the place is converted to a value. If you're not using the place in any way, then you don't hit the invalidity. scottmcm: Consider: ```rust let p: *const (u32, !) = ...; let q = ptr::addr_of!((*p).0); // uses only *place* operations, not values ``` waffle: Yes I think this should be correct. Josh: So if we accept any of the proposals for pointer projection, then this would be fine. scottmcm: So this would be justifiable... This should be legal even if U=! and f1 panics. ```rust pub fn blah<T, U>(f0: impl Fn() -> T, f1: impl Fn() -> U) -> (T, U) { unsafe { let mut mu: MaybeUninit<(T, U)> = MaybeUninit::uninit(); let p = mu.as_ptr_mut(); //(*addr_of_mut!((*p))).0 = f0(); // place projection here is fine, because it never became a value (*p).0 = f0(); pointermagic.1 = f1(); return mu.assume_init(); } } ``` waffle: An invalid type is OK in a place, but it's UB when you coerce that into a value. scottmcm: The code above is the same as the original argument that these tuples can't be ZSTs because of what compiler does internally. The compiler already wants to write code like this (at least to LLVM) for tuple creation. waffle: ```rust // Ralf's suggestion from above // x: *const ! // OK because we say that `_` does not covert a // place to a value. let _: ! = *x; // OK, not UB // This should not compile because if it compiled, // it would make it so that we converted never to unit, // and that would be immediate UB. let _: () = *x; // does not compile // because this is actually let _: () = (*x) as (); // and thus there's a value, // and thus we don't *want* it to compile because that'd be super confusing // Q: is this also doing a coercion // in a world where it hits type fallback instead // of inferring to `!`? (Since nothing infers to `!` today) // like if someone uses the never-type-on-stable hack... // // A: yes let _ = *x; //~ Shouldn't compile because it infers unit and be UB, today. But we want it to not compile. // Today: compiles as UB because it infers as `()` due to fallback // Wish: doesn't compile because oh god no. let _: String = *x; // does not compile let _: T = *x; // does not compile enum Never {} let y: *const Never = 1 as _; //~ OK today. // this doesn't compile today, // because there is no Never -> () place coercion which is probably incorrect with ! let _: () = *y; //~ ERROR: type mismatch // This still will be UB: let _: () = {*x}; ``` Josh: No objection any longer about what was mentioned above. Happy to defer to expert analysis here. tmandry: Stabilizing `!` is one of the 2024 issues up for discussion. TC: If there are things we could do in 2024 that would help make it possible to evetually do the never type, we should look at that. scottmcm: If we stopped doing this coercion, and people had to write it out, that's one thing we could do. scottmcm: second attempt at stabilizing never: https://github.com/rust-lang/rust/issues/57012 scottmcm: Nothing ever infers to `!` today because it's not a type on stable. It's a weird magic syntax. So reading a pointer to `!`, if you do a hack to get it, is that the value you get back will infer to unit, because that's what type parameter fallback does in these cases, which is why we're having trouble stabilizing never in the first place. So because of that type parameter fallback, you get coercions in places that wouldn't be corecions for literally any other type. waffle: That's correct. waffle: Simple explanation: ```rust // We want to say that this: let _ = *x; //~ Does not do a read. ``` This implies that places don't enforce validity invariants. Which means that a *place* coercion of `! -> T` is invalid, because it assumes that `!`'s validity invariant (false) was enforced. I.e. The **place** coercion of `! -> T` (any type `T`) is a compiler *bug*. It's wrong that we accept this code today. If you have a value of never, then you can coerce it. But you can't validly do that to a place. TC: Does this have bearing on the never stabilization? scottmcm: We can't remove the value coercion since we need that. But if we could figure out how to remove the value coercion, that would make it more possible. tmandry: We could change how the coercions work with the edition. We could make it go from being implicit to explicit. scottmcm: Of course, if it's explicit, it's not a coercion. tmandry: It's a cast. scottmcm: There's no place cast in stable Rust. In this case, we'll get rid of the place coercion, so we don't need a place cast. tmandry: Sounds good to me. I trust you all to figure this out. TC: Could we make those value coercions into casts, over an edition? scottmcm: Maybe? It's hard to make confident statements in this area. scottmcm: If we could notice what you're calling is a function that returns `!` and treat that as control-flow rather than value flow somehow, and do that in a way that is edition dependent. But this is all slightly wrong because of how we do HIR building. scottmcm: Theoretically the only thing you can do with `!` today is to have a value return from a function. It's technically wrong to use it elsewhere. It's officially unstable, so maybe we could carve something out. TC: We've discussed how stabilizing `Infallible` made more difficult the stabilization of the never type. scottmcm: It's because we want `Infallible` to be a type alias to never. TC: Is there any sense in that all emtpy enums should coerce to `!`? scottmcm: Maybe. This may get into the problem of type parameter fallback. ```rust let x = returns_bang(); // x is of type `()` let y = returns_infallible(); // y is of type `Infallible` ``` waffle: If I recall correctly, the problem with type fallback is that for generic functions, we currently infer unit, but we want to infer bang. But if we infer bang, then existing code become UB. scottmcm: ```rust if false { panic!() } else { transmute(()) } ``` This is not UB today. But if the `panic!()` inferred to bang, then it would be UB. A trunsmute creating a `!` is obvious immediate UB. Since the transmute is unconstrained, changing the type of `panic!()` changes the `dst` type of `transmute` from unit to bang. TC: We needed to circle back to: ```rust= let _: () = *x; // Insta-UB or compiler error? ``` scottmcm: Even if we say that the place can't be coerced, that could still do the place to value coercion, and then convert that. waffle: The place to value coercion happens at the `let` level... scottmcm: And we wouldn't be asking for the value? TC: It seems like we're saying it's at least insta-UB, and any insta-UB that the compiler can find is of course good. scottmcm: I might put this in a deny-by-default lint rather than a compiler error category. TC: +1. scottmcm: You only get the coercion if it's literally a coercion to `!`. If it's a pointer to a generic type, and that happens to be substituted to `!`, then... waffle: ```rust unsafe fn foo<T>(p: *const T) { // doesn't compile because generics don't work like that let _: () = *p; //~ ERROR } // so you only hit that if it's literally bang, like unsafe fn bar(p: *const !) { let _: () = *p; } // and nobody would ever write that. ``` scottmcm: If `bar` is UB to call but compiles, then I'm OK with that. Don't write that. scottmcm: Do we want a crater run? TC: What would we expect crater to hit? waffle: Not doing place coercions should make strictly less code compile. scottmcm: What classes of things would hit this? scottmcm: If we could make this be the rule, that'd be great. *Consensus*: It's not UB to have an invalid thing in a place. But it's UB to coerce that invalid place to a value. And anywhere that the compiler can statically determine that insta-UB is happening, that would be a good spot for a deny-by-default lint, and it'd also be fine to hard error on those cases if that's easier. Ralf's comment here <https://github.com/rust-lang/rust/issues/117288#issuecomment-1813030483> scottmcm: Where this may break is the use of the never type hack, but that's probably OK. waffle: ```rust trait Hack { type Out; } impl<T> Hack for fn() -> T { type Out = T; } type Never = <fn() -> ! as Hack>::Out; ``` scottmcm: More details: https://github.com/rust-lang/never-type-initiative (The meeting ended here.) ## Active initiatives ### "project-safe-transmute" lang-team#21 **Link:** https://github.com/rust-lang/lang-team/issues/21 ### "const-evaluation" lang-team#22 **Link:** https://github.com/rust-lang/lang-team/issues/22 ### "const-generics" lang-team#51 **Link:** https://github.com/rust-lang/lang-team/issues/51 ### "Deref patterns" lang-team#88 **Link:** https://github.com/rust-lang/lang-team/issues/88 ### "Generators (iterator functions), sync and async" lang-team#137 **Link:** https://github.com/rust-lang/lang-team/issues/137 ### "Initiative: trusted external static declarations" lang-team#149 **Link:** https://github.com/rust-lang/lang-team/issues/149 ## Pending proposals on the lang-team repo None. ## Pending PRs on the lang-team repo ### "project-safe-transmute" lang-team#21 **Link:** https://github.com/rust-lang/lang-team/issues/21 ### "const-evaluation" lang-team#22 **Link:** https://github.com/rust-lang/lang-team/issues/22 ### "clarify lint policy " lang-team#48 **Link:** https://github.com/rust-lang/lang-team/issues/48 ### "const-generics" lang-team#51 **Link:** https://github.com/rust-lang/lang-team/issues/51 ### "Make a place for a "lang team wishlist"" lang-team#54 **Link:** https://github.com/rust-lang/lang-team/issues/54 ### "Link in design meeting template is dead" lang-team#80 **Link:** https://github.com/rust-lang/lang-team/issues/80 ### "Eventual Concern: Send/Sync insufficient in the presence of multiple execution contexts." lang-team#87 **Link:** https://github.com/rust-lang/lang-team/issues/87 ### "Deref patterns" lang-team#88 **Link:** https://github.com/rust-lang/lang-team/issues/88 ### "Specification of safe rust ?" lang-team#123 **Link:** https://github.com/rust-lang/lang-team/issues/123 ### "Generators (iterator functions), sync and async" lang-team#137 **Link:** https://github.com/rust-lang/lang-team/issues/137 ### "Initiative: trusted external static declarations" lang-team#149 **Link:** https://github.com/rust-lang/lang-team/issues/149 ### "agenda generation should include section with S-waiting-on-team + T-lang" lang-team#172 **Link:** https://github.com/rust-lang/lang-team/issues/172 ### "dead Zulip/zulip-archive links" lang-team#185 **Link:** https://github.com/rust-lang/lang-team/issues/185 ### "HTTP Error 404 in the Chat Platform p link" lang-team#186 **Link:** https://github.com/rust-lang/lang-team/issues/186 ### "Language design principles" lang-team#189 **Link:** https://github.com/rust-lang/lang-team/issues/189 ### "discuss/resolve `fn { mod { (use) super::...; } }` and its interaction with derive patterns" lang-team#193 **Link:** https://github.com/rust-lang/lang-team/issues/193 ### "lang agenda generator ignores lang-nominated closed issues" lang-team#199 **Link:** https://github.com/rust-lang/lang-team/issues/199 ### "The #[diagnostic] attribute namespace" lang-team#204 **Link:** https://github.com/rust-lang/lang-team/issues/204 ### "Rust 2024 survey" lang-team#209 **Link:** https://github.com/rust-lang/lang-team/issues/209 ### "Extern types V2 RFC" lang-team#211 **Link:** https://github.com/rust-lang/lang-team/issues/211 ### "Capturing lifetimes in `impl Trait`" lang-team#215 **Link:** https://github.com/rust-lang/lang-team/issues/215 ### "RFC review Inherent Trait Impls -- RFC#2375" lang-team#217 **Link:** https://github.com/rust-lang/lang-team/issues/217 ### "RFC review: Add f16 and f128 float types -- RFC#3453" lang-team#218 **Link:** https://github.com/rust-lang/lang-team/issues/218 ### "RFC review: MaybeDangling -- RFCS#3336" lang-team#219 **Link:** https://github.com/rust-lang/lang-team/issues/219 ### "Design meeting: Decide about the future for consts in patterns" lang-team#220 **Link:** https://github.com/rust-lang/lang-team/issues/220 ### "mdbook build and deploy is failing" lang-team#221 **Link:** https://github.com/rust-lang/lang-team/issues/221 ### "We need to settle the behaviour of floating-point in `const`" lang-team#222 **Link:** https://github.com/rust-lang/lang-team/issues/222 ### "Meeting proposal: Unsafe extern blocks" lang-team#223 **Link:** https://github.com/rust-lang/lang-team/issues/223 ### "Design meeting: Implementable trait aliases" lang-team#224 **Link:** https://github.com/rust-lang/lang-team/issues/224 ### "Design meeting: Rust issues encountered by new Rust users in the Bevy project" lang-team#229 **Link:** https://github.com/rust-lang/lang-team/issues/229 ### "Nail down cargo-script syntax proposal" lang-team#232 **Link:** https://github.com/rust-lang/lang-team/issues/232 ### "Design meeting: resolve ABI issues around target-feature" lang-team#235 **Link:** https://github.com/rust-lang/lang-team/issues/235 ### "Add soqb`s design doc to variadics notes" lang-team#236 **Link:** https://github.com/rust-lang/lang-team/pull/236 ### "Update auto traits design notes with recent discussion" lang-team#237 **Link:** https://github.com/rust-lang/lang-team/pull/237 ### "Website broken" lang-team#238 **Link:** https://github.com/rust-lang/lang-team/issues/238

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