Skip to content

Latest commit

 

History

History
314 lines (117 loc) · 8.7 KB

keywords.md

File metadata and controls

314 lines (117 loc) · 8.7 KB

Nuggets about each and every (strict)

https://doc.rust-lang.org/stable/reference/keywords.html

Original thread: https://twitter.com/jonhoo/status/1539661689880137728


as: x as T can do lossy conversion, so prefer T::try_from(x).expect("…") if you want it to fail loudly (e.g., if a u64 doesn't fit in a u32).

https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions


async: in async blocks, return and ? only bubble to the result of the future, whereas break and continue would affect the outer context and so re disallowed.

https://doc.rust-lang.org/stable/reference/expressions/block-expr.html#control-flow-operators


await: await is nothing but syntactic sugar for a loop that calls Future::poll and calls yield on Poll::Pending.

https://github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_ast_lowering/src/expr.rs#L635-L650


break: You can pass a value to break in a loop to make the loop evaluate to that value.

https://doc.rust-lang.org/stable/reference/expressions/loop-expr.html#break-and-loop-values


const: There are a lot more constifications planned, including allowing async {} in const fn!

rust-lang/rust#57563


continue: continue effectively evaluates to !, which allows it to masquerade as any type.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8cc6050f46ba1de14afd2a8b8ab53bc2


crate: These days, the two primary uses of crate as a standalone keyword have mostly gone away: extern crate is rarely used, and crate as a visibility modifer won't happen (just use pub(crate) instead).

rust-lang/rust#53120 (comment)


dyn: dyn trait objects come with a default lifetime bound inherited from the containing wide pointer type.

https://doc.rust-lang.org/stable/reference/lifetime-elision.html#default-trait-object-lifetimes


else: else is about to get another meaning with let-else expressions, which are like .unwrap_or for pattern matches!

rust-lang/rust#93628


enum: For data-less enums ("C-style enums"), you can assign a value to only a subset of the variants, and the remaining ones get inferred automatically.

https://doc.rust-lang.org/stable/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations


extern: extern on its own is an alias for extern "C" — the two are interchangeable.

https://doc.rust-lang.org/stable/reference/items/external-blocks.html#abi


false: false < true.

https://doc.rust-lang.org/stable/reference/types/boolean.html#comparisons


fn: You can write #![attr] immediately inside a function to add attributes to the function itself (though it's not very idiomatic).

https://doc.rust-lang.org/stable/reference/items/functions.html#attributes-on-functions


for: for loops are really just syntax sugar for a loop that calls IntoIterator::into_iter and then matches on Iterator::next.

https://github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/compiler/rustc_ast_lowering/src/expr.rs#L1390-L1406


if: 🤔🤷

undefined


impl: You can put consts directly in impl blocks to make "associated constants" for a type.

https://doc.rust-lang.org/stable/reference/items/associated-items.html#associated-constants


in: Not specifically about in, but any .. expression is actually just a convenient constructor for a Range type.

https://doc.rust-lang.org/stable/reference/expressions/range-expr.html


let: The interaction between let _ and dropping are subtle and interesting.

rust-lang/rust#10488


loop: There used to be a mode in the Rust compiler that turned every function body into loop {}, which was used (among other things) to make rustdoc faster. It was called "everybody loops" 😆.

rust-lang/rust#73566


match: The expression that a match matches on is called a "scrutinee".

https://doc.rust-lang.org/stable/reference/glossary.html#scrutinee


mod: You can make mod load files from non-standard locations using the #[path] attribute. Though use it sparingly, as it can be very confusing for other developers trying to sort through your code base.

https://doc.rust-lang.org/stable/reference/items/modules.html#the-path-attribute


move: The "opposite" capture behavior of move (that is, if move isn't passed), is far from straightforward.

https://doc.rust-lang.org/stable/reference/types/closure.html#capture-modes


mut: While mut is techically short for "mutable", you're generally better off thinking about it as "MUTually exclusive".

https://docs.rs/dtolnay/latest/dtolnay/macro._02__reference_types.html


pub: There are a lot of visibility modifiers between non-pub and pub. pub(crate) and pub(super) are both useful, but you can even specify pub(in crate::some_mod) to get really specific.

https://doc.rust-lang.org/stable/reference/visibility-and-privacy.html


ref: You can use ref to match something as a reference in a pattern, instead of capturing it as a value. That's not a secret of ref, it's just what it means, but it's so commonly confused that it's worth repeating.

https://doc.rust-lang.org/stable/reference/patterns.html#identifier-patterns


return: return has a secret, long-unimplemented sibling, become, which is intended to one day maybe be used for functions that require guaranteed tail-call optimization.

https://rust-lang.github.io/rfcs/0601-replace-be-with-become.html


self: self is special when it comes to automatic inference of the lifetime of return values. Specifically, the lifetime of a &self or &mut self argument will always be inferred to be the lifetime of the return value (if lifetimes are elided).

https://doc.rust-lang.org/stable/reference/lifetime-elision.html


Self:

undefined


static: You can declare static items inside function bodies to get a static that only that function has access to (unless it gives out references). This can be handy for implementing singleton-like patterns.

https://doc.rust-lang.org/stable/reference/items/static-items.html#statics--generics


struct: A tuple-like struct implicitly defines a free-standing function by the same name that acts as the type's constructor. And a unit-like struct implicitly defines a constant by that name!

https://doc.rust-lang.org/stable/reference/items/structs.html


super: super is only permitted to follow either another super or an initial self in paths, and if it follows a self then the self is effectively ignored.

https://doc.rust-lang.org/stable/reference/paths.html#super


trait: Traits can have associated constants, both with and without default values.

https://doc.rust-lang.org/stable/reference/items/traits.html


true: Even though bools in Rust are generally u8s internally, it is illegal for true to be represented by anything but 0x01. This is to enable optimizations that use other bitpatterns to compress state (like Option::None == 0x02).

rust-lang/rfcs#1230


type: You cannot construct a type through its type alias name.

https://doc.rust-lang.org/stable/reference/items/type-aliases.html


unsafe: You don't currently have to use unsafe {} to perform unsafe operations inside an unsafe fn, though that's likely to get a lint in the future to encourage fine-grained safety tracking (and thinking).

rust-lang/rust#71668


use: You can use the syntax use path::to::Trait as _ to bring a trait into scope (so you can call its methods) without also bringing the name into scope. Handy in cases where two traits have the same name for example.

https://doc.rust-lang.org/stable/reference/items/use-declarations.html#underscore-imports


where: where clauses do not need to reference the generic type parameters of the thing they're attached to. You can write, for example: where String: Clone if you want to.

https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses


while: While loops are particularly handy for cases where the iterator type is useful beyond iteration. For example, if you're iterating over a Path (with Path::iter), you can call .as_path() on the iterator to get the remaining Path.

https://doc.rust-lang.org/std/path/struct.Iter.html