Skip to content

Commit 1df6ddd

Browse files
committed
doc: add information about suffix inference to tutorial and manual.
1 parent 4dcf84e commit 1df6ddd

File tree

3 files changed

+88
-13
lines changed

3 files changed

+88
-13
lines changed

doc/rust.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,24 +330,32 @@ An _integer literal_ has one of three forms:
330330
* A _binary literal_ starts with the character sequence `U+0030` `U+0062`
331331
(`0b`) and continues as any mixture binary digits and underscores.
332332

333-
By default, an integer literal is of type `int`. An integer literal may be
334-
followed (immediately, without any spaces) by an _integer suffix_, which
335-
changes the type of the literal. There are two kinds of integer literal
336-
suffix:
333+
An integer literal may be followed (immediately, without any spaces) by an
334+
_integer suffix_, which changes the type of the literal. There are two kinds
335+
of integer literal suffix:
337336

338-
* The `u` suffix gives the literal type `uint`.
337+
* The `i` and `u` suffixes give the literal type `int` or `uint`,
338+
respectively.
339339
* Each of the signed and unsigned machine types `u8`, `i8`,
340340
`u16`, `i16`, `u32`, `i32`, `u64` and `i64`
341341
give the literal the corresponding machine type.
342342

343+
The type of an _unsuffixed_ integer literal is determined by type inference.
344+
If a integer type can be _uniquely_ determined from the surrounding program
345+
context, the unsuffixed integer literal has that type. If the program context
346+
underconstrains the type, the unsuffixed integer literal's type is `int`; if
347+
the program context overconstrains the type, it is considered a static type
348+
error.
343349

344350
Examples of integer literals of various forms:
345351

346352
~~~~
347-
123; // type int
353+
123; 0xff00; // type determined by program context;
354+
// defaults to int in absence of type
355+
// information
356+
348357
123u; // type uint
349358
123_u; // type uint
350-
0xff00; // type int
351359
0xff_u8; // type u8
352360
0b1111_1111_1001_0000_i32; // type i32
353361
~~~~

doc/tutorial.md

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,22 +396,67 @@ synonym.
396396

397397
## Literals
398398

399+
### Numeric literals
400+
399401
Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
400-
binary (`0b10010000`) base. Without a suffix, an integer literal is
401-
considered to be of type `int`. Add a `u` (`144u`) to make it a `uint`
402-
instead. Literals of the fixed-size integer types can be created by
403-
the literal with the type name (`255u8`, `50i64`, etc).
402+
binary (`0b10010000`) base.
403+
404+
If you write an integer literal without a suffix (`3`, `-500`, etc.),
405+
the Rust compiler will try to infer its type based on type annotations
406+
and function signatures in the surrounding program. For example, here
407+
the type of `x` is inferred to be `u16` because it is passed to a
408+
function that takes a `u16` argument:
409+
410+
~~~~~
411+
let x = 3;
412+
413+
fn identity_u16(n: u16) -> u16 { n }
414+
415+
identity_u16(x);
416+
~~~~
417+
418+
On the other hand, if the program gives conflicting information about
419+
what the type of the unsuffixed literal should be, you'll get an error
420+
message.
421+
422+
~~~~~{.xfail-test}
423+
let x = 3;
424+
let y: i32 = 3;
425+
426+
fn identity_u8(n: u8) -> u8 { n }
427+
fn identity_u16(n: u16) -> u16 { n }
428+
429+
identity_u8(x); // after this, `x` is assumed to have type `u8`
430+
identity_u16(x); // raises a type error (expected `u16` but found `u8`)
431+
identity_u16(y); // raises a type error (expected `u16` but found `i32`)
432+
~~~~
433+
434+
In the absence of any type annotations at all, Rust will assume that
435+
an unsuffixed integer literal has type `int`.
436+
437+
~~~~
438+
let n = 50;
439+
log(error, n); // n is an int
440+
~~~~
441+
442+
It's also possible to avoid any type ambiguity by writing integer
443+
literals with a suffix. The suffixes `i` and `u` are for the types
444+
`int` and `uint`, respectively: the literal `-3i` has type `int`,
445+
while `127u` has type `uint`. For the fixed-size integer types, just
446+
suffix the literal with the type name: `255u8`, `50i64`, etc.
404447
405448
Note that, in Rust, no implicit conversion between integer types
406-
happens. If you are adding one to a variable of type `uint`, you must
407-
type `v += 1u`—saying `+= 1` will give you a type error.
449+
happens. If you are adding one to a variable of type `uint`, saying
450+
`+= 1u8` will give you a type error.
408451
409452
Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`. Without
410453
a suffix, the literal is assumed to be of type `float`. Suffixes `f32`
411454
and `f64` can be used to create literals of a specific type. The
412455
suffix `f` can be used to write `float` literals without a dot or
413456
exponent: `3f`.
414457
458+
### Other literals
459+
415460
The nil literal is written just like the type: `()`. The keywords
416461
`true` and `false` produce the boolean literals.
417462
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fn main() {
2+
let x = 3;
3+
let y: i32 = 3;
4+
5+
fn identity_u8(n: u8) -> u8 { n }
6+
fn identity_u16(n: u16) -> u16 { n }
7+
8+
identity_u8(x); // after this, `x` is assumed to have type `u8`
9+
identity_u16(x);
10+
//!^ ERROR mismatched types: expected `u16` but found `u8`
11+
identity_u16(y);
12+
//!^ ERROR mismatched types: expected `u16` but found `i32`
13+
14+
let a = 3i;
15+
16+
fn identity_i(n: int) -> int { n }
17+
18+
identity_i(a); // ok
19+
identity_u16(a);
20+
//!^ ERROR mismatched types: expected `u16` but found `int`
21+
22+
}

0 commit comments

Comments
 (0)