]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/diagnostics.rs
Auto merge of #32989 - GuillaumeGomez:e0393, r=Manishearth
[rust.git] / src / librustc_typeck / diagnostics.rs
index db7ad844494be263468c14615002bf8a327d383f..ad91bc9399fef1293a632088756d48cb5bcd102e 100644 (file)
@@ -632,7 +632,7 @@ fn bar(&mut self) { }
 
 For a somewhat artificial example:
 
-```compile_fail
+```compile_fail,ignore
 #![recursion_limit="2"]
 
 struct Foo;
@@ -1420,45 +1420,24 @@ fn main() {
 "##,
 
 E0102: r##"
-You hit this error because the compiler lacks information to
-determine a type for this variable. Erroneous code example:
+You hit this error because the compiler lacks the information to
+determine the type of this variable. Erroneous code example:
 
 ```compile_fail
-fn demo(devil: fn () -> !) {
-    let x: &_ = devil();
-    // error: cannot determine a type for this local variable
-}
-
-fn oh_no() -> ! { panic!("the devil is in the details") }
-
 fn main() {
-    demo(oh_no);
+    // could be an array of anything
+    let x = []; // error: cannot determine a type for this local variable
 }
 ```
 
 To solve this situation, constrain the type of the variable.
 Examples:
 
-```no_run
+```
 #![allow(unused_variables)]
 
-fn some_func(x: &u32) {
-    // some code
-}
-
-fn demo(devil: fn () -> !) {
-    let x: &u32 = devil();
-    // Here we defined the type at the variable creation
-
-    let x: &_ = devil();
-    some_func(x);
-    // Here, the type is determined by the function argument type
-}
-
-fn oh_no() -> ! { panic!("the devil is in the details") }
-
 fn main() {
-    demo(oh_no);
+    let x: [u8; 0] = [];
 }
 ```
 "##,
@@ -2717,7 +2696,7 @@ fn main() {
 
 ```compile_fail
 fn main() {
-    let _: Box<std::io::Read+std::io::Write>;
+    let _: Box<std::io::Read + std::io::Write>;
 }
 ```
 
@@ -2727,7 +2706,7 @@ fn main() {
 
 ```
 fn main() {
-    let _: Box<std::io::Read+Copy+Sync>;
+    let _: Box<std::io::Read + Send + Sync>;
 }
 ```
 "##,
@@ -3675,6 +3654,68 @@ fn main() {
 ```
 "##,
 
+E0520: r##"
+A non-default implementation was already made on this type so it cannot be
+specialized further. Erroneous code example:
+
+```compile_fail
+#![feature(specialization)]
+
+trait SpaceLlama {
+    fn fly(&self);
+}
+
+// applies to all T
+impl<T> SpaceLlama for T {
+    default fn fly(&self) {}
+}
+
+// non-default impl
+// applies to all `Clone` T and overrides the previous impl
+impl<T: Clone> SpaceLlama for T {
+    fn fly(&self) {}
+}
+
+// since `i32` is clone, this conflicts with the previous implementation
+impl SpaceLlama for i32 {
+    default fn fly(&self) {}
+    // error: item `fly` is provided by an `impl` that specializes
+    //        another, but the item in the parent `impl` is not marked
+    //        `default` and so it cannot be specialized.
+}
+```
+
+Specialization only allows you to override `default` functions in
+implementations.
+
+To fix this error, you need to mark all the parent implementations as default.
+Example:
+
+```
+#![feature(specialization)]
+
+trait SpaceLlama {
+    fn fly(&self);
+}
+
+// applies to all T
+impl<T> SpaceLlama for T {
+    default fn fly(&self) {} // This is a parent implementation.
+}
+
+// applies to all `Clone` T; overrides the previous impl
+impl<T: Clone> SpaceLlama for T {
+    default fn fly(&self) {} // This is a parent implementation but was
+                             // previously not a default one, causing the error
+}
+
+// applies to i32, overrides the previous two impls
+impl SpaceLlama for i32 {
+    fn fly(&self) {} // And now that's ok!
+}
+```
+"##,
+
 }
 
 register_diagnostics! {
@@ -3749,6 +3790,5 @@ fn main() {
            // type `{}` was overridden
     E0436, // functional record update requires a struct
     E0513, // no type for local variable ..
-    E0520, // cannot specialize non-default item
     E0521  // redundant default implementations of trait
 }