]> git.lizzy.rs Git - rust.git/commitdiff
Review fixes
authorManish Goregaokar <manishsmail@gmail.com>
Sat, 11 Jul 2015 20:30:35 +0000 (02:00 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Thu, 23 Jul 2015 07:19:25 +0000 (12:49 +0530)
src/librustc/diagnostics.rs

index 949f4457aa3240fcf58d04b13a27f09d710940ec..c7a20f243b0c199e82302214bc95c41d1406765c 100644 (file)
@@ -55,10 +55,9 @@ fn foo(x: Empty) {
         // empty
     }
 }
-
 ```
 
-but this won't:
+However, this won't:
 
 ```
 fn foo(x: Option<String>) {
@@ -71,7 +70,18 @@ fn foo(x: Option<String>) {
 
 E0003: r##"
 Not-a-Number (NaN) values cannot be compared for equality and hence can never
-match the input to a match expression. To match against NaN values, you should
+match the input to a match expression. So, the following will not compile:
+
+```
+const NAN: f32 = 0.0 / 0.0;
+
+match number {
+    NAN => { /* ... */ },
+    // ...
+}
+```
+
+To match against NaN values, you should
 instead use the `is_nan()` method in a guard, like so:
 
 ```
@@ -429,22 +439,20 @@ const fn foo(mut x: u8) {
 "##,
 
 E0038: r####"
+Trait objects like `Box<Trait>` can only be constructed when certain
+requirements are satisfied by the trait in question.
 
-Trait objects like `Box<Trait>`, can only be constructed when certain
-requirements are obeyed by the trait in question.
-
-Trait objects are a form of dynamic dispatch and use dynamically sized types.
-So, for a given trait `Trait`, when `Trait` is treated as a type, as in
-`Box<Trait>`, the inner type is "unsized". In such cases the boxed pointer is a
-"fat pointer" and contains an extra pointer to a method table for dynamic
-dispatch. This design mandates some restrictions on the types of traits that are
-allowed to be used in trait objects, which are collectively termed as "object
-safety" rules.
+Trait objects are a form of dynamic dispatch and use a dynamically sized type
+for the inner type. So, for a given trait `Trait`, when `Trait` is treated as a
+type, as in `Box<Trait>`, the inner type is "unsized". In such cases the boxed
+pointer is a "fat pointer" that contains an extra pointer to a table of methods
+(among other things) for dynamic dispatch. This design mandates some
+restrictions on the types of traits that are allowed to be used in trait
+objects, which are collectively termed as "object safety" rules.
 
 Attempting to create a trait object for a non object-safe trait will trigger
 this error.
 
-
 There are various rules:
 
 ### The trait cannot require `Self: Sized`
@@ -463,7 +471,7 @@ trait Foo where Self: Sized {
 we cannot create an object of type `Box<Foo>` or `&Foo` since in this case
 `Self` would not be `Sized`.
 
-Generally `Self : Sized` is used to indicate that the trait should not be used
+Generally, `Self : Sized` is used to indicate that the trait should not be used
 as a trait object. If the trait comes from your own crate, consider removing
 this restriction.
 
@@ -475,6 +483,7 @@ trait Foo where Self: Sized {
 trait Trait {
     fn foo(&self) -> Self;
 }
+
 impl Trait for String {
     fn foo(&self) -> Self {
         "hi".to_owned()
@@ -488,8 +497,11 @@ fn foo(&self) -> Self {
 }
 ```
 
-In such a case, the compiler cannot predict the return type of `foo()` in a case
-like the following:
+(Note that `&self` and `&mut self` are okay, it's additional `Self` types which
+cause this problem)
+
+In such a case, the compiler cannot predict the return type of `foo()` in a
+situation like the following:
 
 ```
 fn call_foo(x: Box<Trait>) {
@@ -498,8 +510,10 @@ fn call_foo(x: Box<Trait>) {
 }
 ```
 
-If the offending method isn't actually being called on the trait object, you can
-add a `where Self: Sized` bound on the method:
+If only some methods aren't object-safe, you can add a `where Self: Sized` bound
+on them to mark them as explicitly unavailable to trait objects. The
+functionality will still be available to all other implementers, including
+`Box<Trait>` which is itself sized (assuming you `impl Trait for Box<Trait>`)
 
 ```
 trait Trait {
@@ -508,10 +522,10 @@ trait Trait {
 }
 ```
 
-Now, `foo()` can no longer be called on the trait object, but you will be
-allowed to call other trait methods and construct the trait objects. With such a
-bound, one can still call `foo()` on types implementing that trait that aren't
-behind trait objects.
+Now, `foo()` can no longer be called on a trait object, but you will now be
+allowed to make a trait object, and that will be able to call any object-safe
+methods". With such a bound, one can still call `foo()` on types implementing
+that trait that aren't behind trait objects.
 
 ### Method has generic type parameters
 
@@ -535,10 +549,10 @@ fn foo(&self) {
 // ...
 ```
 
-at compile time a table of all implementations of `Trait`, containing pointers
-to the implementation of `foo()` would be generated.
+at compile time each implementation of `Trait` will produce a table containing
+the various methods (and other items) related to the implementation.
 
-This works fine, but when we the method gains generic parameters, we can have a
+This works fine, but when the method gains generic parameters, we can have a
 problem.
 
 Usually, generic parameters get _monomorphized_. For example, if I have
@@ -555,12 +569,14 @@ fn foo<T>(x: T) {
 compiler will only generate code for `foo::<bool>()`. When we have additional
 type parameters, the number of monomorphized implementations the compiler
 generates does not grow drastically, since the compiler will only generate an
-implementation if the function is called with hard substitutions.
+implementation if the function is called with unparametrized substitutions
+(i.e., substitutions where none of the substituted types are themselves
+parametrized).
 
 However, with trait objects we have to make a table containing _every object
 that implements the trait_. Now, if it has type parameters, we need to add
-implementations for every type that implements the trait, bloating the table
-quickly.
+implementations for every type that implements the trait, and there could
+theoretically be an infinite number of types.
 
 For example, with
 
@@ -675,13 +691,46 @@ trait Super<A> {
 
 There's no easy fix for this, generally code will need to be refactored so that
 you no longer need to derive from `Super<Self>`.
-
 "####,
 
 E0079: r##"
 Enum variants which contain no data can be given a custom integer
 representation. This error indicates that the value provided is not an
 integer literal and is therefore invalid.
+
+For example, in the following code,
+
+```
+enum Foo {
+    Q = "32"
+}
+```
+
+we try to set the representation to a string.
+
+There's no general fix for this; if you can work with an integer
+then just set it to one:
+
+```
+enum Foo {
+    Q = 32
+}
+```
+
+however if you actually wanted a mapping between variants
+and non-integer objects, it may be preferable to use a method with
+a match instead:
+
+```
+enum Foo { Q }
+impl Foo {
+    fn get_str(&self) -> &'static str {
+        match *self {
+            Foo::Q => "32",
+        }
+    }
+}
+```
 "##,
 
 E0080: r##"
@@ -704,8 +753,7 @@ enum Enum {
 "##,
 
 E0109: r##"
-You tried to give a type parameter to a type which doesn't need it. Erroneous
-code example:
+You tried to give a type parameter to a type which doesn't need it; for example:
 
 ```
 type X = u32<i32>; // error: type parameters are not allowed on this type
@@ -713,24 +761,25 @@ enum Enum {
 
 Please check that you used the correct type and recheck its definition. Perhaps
 it doesn't need the type parameter.
+
 Example:
 
 ```
-type X = u32; // ok!
+type X = u32; // this compiles
 ```
 "##,
 
 E0110: r##"
-You tried to give a lifetime parameter to a type which doesn't need it.
-Erroneous code example:
+You tried to give a lifetime parameter to a type which doesn't need it; for
+example:
 
 ```
 type X = u32<'static>; // error: lifetime parameters are not allowed on
                        //        this type
 ```
 
-Please check that you used the correct type and recheck its definition,
-perhaps it doesn't need the lifetime parameter. Example:
+Please check that the correct type was used and recheck its definition; perhaps
+it doesn't need the lifetime parameter. Example:
 
 ```
 type X = u32; // ok!