Rollup merge of #29022 - apasel422:spell, r=steveklabnik
r? @steveklabnik
This commit is contained in:
commit
d90f8f912b
43 changed files with 82 additions and 82 deletions
|
@ -1,6 +1,6 @@
|
||||||
# Compiler Test Documentation
|
# Compiler Test Documentation
|
||||||
|
|
||||||
In the Rust project, we use a special set of comands embedded in
|
In the Rust project, we use a special set of commands embedded in
|
||||||
comments to test the Rust compiler. There are two groups of commands:
|
comments to test the Rust compiler. There are two groups of commands:
|
||||||
|
|
||||||
1. Header commands
|
1. Header commands
|
||||||
|
|
|
@ -76,7 +76,7 @@ Cleanup through RAII-style destructors is more likely to work than in catch bloc
|
||||||
|
|
||||||
## Why aren't modules type-parametric?
|
## Why aren't modules type-parametric?
|
||||||
|
|
||||||
We want to maintain the option to parametrize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
|
We want to maintain the option to parameterize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.
|
||||||
|
|
||||||
## Why aren't values type-parametric? Why only items?
|
## Why aren't values type-parametric? Why only items?
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ For numeric casts, there are quite a few cases to consider:
|
||||||
* zero-extend if the source is unsigned
|
* zero-extend if the source is unsigned
|
||||||
* sign-extend if the source is signed
|
* sign-extend if the source is signed
|
||||||
* casting from a float to an integer will round the float towards zero
|
* casting from a float to an integer will round the float towards zero
|
||||||
* **[NOTE: currently this will cause Undefined Behaviour if the rounded
|
* **[NOTE: currently this will cause Undefined Behavior if the rounded
|
||||||
value cannot be represented by the target integer type][float-int]**.
|
value cannot be represented by the target integer type][float-int]**.
|
||||||
This includes Inf and NaN. This is a bug and will be fixed.
|
This includes Inf and NaN. This is a bug and will be fixed.
|
||||||
* casting from an integer to float will produce the floating point
|
* casting from an integer to float will produce the floating point
|
||||||
|
@ -61,7 +61,7 @@ For numeric casts, there are quite a few cases to consider:
|
||||||
* casting from an f32 to an f64 is perfect and lossless
|
* casting from an f32 to an f64 is perfect and lossless
|
||||||
* casting from an f64 to an f32 will produce the closest possible value
|
* casting from an f64 to an f32 will produce the closest possible value
|
||||||
(rounding strategy unspecified)
|
(rounding strategy unspecified)
|
||||||
* **[NOTE: currently this will cause Undefined Behaviour if the value
|
* **[NOTE: currently this will cause Undefined Behavior if the value
|
||||||
is finite but larger or smaller than the largest or smallest finite
|
is finite but larger or smaller than the largest or smallest finite
|
||||||
value representable by f32][float-float]**. This is a bug and will
|
value representable by f32][float-float]**. This is a bug and will
|
||||||
be fixed.
|
be fixed.
|
||||||
|
|
|
@ -6,7 +6,7 @@ interacted with the *outlives* relationship in an inclusive manner. That is,
|
||||||
when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
|
when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
|
||||||
`'b`. At first glance, this seems to be a meaningless distinction. Nothing ever
|
`'b`. At first glance, this seems to be a meaningless distinction. Nothing ever
|
||||||
gets dropped at the same time as another, right? This is why we used the
|
gets dropped at the same time as another, right? This is why we used the
|
||||||
following desugarring of `let` statements:
|
following desugaring of `let` statements:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
let x;
|
let x;
|
||||||
|
|
|
@ -20,7 +20,7 @@ information that "completes" them (more on this below).
|
||||||
There are two major DSTs exposed by the language: trait objects, and slices.
|
There are two major DSTs exposed by the language: trait objects, and slices.
|
||||||
|
|
||||||
A trait object represents some type that implements the traits it specifies.
|
A trait object represents some type that implements the traits it specifies.
|
||||||
The exact original type is *erased* in favour of runtime reflection
|
The exact original type is *erased* in favor of runtime reflection
|
||||||
with a vtable containing all the information necessary to use the type.
|
with a vtable containing all the information necessary to use the type.
|
||||||
This is the information that completes a trait object: a pointer to its vtable.
|
This is the information that completes a trait object: a pointer to its vtable.
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ But neither of these tricks work today, so all Void types get you is
|
||||||
the ability to be confident that certain situations are statically impossible.
|
the ability to be confident that certain situations are statically impossible.
|
||||||
|
|
||||||
One final subtle detail about empty types is that raw pointers to them are
|
One final subtle detail about empty types is that raw pointers to them are
|
||||||
actually valid to construct, but dereferencing them is Undefined Behaviour
|
actually valid to construct, but dereferencing them is Undefined Behavior
|
||||||
because that doesn't actually make sense. That is, you could model C's `void *`
|
because that doesn't actually make sense. That is, you could model C's `void *`
|
||||||
type with `*const Void`, but this doesn't necessarily gain anything over using
|
type with `*const Void`, but this doesn't necessarily gain anything over using
|
||||||
e.g. `*const ()`, which *is* safe to randomly dereference.
|
e.g. `*const ()`, which *is* safe to randomly dereference.
|
||||||
|
|
|
@ -90,7 +90,7 @@ let mut vec = vec![Box::new(0); 4];
|
||||||
println!("{}", vec[0]);
|
println!("{}", vec[0]);
|
||||||
```
|
```
|
||||||
|
|
||||||
This is pretty clearly Not Good. Unfortunately, we're kind've stuck between a
|
This is pretty clearly Not Good. Unfortunately, we're kind of stuck between a
|
||||||
rock and a hard place: maintaining consistent state at every step has an
|
rock and a hard place: maintaining consistent state at every step has an
|
||||||
enormous cost (and would negate any benefits of the API). Failing to maintain
|
enormous cost (and would negate any benefits of the API). Failing to maintain
|
||||||
consistent state gives us Undefined Behavior in safe code (making the API
|
consistent state gives us Undefined Behavior in safe code (making the API
|
||||||
|
@ -248,4 +248,4 @@ let mut data = Box::new(0);
|
||||||
```
|
```
|
||||||
|
|
||||||
Dang. Here the destructor running was pretty fundamental to the API, and it had
|
Dang. Here the destructor running was pretty fundamental to the API, and it had
|
||||||
to be scrapped in favour of a completely different design.
|
to be scrapped in favor of a completely different design.
|
||||||
|
|
|
@ -26,7 +26,7 @@ do some really crazy unsafe things.
|
||||||
|
|
||||||
Safe Rust is the *true* Rust programming language. If all you do is write Safe
|
Safe Rust is the *true* Rust programming language. If all you do is write Safe
|
||||||
Rust, you will never have to worry about type-safety or memory-safety. You will
|
Rust, you will never have to worry about type-safety or memory-safety. You will
|
||||||
never endure a null or dangling pointer, or any of that Undefined Behaviour
|
never endure a null or dangling pointer, or any of that Undefined Behavior
|
||||||
nonsense.
|
nonsense.
|
||||||
|
|
||||||
*That's totally awesome.*
|
*That's totally awesome.*
|
||||||
|
@ -52,11 +52,11 @@ The only things that are different in Unsafe Rust are that you can:
|
||||||
* Mutate statics
|
* Mutate statics
|
||||||
|
|
||||||
That's it. The reason these operations are relegated to Unsafe is that misusing
|
That's it. The reason these operations are relegated to Unsafe is that misusing
|
||||||
any of these things will cause the ever dreaded Undefined Behaviour. Invoking
|
any of these things will cause the ever dreaded Undefined Behavior. Invoking
|
||||||
Undefined Behaviour gives the compiler full rights to do arbitrarily bad things
|
Undefined Behavior gives the compiler full rights to do arbitrarily bad things
|
||||||
to your program. You definitely *should not* invoke Undefined Behaviour.
|
to your program. You definitely *should not* invoke Undefined Behavior.
|
||||||
|
|
||||||
Unlike C, Undefined Behaviour is pretty limited in scope in Rust. All the core
|
Unlike C, Undefined Behavior is pretty limited in scope in Rust. All the core
|
||||||
language cares about is preventing the following things:
|
language cares about is preventing the following things:
|
||||||
|
|
||||||
* Dereferencing null or dangling pointers
|
* Dereferencing null or dangling pointers
|
||||||
|
@ -71,9 +71,9 @@ language cares about is preventing the following things:
|
||||||
* Unwinding into another language
|
* Unwinding into another language
|
||||||
* Causing a [data race][race]
|
* Causing a [data race][race]
|
||||||
|
|
||||||
That's it. That's all the causes of Undefined Behaviour baked into Rust. Of
|
That's it. That's all the causes of Undefined Behavior baked into Rust. Of
|
||||||
course, unsafe functions and traits are free to declare arbitrary other
|
course, unsafe functions and traits are free to declare arbitrary other
|
||||||
constraints that a program must maintain to avoid Undefined Behaviour. However,
|
constraints that a program must maintain to avoid Undefined Behavior. However,
|
||||||
generally violations of these constraints will just transitively lead to one of
|
generally violations of these constraints will just transitively lead to one of
|
||||||
the above problems. Some additional constraints may also derive from compiler
|
the above problems. Some additional constraints may also derive from compiler
|
||||||
intrinsics that make special assumptions about how code can be optimized.
|
intrinsics that make special assumptions about how code can be optimized.
|
||||||
|
|
|
@ -6,7 +6,7 @@ Safe Rust guarantees an absence of data races, which are defined as:
|
||||||
* one of them is a write
|
* one of them is a write
|
||||||
* one of them is unsynchronized
|
* one of them is unsynchronized
|
||||||
|
|
||||||
A data race has Undefined Behaviour, and is therefore impossible to perform
|
A data race has Undefined Behavior, and is therefore impossible to perform
|
||||||
in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
|
in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
|
||||||
it's impossible to alias a mutable reference, so it's impossible to perform a
|
it's impossible to alias a mutable reference, so it's impossible to perform a
|
||||||
data race. Interior mutability makes this more complicated, which is largely why
|
data race. Interior mutability makes this more complicated, which is largely why
|
||||||
|
@ -53,7 +53,7 @@ thread::spawn(move || {
|
||||||
// bounds checked, and there's no chance of the value getting changed
|
// bounds checked, and there's no chance of the value getting changed
|
||||||
// in the middle. However our program may panic if the thread we spawned
|
// in the middle. However our program may panic if the thread we spawned
|
||||||
// managed to increment before this ran. A race condition because correct
|
// managed to increment before this ran. A race condition because correct
|
||||||
// program execution (panicing is rarely correct) depends on order of
|
// program execution (panicking is rarely correct) depends on order of
|
||||||
// thread execution.
|
// thread execution.
|
||||||
println!("{}", data[idx.load(Ordering::SeqCst)]);
|
println!("{}", data[idx.load(Ordering::SeqCst)]);
|
||||||
```
|
```
|
||||||
|
|
|
@ -41,7 +41,7 @@ Some examples of unsafe functions:
|
||||||
|
|
||||||
* `slice::get_unchecked` will perform unchecked indexing, allowing memory
|
* `slice::get_unchecked` will perform unchecked indexing, allowing memory
|
||||||
safety to be freely violated.
|
safety to be freely violated.
|
||||||
* `ptr::offset` is an intrinsic that invokes Undefined Behaviour if it is
|
* `ptr::offset` is an intrinsic that invokes Undefined Behavior if it is
|
||||||
not "in bounds" as defined by LLVM.
|
not "in bounds" as defined by LLVM.
|
||||||
* `mem::transmute` reinterprets some value as having the given type,
|
* `mem::transmute` reinterprets some value as having the given type,
|
||||||
bypassing type safety in arbitrary ways. (see [conversions] for details)
|
bypassing type safety in arbitrary ways. (see [conversions] for details)
|
||||||
|
@ -59,9 +59,9 @@ As of Rust 1.0 there are exactly two unsafe traits:
|
||||||
The need for unsafe traits boils down to the fundamental property of safe code:
|
The need for unsafe traits boils down to the fundamental property of safe code:
|
||||||
|
|
||||||
**No matter how completely awful Safe code is, it can't cause Undefined
|
**No matter how completely awful Safe code is, it can't cause Undefined
|
||||||
Behaviour.**
|
Behavior.**
|
||||||
|
|
||||||
This means that Unsafe Rust, **the royal vanguard of Undefined Behaviour**, has to be
|
This means that Unsafe Rust, **the royal vanguard of Undefined Behavior**, has to be
|
||||||
*super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
|
*super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
|
||||||
specific safe code. Anything else would degenerate into infinite spirals of
|
specific safe code. Anything else would degenerate into infinite spirals of
|
||||||
paranoid despair. In particular it's generally regarded as ok to trust the standard library
|
paranoid despair. In particular it's generally regarded as ok to trust the standard library
|
||||||
|
|
|
@ -15,7 +15,7 @@ implement, and other unsafe code can assume that they are correctly
|
||||||
implemented. Since they're *marker traits* (they have no associated items like
|
implemented. Since they're *marker traits* (they have no associated items like
|
||||||
methods), correctly implemented simply means that they have the intrinsic
|
methods), correctly implemented simply means that they have the intrinsic
|
||||||
properties an implementor should have. Incorrectly implementing Send or Sync can
|
properties an implementor should have. Incorrectly implementing Send or Sync can
|
||||||
cause Undefined Behaviour.
|
cause Undefined Behavior.
|
||||||
|
|
||||||
Send and Sync are also automatically derived traits. This means that, unlike
|
Send and Sync are also automatically derived traits. This means that, unlike
|
||||||
every other trait, if a type is composed entirely of Send or Sync types, then it
|
every other trait, if a type is composed entirely of Send or Sync types, then it
|
||||||
|
|
|
@ -8,7 +8,7 @@ horribly unsafe thing you can do in Rust. The railguards here are dental floss.
|
||||||
|
|
||||||
`mem::transmute<T, U>` takes a value of type `T` and reinterprets it to have
|
`mem::transmute<T, U>` takes a value of type `T` and reinterprets it to have
|
||||||
type `U`. The only restriction is that the `T` and `U` are verified to have the
|
type `U`. The only restriction is that the `T` and `U` are verified to have the
|
||||||
same size. The ways to cause Undefined Behaviour with this are mind boggling.
|
same size. The ways to cause Undefined Behavior with this are mind boggling.
|
||||||
|
|
||||||
* First and foremost, creating an instance of *any* type with an invalid state
|
* First and foremost, creating an instance of *any* type with an invalid state
|
||||||
is going to cause arbitrary chaos that can't really be predicted.
|
is going to cause arbitrary chaos that can't really be predicted.
|
||||||
|
@ -26,7 +26,7 @@ same size. The ways to cause Undefined Behaviour with this are mind boggling.
|
||||||
`mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than
|
`mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than
|
||||||
this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
|
this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
|
||||||
The size check that `mem::transmute` has is gone (as it may be valid to copy
|
The size check that `mem::transmute` has is gone (as it may be valid to copy
|
||||||
out a prefix), though it is Undefined Behaviour for `U` to be larger than `T`.
|
out a prefix), though it is Undefined Behavior for `U` to be larger than `T`.
|
||||||
|
|
||||||
Also of course you can get most of the functionality of these functions using
|
Also of course you can get most of the functionality of these functions using
|
||||||
pointer casts.
|
pointer casts.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Unsafe code can often end up producing references or lifetimes out of thin air.
|
Unsafe code can often end up producing references or lifetimes out of thin air.
|
||||||
Such lifetimes come into the world as *unbounded*. The most common source of this
|
Such lifetimes come into the world as *unbounded*. The most common source of this
|
||||||
is derefencing a raw pointer, which produces a reference with an unbounded lifetime.
|
is dereferencing a raw pointer, which produces a reference with an unbounded lifetime.
|
||||||
Such a lifetime becomes as big as context demands. This is in fact more powerful
|
Such a lifetime becomes as big as context demands. This is in fact more powerful
|
||||||
than simply becoming `'static`, because for instance `&'static &'a T`
|
than simply becoming `'static`, because for instance `&'static &'a T`
|
||||||
will fail to typecheck, but the unbound lifetime will perfectly mold into
|
will fail to typecheck, but the unbound lifetime will perfectly mold into
|
||||||
|
@ -10,7 +10,7 @@ will fail to typecheck, but the unbound lifetime will perfectly mold into
|
||||||
lifetime can be regarded as `'static`.
|
lifetime can be regarded as `'static`.
|
||||||
|
|
||||||
Almost no reference is `'static`, so this is probably wrong. `transmute` and
|
Almost no reference is `'static`, so this is probably wrong. `transmute` and
|
||||||
`transmute_copy` are the two other primary offenders. One should endeavour to
|
`transmute_copy` are the two other primary offenders. One should endeavor to
|
||||||
bound an unbounded lifetime as quick as possible, especially across function
|
bound an unbounded lifetime as quick as possible, especially across function
|
||||||
boundaries.
|
boundaries.
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ dropping the old value: `write`, `copy`, and `copy_nonoverlapping`.
|
||||||
(this is equivalent to memcpy -- note that the argument order is reversed!)
|
(this is equivalent to memcpy -- note that the argument order is reversed!)
|
||||||
|
|
||||||
It should go without saying that these functions, if misused, will cause serious
|
It should go without saying that these functions, if misused, will cause serious
|
||||||
havoc or just straight up Undefined Behaviour. The only things that these
|
havoc or just straight up Undefined Behavior. The only things that these
|
||||||
functions *themselves* require is that the locations you want to read and write
|
functions *themselves* require is that the locations you want to read and write
|
||||||
are allocated. However the ways writing arbitrary bits to arbitrary
|
are allocated. However the ways writing arbitrary bits to arbitrary
|
||||||
locations of memory can break things are basically uncountable!
|
locations of memory can break things are basically uncountable!
|
||||||
|
|
|
@ -4,7 +4,7 @@ All runtime-allocated memory in a Rust program begins its life as
|
||||||
*uninitialized*. In this state the value of the memory is an indeterminate pile
|
*uninitialized*. In this state the value of the memory is an indeterminate pile
|
||||||
of bits that may or may not even reflect a valid state for the type that is
|
of bits that may or may not even reflect a valid state for the type that is
|
||||||
supposed to inhabit that location of memory. Attempting to interpret this memory
|
supposed to inhabit that location of memory. Attempting to interpret this memory
|
||||||
as a value of *any* type will cause Undefined Behaviour. Do Not Do This.
|
as a value of *any* type will cause Undefined Behavior. Do Not Do This.
|
||||||
|
|
||||||
Rust provides mechanisms to work with uninitialized memory in checked (safe) and
|
Rust provides mechanisms to work with uninitialized memory in checked (safe) and
|
||||||
unchecked (unsafe) ways.
|
unchecked (unsafe) ways.
|
||||||
|
|
|
@ -42,7 +42,7 @@ should only panic for programming errors or *extreme* problems.
|
||||||
|
|
||||||
Rust's unwinding strategy is not specified to be fundamentally compatible
|
Rust's unwinding strategy is not specified to be fundamentally compatible
|
||||||
with any other language's unwinding. As such, unwinding into Rust from another
|
with any other language's unwinding. As such, unwinding into Rust from another
|
||||||
language, or unwinding into another language from Rust is Undefined Behaviour.
|
language, or unwinding into another language from Rust is Undefined Behavior.
|
||||||
You must *absolutely* catch any panics at the FFI boundary! What you do at that
|
You must *absolutely* catch any panics at the FFI boundary! What you do at that
|
||||||
point is up to you, but *something* must be done. If you fail to do this,
|
point is up to you, but *something* must be done. If you fail to do this,
|
||||||
at best, your application will crash and burn. At worst, your application *won't*
|
at best, your application will crash and burn. At worst, your application *won't*
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub struct Vec<T> {
|
||||||
If you don't care about the null-pointer optimization, then you can use the
|
If you don't care about the null-pointer optimization, then you can use the
|
||||||
stable code. However we will be designing the rest of the code around enabling
|
stable code. However we will be designing the rest of the code around enabling
|
||||||
the optimization. In particular, `Unique::new` is unsafe to call, because
|
the optimization. In particular, `Unique::new` is unsafe to call, because
|
||||||
putting `null` inside of it is Undefined Behaviour. Our stable Unique doesn't
|
putting `null` inside of it is Undefined Behavior. Our stable Unique doesn't
|
||||||
need `new` to be unsafe because it doesn't make any interesting guarantees about
|
need `new` to be unsafe because it doesn't make any interesting guarantees about
|
||||||
its contents.
|
its contents.
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Easy! How about `pop`? Although this time the index we want to access is
|
||||||
initialized, Rust won't just let us dereference the location of memory to move
|
initialized, Rust won't just let us dereference the location of memory to move
|
||||||
the value out, because that would leave the memory uninitialized! For this we
|
the value out, because that would leave the memory uninitialized! For this we
|
||||||
need `ptr::read`, which just copies out the bits from the target address and
|
need `ptr::read`, which just copies out the bits from the target address and
|
||||||
intrprets it as a value of type T. This will leave the memory at this address
|
interprets it as a value of type T. This will leave the memory at this address
|
||||||
logically uninitialized, even though there is in fact a perfectly good instance
|
logically uninitialized, even though there is in fact a perfectly good instance
|
||||||
of T there.
|
of T there.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
% Handling Zero-Sized Types
|
% Handling Zero-Sized Types
|
||||||
|
|
||||||
It's time. We're going to fight the spectre that is zero-sized types. Safe Rust
|
It's time. We're going to fight the specter that is zero-sized types. Safe Rust
|
||||||
*never* needs to care about this, but Vec is very intensive on raw pointers and
|
*never* needs to care about this, but Vec is very intensive on raw pointers and
|
||||||
raw allocations, which are exactly the two things that care about
|
raw allocations, which are exactly the two things that care about
|
||||||
zero-sized types. We need to be careful of two things:
|
zero-sized types. We need to be careful of two things:
|
||||||
|
|
|
@ -3709,7 +3709,7 @@ repeated sub-expression is a coercion site for coercion to type `U`.
|
||||||
Each sub-expression is a coercion site to the respective type, e.g. the
|
Each sub-expression is a coercion site to the respective type, e.g. the
|
||||||
zeroth sub-expression is a coercion site to type `U_0`.
|
zeroth sub-expression is a coercion site to type `U_0`.
|
||||||
|
|
||||||
* Parenthesised sub-expressions (`(e)`): if the expression has type `U`, then
|
* Parenthesized sub-expressions (`(e)`): if the expression has type `U`, then
|
||||||
the sub-expression is a coercion site to `U`.
|
the sub-expression is a coercion site to `U`.
|
||||||
|
|
||||||
* Blocks: if a block has type `U`, then the last expression in the block (if
|
* Blocks: if a block has type `U`, then the last expression in the block (if
|
||||||
|
@ -4075,7 +4075,7 @@ that have since been removed):
|
||||||
|
|
||||||
* SML, OCaml: algebraic data types, pattern matching, type inference,
|
* SML, OCaml: algebraic data types, pattern matching, type inference,
|
||||||
semicolon statement separation
|
semicolon statement separation
|
||||||
* C++: references, RAII, smart pointers, move semantics, monomorphisation,
|
* C++: references, RAII, smart pointers, move semantics, monomorphization,
|
||||||
memory model
|
memory model
|
||||||
* ML Kit, Cyclone: region based memory management
|
* ML Kit, Cyclone: region based memory management
|
||||||
* Haskell (GHC): typeclasses, type families
|
* Haskell (GHC): typeclasses, type families
|
||||||
|
|
|
@ -17,12 +17,12 @@ Organize module headers as follows:
|
||||||
Avoid using `#[path="..."]` directives; make the file system and
|
Avoid using `#[path="..."]` directives; make the file system and
|
||||||
module hierarchy match, instead.
|
module hierarchy match, instead.
|
||||||
|
|
||||||
### Use the module hirearchy to organize APIs into coherent sections. [FIXME]
|
### Use the module hierarchy to organize APIs into coherent sections. [FIXME]
|
||||||
|
|
||||||
> **[FIXME]** Flesh this out with examples; explain what a "coherent
|
> **[FIXME]** Flesh this out with examples; explain what a "coherent
|
||||||
> section" is with examples.
|
> section" is with examples.
|
||||||
>
|
>
|
||||||
> The module hirearchy defines both the public and internal API of your module.
|
> The module hierarchy defines both the public and internal API of your module.
|
||||||
> Breaking related functionality into submodules makes it understandable to both
|
> Breaking related functionality into submodules makes it understandable to both
|
||||||
> users and contributors to the module.
|
> users and contributors to the module.
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ io/mod.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
While it is possible to define all of `io` within a single directory,
|
While it is possible to define all of `io` within a single directory,
|
||||||
mirroring the module hirearchy in the directory structure makes
|
mirroring the module hierarchy in the directory structure makes
|
||||||
submodules of `io::net` easier to find.
|
submodules of `io::net` easier to find.
|
||||||
|
|
||||||
### Consider top-level definitions or reexports. [FIXME: needs RFC]
|
### Consider top-level definitions or reexports. [FIXME: needs RFC]
|
||||||
|
@ -104,13 +104,13 @@ while
|
||||||
[`TcpStream`](https://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
|
[`TcpStream`](https://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
|
||||||
is defined in `io/net/tcp.rs` and reexported in the `io` module.
|
is defined in `io/net/tcp.rs` and reexported in the `io` module.
|
||||||
|
|
||||||
### Use internal module hirearchies for organization. [FIXME: needs RFC]
|
### Use internal module hierarchies for organization. [FIXME: needs RFC]
|
||||||
|
|
||||||
> **[FIXME]**
|
> **[FIXME]**
|
||||||
> - Referencing internal modules from the standard library is subject to
|
> - Referencing internal modules from the standard library is subject to
|
||||||
> becoming outdated.
|
> becoming outdated.
|
||||||
|
|
||||||
Internal module hirearchies (i.e., private submodules) may be used to
|
Internal module hierarchies (i.e., private submodules) may be used to
|
||||||
hide implementation details that are not part of the module's API.
|
hide implementation details that are not part of the module's API.
|
||||||
|
|
||||||
For example, in [`std::io`](https://doc.rust-lang.org/std/io/), `mod mem`
|
For example, in [`std::io`](https://doc.rust-lang.org/std/io/), `mod mem`
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
> **[FIXME]** We probably want to discourage this, at least when used in a way
|
> **[FIXME]** We probably want to discourage this, at least when used in a way
|
||||||
> that is publicly exposed.
|
> that is publicly exposed.
|
||||||
|
|
||||||
Traits that provide default implmentations for function can provide code reuse
|
Traits that provide default implementations for function can provide code reuse
|
||||||
across types. For example, a `print` method can be defined across multiple
|
across types. For example, a `print` method can be defined across multiple
|
||||||
types as follows:
|
types as follows:
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ Hoare in 1985.
|
||||||
> dining room, furnished with a circular table, surrounded by five chairs, each
|
> dining room, furnished with a circular table, surrounded by five chairs, each
|
||||||
> labelled by the name of the philosopher who was to sit in it. They sat
|
> labelled by the name of the philosopher who was to sit in it. They sat
|
||||||
> anticlockwise around the table. To the left of each philosopher there was
|
> anticlockwise around the table. To the left of each philosopher there was
|
||||||
> laid a golden fork, and in the centre stood a large bowl of spaghetti, which
|
> laid a golden fork, and in the center stood a large bowl of spaghetti, which
|
||||||
> was constantly replenished. A philosopher was expected to spend most of
|
> was constantly replenished. A philosopher was expected to spend most of
|
||||||
> their time thinking; but when they felt hungry, they went to the dining
|
> their time thinking; but when they felt hungry, they went to the dining
|
||||||
> room, sat down in their own chair, picked up their own fork on their left,
|
> room, sat down in their own chair, picked up their own fork on their left,
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
* `pub`: denotes public visibility in `struct` fields, `impl` blocks, and modules. See [Crates and Modules (Exporting a Public Interface)].
|
* `pub`: denotes public visibility in `struct` fields, `impl` blocks, and modules. See [Crates and Modules (Exporting a Public Interface)].
|
||||||
* `ref`: by-reference binding. See [Patterns (`ref` and `ref mut`)].
|
* `ref`: by-reference binding. See [Patterns (`ref` and `ref mut`)].
|
||||||
* `return`: return from function. See [Functions (Early Returns)].
|
* `return`: return from function. See [Functions (Early Returns)].
|
||||||
* `Self`: implementer type alias. See [Traits].
|
* `Self`: implementor type alias. See [Traits].
|
||||||
* `self`: method subject. See [Method Syntax (Method Calls)].
|
* `self`: method subject. See [Method Syntax (Method Calls)].
|
||||||
* `static`: global variable. See [`const` and `static` (`static`)].
|
* `static`: global variable. See [`const` and `static` (`static`)].
|
||||||
* `struct`: structure definition. See [Structs].
|
* `struct`: structure definition. See [Structs].
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
* `/` (`expr / expr`): arithmetic division. Overloadable (`Div`).
|
* `/` (`expr / expr`): arithmetic division. Overloadable (`Div`).
|
||||||
* `/=` (`var /= expr`): arithmetic division & assignment.
|
* `/=` (`var /= expr`): arithmetic division & assignment.
|
||||||
* `:` (`pat: type`, `ident: type`): constraints. See [Variable Bindings], [Functions], [Structs], [Traits].
|
* `:` (`pat: type`, `ident: type`): constraints. See [Variable Bindings], [Functions], [Structs], [Traits].
|
||||||
* `:` (`ident: expr`): struct field initialiser. See [Structs].
|
* `:` (`ident: expr`): struct field initializer. See [Structs].
|
||||||
* `:` (`'a: loop {…}`): loop label. See [Loops (Loops Labels)].
|
* `:` (`'a: loop {…}`): loop label. See [Loops (Loops Labels)].
|
||||||
* `;`: statement and item terminator.
|
* `;`: statement and item terminator.
|
||||||
* `;` (`[…; len]`): part of fixed-size array syntax. See [Primitive Types (Arrays)].
|
* `;` (`[…; len]`): part of fixed-size array syntax. See [Primitive Types (Arrays)].
|
||||||
|
@ -153,12 +153,12 @@
|
||||||
<!-- Various things involving parens and tuples -->
|
<!-- Various things involving parens and tuples -->
|
||||||
|
|
||||||
* `()`: empty tuple (*a.k.a.* unit), both literal and type.
|
* `()`: empty tuple (*a.k.a.* unit), both literal and type.
|
||||||
* `(expr)`: parenthesised expression.
|
* `(expr)`: parenthesized expression.
|
||||||
* `(expr,)`: single-element tuple expression. See [Primitive Types (Tuples)].
|
* `(expr,)`: single-element tuple expression. See [Primitive Types (Tuples)].
|
||||||
* `(type,)`: single-element tuple type. See [Primitive Types (Tuples)].
|
* `(type,)`: single-element tuple type. See [Primitive Types (Tuples)].
|
||||||
* `(expr, …)`: tuple expression. See [Primitive Types (Tuples)].
|
* `(expr, …)`: tuple expression. See [Primitive Types (Tuples)].
|
||||||
* `(type, …)`: tuple type. See [Primitive Types (Tuples)].
|
* `(type, …)`: tuple type. See [Primitive Types (Tuples)].
|
||||||
* `expr(expr, …)`: function call expression. Also used to initialise tuple `struct`s and tuple `enum` variants. See [Functions].
|
* `expr(expr, …)`: function call expression. Also used to initialize tuple `struct`s and tuple `enum` variants. See [Functions].
|
||||||
* `ident!(…)`, `ident!{…}`, `ident![…]`: macro invocation. See [Macros].
|
* `ident!(…)`, `ident!{…}`, `ident![…]`: macro invocation. See [Macros].
|
||||||
* `expr.0`, `expr.1`, …: tuple indexing. See [Primitive Types (Tuple Indexing)].
|
* `expr.0`, `expr.1`, …: tuple indexing. See [Primitive Types (Tuple Indexing)].
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ Could not compile `hello`.
|
||||||
To learn more, run the command again with --verbose.
|
To learn more, run the command again with --verbose.
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionaly, variable bindings can be shadowed. This means that a later
|
Additionally, variable bindings can be shadowed. This means that a later
|
||||||
variable binding with the same name as another binding, that's currently in
|
variable binding with the same name as another binding, that's currently in
|
||||||
scope, will override the previous binding.
|
scope, will override the previous binding.
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl<T> RawVec<T> {
|
||||||
|
|
||||||
/// Reconstitutes a RawVec from a pointer and capacity.
|
/// Reconstitutes a RawVec from a pointer and capacity.
|
||||||
///
|
///
|
||||||
/// # Undefined Behaviour
|
/// # Undefined Behavior
|
||||||
///
|
///
|
||||||
/// The ptr must be allocated, and with the given capacity. The
|
/// The ptr must be allocated, and with the given capacity. The
|
||||||
/// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
/// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
|
||||||
|
@ -248,7 +248,7 @@ impl<T> RawVec<T> {
|
||||||
///
|
///
|
||||||
/// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
|
/// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
|
||||||
/// the requested space. This is not really unsafe, but the unsafe
|
/// the requested space. This is not really unsafe, but the unsafe
|
||||||
/// code *you* write that relies on the behaviour of this function may break.
|
/// code *you* write that relies on the behavior of this function may break.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
@ -302,12 +302,12 @@ impl<T> RawVec<T> {
|
||||||
/// Ensures that the buffer contains at least enough space to hold
|
/// Ensures that the buffer contains at least enough space to hold
|
||||||
/// `used_cap + needed_extra_cap` elements. If it doesn't already have
|
/// `used_cap + needed_extra_cap` elements. If it doesn't already have
|
||||||
/// enough capacity, will reallocate enough space plus comfortable slack
|
/// enough capacity, will reallocate enough space plus comfortable slack
|
||||||
/// space to get amortized `O(1)` behaviour. Will limit this behaviour
|
/// space to get amortized `O(1)` behavior. Will limit this behavior
|
||||||
/// if it would needlessly cause itself to panic.
|
/// if it would needlessly cause itself to panic.
|
||||||
///
|
///
|
||||||
/// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
|
/// If `used_cap` exceeds `self.cap()`, this may fail to actually allocate
|
||||||
/// the requested space. This is not really unsafe, but the unsafe
|
/// the requested space. This is not really unsafe, but the unsafe
|
||||||
/// code *you* write that relies on the behaviour of this function may break.
|
/// code *you* write that relies on the behavior of this function may break.
|
||||||
///
|
///
|
||||||
/// This is ideal for implementing a bulk-push operation like `extend`.
|
/// This is ideal for implementing a bulk-push operation like `extend`.
|
||||||
///
|
///
|
||||||
|
@ -430,7 +430,7 @@ impl<T> RawVec<T> {
|
||||||
|
|
||||||
/// Converts the entire buffer into `Box<[T]>`.
|
/// Converts the entire buffer into `Box<[T]>`.
|
||||||
///
|
///
|
||||||
/// While it is not *strictly* Undefined Behaviour to call
|
/// While it is not *strictly* Undefined Behavior to call
|
||||||
/// this procedure while some of the RawVec is unintialized,
|
/// this procedure while some of the RawVec is unintialized,
|
||||||
/// it cetainly makes it trivial to trigger it.
|
/// it cetainly makes it trivial to trigger it.
|
||||||
///
|
///
|
||||||
|
|
|
@ -949,7 +949,7 @@ impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap<K, V>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Genericises over how to get the correct type of iterator from the correct type
|
/// Genericizes over how to get the correct type of iterator from the correct type
|
||||||
/// of Node ownership.
|
/// of Node ownership.
|
||||||
trait Traverse<N> {
|
trait Traverse<N> {
|
||||||
fn traverse(node: N) -> Self;
|
fn traverse(node: N) -> Self;
|
||||||
|
|
|
@ -818,7 +818,7 @@ impl<K, V, NodeRef> Handle<NodeRef, handle::Edge, handle::Internal> where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle an underflow in this node's child. We favour handling "to the left" because we know
|
/// Handle an underflow in this node's child. We favor handling "to the left" because we know
|
||||||
/// we're empty, but our neighbour can be full. Handling to the left means when we choose to
|
/// we're empty, but our neighbour can be full. Handling to the left means when we choose to
|
||||||
/// steal, we pop off the end of our neighbour (always fast) and "unshift" ourselves
|
/// steal, we pop off the end of our neighbour (always fast) and "unshift" ourselves
|
||||||
/// (always slow, but at least faster since we know we're half-empty).
|
/// (always slow, but at least faster since we know we're half-empty).
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub trait Write {
|
||||||
self.write_str(unsafe { str::from_utf8_unchecked(&utf_8[..bytes_written]) })
|
self.write_str(unsafe { str::from_utf8_unchecked(&utf_8[..bytes_written]) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Glue for usage of the `write!` macro with implementers of this trait.
|
/// Glue for usage of the `write!` macro with implementors of this trait.
|
||||||
///
|
///
|
||||||
/// This method should generally not be invoked manually, but rather through
|
/// This method should generally not be invoked manually, but rather through
|
||||||
/// the `write!` macro itself.
|
/// the `write!` macro itself.
|
||||||
|
@ -523,7 +523,7 @@ pub trait Binary {
|
||||||
|
|
||||||
/// Format trait for the `x` character.
|
/// Format trait for the `x` character.
|
||||||
///
|
///
|
||||||
/// The `LowerHex` trait should format its output as a number in hexidecimal, with `a` through `f`
|
/// The `LowerHex` trait should format its output as a number in hexadecimal, with `a` through `f`
|
||||||
/// in lower case.
|
/// in lower case.
|
||||||
///
|
///
|
||||||
/// The alternate flag, `#`, adds a `0x` in front of the output.
|
/// The alternate flag, `#`, adds a `0x` in front of the output.
|
||||||
|
@ -571,7 +571,7 @@ pub trait LowerHex {
|
||||||
|
|
||||||
/// Format trait for the `X` character.
|
/// Format trait for the `X` character.
|
||||||
///
|
///
|
||||||
/// The `UpperHex` trait should format its output as a number in hexidecimal, with `A` through `F`
|
/// The `UpperHex` trait should format its output as a number in hexadecimal, with `A` through `F`
|
||||||
/// in upper case.
|
/// in upper case.
|
||||||
///
|
///
|
||||||
/// The alternate flag, `#`, adds a `0x` in front of the output.
|
/// The alternate flag, `#`, adds a `0x` in front of the output.
|
||||||
|
@ -620,7 +620,7 @@ pub trait UpperHex {
|
||||||
/// Format trait for the `p` character.
|
/// Format trait for the `p` character.
|
||||||
///
|
///
|
||||||
/// The `Pointer` trait should format its output as a memory location. This is commonly presented
|
/// The `Pointer` trait should format its output as a memory location. This is commonly presented
|
||||||
/// as hexidecimal.
|
/// as hexadecimal.
|
||||||
///
|
///
|
||||||
/// For more information on formatters, see [the module-level documentation][module].
|
/// For more information on formatters, see [the module-level documentation][module].
|
||||||
///
|
///
|
||||||
|
|
|
@ -301,7 +301,7 @@ extern "rust-intrinsic" {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Beyond requiring that the program must be allowed to access both regions
|
/// Beyond requiring that the program must be allowed to access both regions
|
||||||
/// of memory, it is Undefined Behaviour for source and destination to
|
/// of memory, it is Undefined Behavior for source and destination to
|
||||||
/// overlap. Care must also be taken with the ownership of `src` and
|
/// overlap. Care must also be taken with the ownership of `src` and
|
||||||
/// `dst`. This method semantically moves the values of `src` into `dst`.
|
/// `dst`. This method semantically moves the values of `src` into `dst`.
|
||||||
/// However it does not drop the contents of `dst`, or prevent the contents
|
/// However it does not drop the contents of `dst`, or prevent the contents
|
||||||
|
|
|
@ -1453,7 +1453,7 @@ pub trait Iterator {
|
||||||
///
|
///
|
||||||
/// This is an idiosyncratic helper to try to factor out the
|
/// This is an idiosyncratic helper to try to factor out the
|
||||||
/// commonalities of {max,min}{,_by}. In particular, this avoids
|
/// commonalities of {max,min}{,_by}. In particular, this avoids
|
||||||
/// having to implement optimisations several times.
|
/// having to implement optimizations several times.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn select_fold1<I,B, FProj, FCmp>(mut it: I,
|
fn select_fold1<I,B, FProj, FCmp>(mut it: I,
|
||||||
mut f_proj: FProj,
|
mut f_proj: FProj,
|
||||||
|
|
|
@ -279,7 +279,7 @@ macro_rules! unreachable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A standardised placeholder for marking unfinished code. It panics with the
|
/// A standardized placeholder for marking unfinished code. It panics with the
|
||||||
/// message `"not yet implemented"` when executed.
|
/// message `"not yet implemented"` when executed.
|
||||||
///
|
///
|
||||||
/// This can be useful if you are prototyping and are just looking to have your
|
/// This can be useful if you are prototyping and are just looking to have your
|
||||||
|
|
|
@ -172,7 +172,7 @@ pub trait Copy : Clone {
|
||||||
///
|
///
|
||||||
/// A somewhat surprising consequence of the definition is `&mut T` is
|
/// A somewhat surprising consequence of the definition is `&mut T` is
|
||||||
/// `Sync` (if `T` is `Sync`) even though it seems that it might
|
/// `Sync` (if `T` is `Sync`) even though it seems that it might
|
||||||
/// provide unsynchronised mutation. The trick is a mutable reference
|
/// provide unsynchronized mutation. The trick is a mutable reference
|
||||||
/// stored in an aliasable reference (that is, `& &mut T`) becomes
|
/// stored in an aliasable reference (that is, `& &mut T`) becomes
|
||||||
/// read-only, as if it were a `& &T`, hence there is no risk of a data
|
/// read-only, as if it were a `& &T`, hence there is no risk of a data
|
||||||
/// race.
|
/// race.
|
||||||
|
@ -195,7 +195,7 @@ pub trait Copy : Clone {
|
||||||
///
|
///
|
||||||
/// Any types with interior mutability must also use the `std::cell::UnsafeCell`
|
/// Any types with interior mutability must also use the `std::cell::UnsafeCell`
|
||||||
/// wrapper around the value(s) which can be mutated when behind a `&`
|
/// wrapper around the value(s) which can be mutated when behind a `&`
|
||||||
/// reference; not doing this is undefined behaviour (for example,
|
/// reference; not doing this is undefined behavior (for example,
|
||||||
/// `transmute`-ing from `&T` to `&mut T` is invalid).
|
/// `transmute`-ing from `&T` to `&mut T` is invalid).
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[lang = "sync"]
|
#[lang = "sync"]
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub use intrinsics::transmute;
|
||||||
/// * You have two copies of a value (like when writing something like
|
/// * You have two copies of a value (like when writing something like
|
||||||
/// [`mem::swap`][swap]), but need the destructor to only run once to
|
/// [`mem::swap`][swap]), but need the destructor to only run once to
|
||||||
/// prevent a double `free`.
|
/// prevent a double `free`.
|
||||||
/// * Transferring resources across [FFI][ffi] boundries.
|
/// * Transferring resources across [FFI][ffi] boundaries.
|
||||||
///
|
///
|
||||||
/// [swap]: fn.swap.html
|
/// [swap]: fn.swap.html
|
||||||
/// [ffi]: ../../book/ffi.html
|
/// [ffi]: ../../book/ffi.html
|
||||||
|
@ -264,9 +264,9 @@ pub unsafe fn dropped<T>() -> T {
|
||||||
/// This is useful for FFI functions and initializing arrays sometimes,
|
/// This is useful for FFI functions and initializing arrays sometimes,
|
||||||
/// but should generally be avoided.
|
/// but should generally be avoided.
|
||||||
///
|
///
|
||||||
/// # Undefined Behaviour
|
/// # Undefined Behavior
|
||||||
///
|
///
|
||||||
/// It is Undefined Behaviour to read uninitialized memory. Even just an
|
/// It is Undefined Behavior to read uninitialized memory. Even just an
|
||||||
/// uninitialized boolean. For instance, if you branch on the value of such
|
/// uninitialized boolean. For instance, if you branch on the value of such
|
||||||
/// a boolean your program may take one, both, or neither of the branches.
|
/// a boolean your program may take one, both, or neither of the branches.
|
||||||
///
|
///
|
||||||
|
@ -303,7 +303,7 @@ pub unsafe fn dropped<T>() -> T {
|
||||||
///
|
///
|
||||||
/// // DANGER ZONE: if anything panics or otherwise
|
/// // DANGER ZONE: if anything panics or otherwise
|
||||||
/// // incorrectly reads the array here, we will have
|
/// // incorrectly reads the array here, we will have
|
||||||
/// // Undefined Behaviour.
|
/// // Undefined Behavior.
|
||||||
///
|
///
|
||||||
/// // It's ok to mutably iterate the data, since this
|
/// // It's ok to mutably iterate the data, since this
|
||||||
/// // doesn't involve reading it at all.
|
/// // doesn't involve reading it at all.
|
||||||
|
@ -340,7 +340,7 @@ pub unsafe fn uninitialized<T>() -> T {
|
||||||
intrinsics::uninit()
|
intrinsics::uninit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the values at two mutable locations of the same type, without deinitialising or copying
|
/// Swap the values at two mutable locations of the same type, without deinitializing or copying
|
||||||
/// either one.
|
/// either one.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -376,7 +376,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces the value at a mutable location with a new one, returning the old value, without
|
/// Replaces the value at a mutable location with a new one, returning the old value, without
|
||||||
/// deinitialising or copying either one.
|
/// deinitializing or copying either one.
|
||||||
///
|
///
|
||||||
/// This is primarily used for transferring and swapping ownership of a value in a mutable
|
/// This is primarily used for transferring and swapping ownership of a value in a mutable
|
||||||
/// location.
|
/// location.
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub const fn null<T>() -> *const T { 0 as *const T }
|
||||||
pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
|
pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
|
||||||
|
|
||||||
/// Swaps the values at two mutable locations of the same type, without
|
/// Swaps the values at two mutable locations of the same type, without
|
||||||
/// deinitialising either. They may overlap, unlike `mem::swap` which is
|
/// deinitializing either. They may overlap, unlike `mem::swap` which is
|
||||||
/// otherwise equivalent.
|
/// otherwise equivalent.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -247,7 +247,7 @@ impl<T: ?Sized> *mut T {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The offset must be in-bounds of the object, or one-byte-past-the-end.
|
/// The offset must be in-bounds of the object, or one-byte-past-the-end.
|
||||||
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
|
/// Otherwise `offset` invokes Undefined Behavior, regardless of whether
|
||||||
/// the pointer is used.
|
/// the pointer is used.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl<T> Clone for Slice<T> {
|
||||||
/// Synthesizing a trait object with mismatched types—one where the
|
/// Synthesizing a trait object with mismatched types—one where the
|
||||||
/// vtable does not correspond to the type of the value to which the
|
/// vtable does not correspond to the type of the value to which the
|
||||||
/// data pointer points—is highly likely to lead to undefined
|
/// data pointer points—is highly likely to lead to undefined
|
||||||
/// behaviour.
|
/// behavior.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -965,7 +965,7 @@ impl<'a> DoubleEndedIterator for Lines<'a> {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub struct LinesAny<'a>(Lines<'a>);
|
pub struct LinesAny<'a>(Lines<'a>);
|
||||||
|
|
||||||
/// A nameable, clonable fn type
|
/// A nameable, cloneable fn type
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct LinesAnyMap;
|
struct LinesAnyMap;
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub enum Count<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The parser structure for interpreting the input format string. This is
|
/// The parser structure for interpreting the input format string. This is
|
||||||
/// modelled as an iterator over `Piece` structures to form a stream of tokens
|
/// modeled as an iterator over `Piece` structures to form a stream of tokens
|
||||||
/// being output.
|
/// being output.
|
||||||
///
|
///
|
||||||
/// This is a recursive-descent parser for the sake of simplicity, and if
|
/// This is a recursive-descent parser for the sake of simplicity, and if
|
||||||
|
|
|
@ -456,7 +456,7 @@ pub trait Labeller<'a,N,E> {
|
||||||
fn graph_id(&'a self) -> Id<'a>;
|
fn graph_id(&'a self) -> Id<'a>;
|
||||||
|
|
||||||
/// Maps `n` to a unique identifier with respect to `self`. The
|
/// Maps `n` to a unique identifier with respect to `self`. The
|
||||||
/// implementer is responsible for ensuring that the returned name
|
/// implementor is responsible for ensuring that the returned name
|
||||||
/// is a valid DOT identifier.
|
/// is a valid DOT identifier.
|
||||||
fn node_id(&'a self, n: &N) -> Id<'a>;
|
fn node_id(&'a self, n: &N) -> Id<'a>;
|
||||||
|
|
||||||
|
@ -594,7 +594,7 @@ pub type Edges<'a,E> = Cow<'a,[E]>;
|
||||||
/// that is bound by the self lifetime `'a`.
|
/// that is bound by the self lifetime `'a`.
|
||||||
///
|
///
|
||||||
/// The `nodes` and `edges` method each return instantiations of
|
/// The `nodes` and `edges` method each return instantiations of
|
||||||
/// `Cow<[T]>` to leave implementers the freedom to create
|
/// `Cow<[T]>` to leave implementors the freedom to create
|
||||||
/// entirely new vectors or to pass back slices into internally owned
|
/// entirely new vectors or to pass back slices into internally owned
|
||||||
/// vectors.
|
/// vectors.
|
||||||
pub trait GraphWalk<'a, N: Clone, E: Clone> {
|
pub trait GraphWalk<'a, N: Clone, E: Clone> {
|
||||||
|
|
|
@ -168,7 +168,7 @@ impl IndependentSample<f64> for GammaLargeShape {
|
||||||
///
|
///
|
||||||
/// For `k > 0` integral, this distribution is the sum of the squares
|
/// For `k > 0` integral, this distribution is the sum of the squares
|
||||||
/// of `k` independent standard normal random variables. For other
|
/// of `k` independent standard normal random variables. For other
|
||||||
/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
|
/// `k`, this uses the equivalent characterization `χ²(k) = Gamma(k/2,
|
||||||
/// 2)`.
|
/// 2)`.
|
||||||
pub struct ChiSquared {
|
pub struct ChiSquared {
|
||||||
repr: ChiSquaredRepr,
|
repr: ChiSquaredRepr,
|
||||||
|
|
|
@ -207,7 +207,7 @@ fn test_resize_policy() {
|
||||||
/// The hashes are all keyed by the thread-local random number generator
|
/// The hashes are all keyed by the thread-local random number generator
|
||||||
/// on creation by default. This means that the ordering of the keys is
|
/// on creation by default. This means that the ordering of the keys is
|
||||||
/// randomized, but makes the tables more resistant to
|
/// randomized, but makes the tables more resistant to
|
||||||
/// denial-of-service attacks (Hash DoS). This behaviour can be
|
/// denial-of-service attacks (Hash DoS). This behavior can be
|
||||||
/// overridden with one of the constructors.
|
/// overridden with one of the constructors.
|
||||||
///
|
///
|
||||||
/// It is required that the keys implement the `Eq` and `Hash` traits, although
|
/// It is required that the keys implement the `Eq` and `Hash` traits, although
|
||||||
|
@ -324,7 +324,7 @@ fn search_hashed<K, V, M, F>(table: M,
|
||||||
F: FnMut(&K) -> bool,
|
F: FnMut(&K) -> bool,
|
||||||
{
|
{
|
||||||
// This is the only function where capacity can be zero. To avoid
|
// This is the only function where capacity can be zero. To avoid
|
||||||
// undefined behaviour when Bucket::new gets the raw bucket in this
|
// undefined behavior when Bucket::new gets the raw bucket in this
|
||||||
// case, immediately return the appropriate search result.
|
// case, immediately return the appropriate search result.
|
||||||
if table.capacity() == 0 {
|
if table.capacity() == 0 {
|
||||||
return TableRef(table);
|
return TableRef(table);
|
||||||
|
|
|
@ -137,7 +137,7 @@
|
||||||
//! not.
|
//! not.
|
||||||
//!
|
//!
|
||||||
//! Slices can only be handled through some kind of *pointer*, and as
|
//! Slices can only be handled through some kind of *pointer*, and as
|
||||||
//! such come in many flavours such as:
|
//! such come in many flavors such as:
|
||||||
//!
|
//!
|
||||||
//! * `&[T]` - *shared slice*
|
//! * `&[T]` - *shared slice*
|
||||||
//! * `&mut [T]` - *mutable slice*
|
//! * `&mut [T]` - *mutable slice*
|
||||||
|
|
|
@ -235,7 +235,7 @@ impl TcpListener {
|
||||||
/// to this listener. The port allocated can be queried via the
|
/// to this listener. The port allocated can be queried via the
|
||||||
/// `socket_addr` function.
|
/// `socket_addr` function.
|
||||||
///
|
///
|
||||||
/// The address type can be any implementer of `ToSocketAddrs` trait. See
|
/// The address type can be any implementor of `ToSocketAddrs` trait. See
|
||||||
/// its documentation for concrete examples.
|
/// its documentation for concrete examples.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
|
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
|
||||||
|
|
|
@ -75,7 +75,7 @@ impl IntoInner<imp::Process> for Child {
|
||||||
fn into_inner(self) -> imp::Process { self.handle }
|
fn into_inner(self) -> imp::Process { self.handle }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handle to a child procesess's stdin
|
/// A handle to a child process's stdin
|
||||||
#[stable(feature = "process", since = "1.0.0")]
|
#[stable(feature = "process", since = "1.0.0")]
|
||||||
pub struct ChildStdin {
|
pub struct ChildStdin {
|
||||||
inner: AnonPipe
|
inner: AnonPipe
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue