about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLindsey Kuper <lindsey@rockstargirl.org>2012-06-20 17:09:30 -0700
committerLindsey Kuper <lindsey@rockstargirl.org>2012-06-20 17:56:40 -0700
commit1df6ddd08c3155e64806cd54b878337814401b7e (patch)
tree92eeef636afd56b8ab20dd2ed10d39b0ce1aa129
parent4dcf84e4f4a9a54254fd426609ad9f1ccffae3b9 (diff)
downloadrust-1df6ddd08c3155e64806cd54b878337814401b7e.tar.gz
rust-1df6ddd08c3155e64806cd54b878337814401b7e.zip
doc: add information about suffix inference to tutorial and manual.
-rw-r--r--doc/rust.md22
-rw-r--r--doc/tutorial.md57
-rw-r--r--src/test/compile-fail/tutorial-suffix-inference-test.rs22
3 files changed, 88 insertions, 13 deletions
diff --git a/doc/rust.md b/doc/rust.md
index b30932ef5c5..3f4e39d95c8 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -330,24 +330,32 @@ An _integer literal_ has one of three forms:
   * A _binary literal_ starts with the character sequence `U+0030` `U+0062`
     (`0b`) and continues as any mixture binary digits and underscores.
 
-By default, an integer literal is of type `int`. An integer literal may be
-followed (immediately, without any spaces) by an _integer suffix_, which
-changes the type of the literal. There are two kinds of integer literal
-suffix:
+An integer literal may be followed (immediately, without any spaces) by an
+_integer suffix_, which changes the type of the literal. There are two kinds
+of integer literal suffix:
 
-  * The `u` suffix gives the literal type `uint`.
+  * The `i` and `u` suffixes give the literal type `int` or `uint`,
+    respectively.
   * Each of the signed and unsigned machine types `u8`, `i8`,
     `u16`, `i16`, `u32`, `i32`, `u64` and `i64`
     give the literal the corresponding machine type.
 
+The type of an _unsuffixed_ integer literal is determined by type inference.
+If a integer type can be _uniquely_ determined from the surrounding program
+context, the unsuffixed integer literal has that type.  If the program context
+underconstrains the type, the unsuffixed integer literal's type is `int`; if
+the program context overconstrains the type, it is considered a static type
+error.
 
 Examples of integer literals of various forms:
 
 ~~~~
-123;                               // type int
+123; 0xff00;                       // type determined by program context; 
+                                   // defaults to int in absence of type
+				   // information
+
 123u;                              // type uint
 123_u;                             // type uint
-0xff00;                            // type int
 0xff_u8;                           // type u8
 0b1111_1111_1001_0000_i32;         // type i32
 ~~~~
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 1ef17c71166..f6c2aef30ea 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -396,15 +396,58 @@ synonym.
 
 ## Literals
 
+### Numeric literals
+
 Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
-binary (`0b10010000`) base. Without a suffix, an integer literal is
-considered to be of type `int`. Add a `u` (`144u`) to make it a `uint`
-instead. Literals of the fixed-size integer types can be created by
-the literal with the type name (`255u8`, `50i64`, etc).
+binary (`0b10010000`) base.
+
+If you write an integer literal without a suffix (`3`, `-500`, etc.),
+the Rust compiler will try to infer its type based on type annotations
+and function signatures in the surrounding program.  For example, here
+the type of `x` is inferred to be `u16` because it is passed to a
+function that takes a `u16` argument:
+
+~~~~~
+let x = 3;
+
+fn identity_u16(n: u16) -> u16 { n }
+
+identity_u16(x);
+~~~~
+
+On the other hand, if the program gives conflicting information about
+what the type of the unsuffixed literal should be, you'll get an error
+message.
+
+~~~~~{.xfail-test}
+let x = 3;
+let y: i32 = 3;
+
+fn identity_u8(n: u8) -> u8 { n }
+fn identity_u16(n: u16) -> u16 { n }
+
+identity_u8(x);  // after this, `x` is assumed to have type `u8`
+identity_u16(x); // raises a type error (expected `u16` but found `u8`)
+identity_u16(y); // raises a type error (expected `u16` but found `i32`)
+~~~~
+
+In the absence of any type annotations at all, Rust will assume that
+an unsuffixed integer literal has type `int`.
+
+~~~~
+let n = 50;
+log(error, n); // n is an int
+~~~~
+
+It's also possible to avoid any type ambiguity by writing integer
+literals with a suffix.  The suffixes `i` and `u` are for the types
+`int` and `uint`, respectively: the literal `-3i` has type `int`,
+while `127u` has type `uint`.  For the fixed-size integer types, just
+suffix the literal with the type name: `255u8`, `50i64`, etc.
 
 Note that, in Rust, no implicit conversion between integer types
-happens. If you are adding one to a variable of type `uint`, you must
-type `v += 1u`—saying `+= 1` will give you a type error.
+happens. If you are adding one to a variable of type `uint`, saying
+`+= 1u8` will give you a type error.
 
 Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`. Without
 a suffix, the literal is assumed to be of type `float`. Suffixes `f32`
@@ -412,6 +455,8 @@ and `f64` can be used to create literals of a specific type. The
 suffix `f` can be used to write `float` literals without a dot or
 exponent: `3f`.
 
+### Other literals
+
 The nil literal is written just like the type: `()`. The keywords
 `true` and `false` produce the boolean literals.
 
diff --git a/src/test/compile-fail/tutorial-suffix-inference-test.rs b/src/test/compile-fail/tutorial-suffix-inference-test.rs
new file mode 100644
index 00000000000..fa07be952c1
--- /dev/null
+++ b/src/test/compile-fail/tutorial-suffix-inference-test.rs
@@ -0,0 +1,22 @@
+fn main() {
+    let x = 3;
+    let y: i32 = 3;
+
+    fn identity_u8(n: u8) -> u8 { n }
+    fn identity_u16(n: u16) -> u16 { n }
+
+    identity_u8(x);  // after this, `x` is assumed to have type `u8`
+    identity_u16(x);
+    //!^ ERROR mismatched types: expected `u16` but found `u8`
+    identity_u16(y);
+    //!^ ERROR mismatched types: expected `u16` but found `i32`
+
+    let a = 3i;
+    
+    fn identity_i(n: int) -> int { n }
+
+    identity_i(a); // ok
+    identity_u16(a); 
+    //!^ ERROR mismatched types: expected `u16` but found `int`
+
+}
\ No newline at end of file