about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-12-19 20:38:28 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-12-19 20:38:28 -0700
commit2d313fe5011acfa28b8771c5975be37e1c84fd73 (patch)
tree9f7f4ae8b617697ebda7102eaecd41efe3061c21
parentb865b4b70df27a1e19e7a0cdfedf51d0096da25b (diff)
downloadrust-2d313fe5011acfa28b8771c5975be37e1c84fd73.tar.gz
rust-2d313fe5011acfa28b8771c5975be37e1c84fd73.zip
Update docs to mention trait constraints; also fix failing doc tests
/cc #4217
-rw-r--r--doc/rust.md21
-rw-r--r--doc/tutorial.md33
2 files changed, 51 insertions, 3 deletions
diff --git a/doc/rust.md b/doc/rust.md
index c73211acef9..8bff1aa37af 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -1195,8 +1195,19 @@ Values with a trait type can have [methods called](#method-call-expressions) on
 for any method in the trait,
 and can be used to instantiate type parameters that are bounded by the trait.
 
-Trait methods may be static. Currently implementations of static methods behave like
-functions declared in the implentation's module.
+Trait methods may be static.
+Currently, implementations of static methods behave like functions declared in the implementation's module.
+
+Traits can have _constraints_ for example, in
+
+~~~~
+trait Shape { fn area() -> float; }
+trait Circle : Shape { fn radius() -> float; }
+~~~~
+
+the syntax `Circle : Shape` means that types that implement `Circle` must also have an implementation for `Shape`.
+In an implementation of `Circle` for a given type `T`, methods can refer to `Shape` methods,
+since the typechecker checks that any type with an implementation of `Circle` also has an implementation of `Shape`.
 
 ### Implementations
 
@@ -1520,8 +1531,11 @@ To indicate that a field is mutable, the `mut` keyword is written before its nam
 The following are examples of structure expressions:
 
 ~~~~
+# struct Point { x: float, y: float }
+# mod game { pub struct User { name: &str, age: uint, mut score: uint } } 
+# use game;
 Point {x: 10f, y: 20f};
-game::User {name: "Joe", age: 35u, mut score: 100_000};
+let u = game::User {name: "Joe", age: 35u, mut score: 100_000};
 ~~~~
 
 A structure expression forms a new value of the named structure type.
@@ -1532,6 +1546,7 @@ A new structure will be created, of the same type as the base expression, with t
 and the values in the base record for all other fields.
 
 ~~~~
+# struct Point3d { x: int, y: int, z: int }
 let base = Point3d {x: 1, y: 2, z: 3};
 Point3d {y: 0, z: 10, .. base};
 ~~~~
diff --git a/doc/tutorial.md b/doc/tutorial.md
index b7eab9b7921..c7b75993f11 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -2076,6 +2076,39 @@ the preferred way to use traits polymorphically.
 
 This usage of traits is similar to Haskell type classes.
 
+## Trait constraints
+
+We can write a trait declaration that is _constrained_ to only be implementable on types that
+also implement some other trait.
+
+For example, we can define a `Circle` trait that only types that also have the `Shape` trait can have:
+
+~~~~
+trait Shape { fn area() -> float; }
+trait Circle : Shape { fn radius() -> float; }
+~~~~
+
+Now, implementations of `Circle` methods can call `Shape` methods:
+
+~~~~
+# trait Shape { fn area() -> float; }
+# trait Circle : Shape { fn radius() -> float; }
+# struct Point { x: float, y: float }
+# use float::consts::pi;
+# use float::sqrt;
+# fn square(x: float) -> float { x * x }
+struct CircleStruct { center: Point, radius: float }
+impl CircleStruct: Circle {
+     fn radius() -> float { sqrt(self.area() / pi) }
+}
+impl CircleStruct: Shape {
+     fn area() -> float { pi * square(self.radius) }
+}   
+~~~~
+
+This is a silly way to compute the radius of a circle
+(since we could just return the `circle` field), but you get the idea.
+
 ## Trait objects and dynamic method dispatch
 
 The above allows us to define functions that polymorphically act on