]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #32989 - GuillaumeGomez:e0393, r=Manishearth
authorbors <bors@rust-lang.org>
Tue, 26 Apr 2016 11:51:08 +0000 (04:51 -0700)
committerbors <bors@rust-lang.org>
Tue, 26 Apr 2016 11:51:08 +0000 (04:51 -0700)
Add E0393 error explanation

Part of #32777.

r? @Manishearth
cc @steveklabnik

1  2 
src/librustc_typeck/diagnostics.rs

index 582b9696bb1aa09c189029bf49cde33d55daf3dc,db7ad844494be263468c14615002bf8a327d383f..ad91bc9399fef1293a632088756d48cb5bcd102e
@@@ -632,7 -632,7 +632,7 @@@ recursion limit (which can be set via t
  
  For a somewhat artificial example:
  
 -```compile_fail
 +```compile_fail,ignore
  #![recursion_limit="2"]
  
  struct Foo;
@@@ -1420,24 -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] = [];
  }
  ```
  "##,
@@@ -2696,7 -2717,7 +2696,7 @@@ Rust does not currently support this. 
  
  ```compile_fail
  fn main() {
 -    let _: Box<std::io::Read+std::io::Write>;
 +    let _: Box<std::io::Read + std::io::Write>;
  }
  ```
  
@@@ -2706,7 -2727,7 +2706,7 @@@ following compiles correctly
  
  ```
  fn main() {
 -    let _: Box<std::io::Read+Copy+Sync>;
 +    let _: Box<std::io::Read + Send + Sync>;
  }
  ```
  "##,
@@@ -3405,6 -3426,37 +3405,37 @@@ parameters. You can read more about it 
  https://doc.rust-lang.org/std/marker/struct.PhantomData.html
  "##,
  
+ E0393: r##"
+ A type parameter which references `Self` in its default value was not specified.
+ Example of erroneous code:
+ ```compile_fail
+ trait A<T=Self> {}
+ fn together_we_will_rule_the_galaxy(son: &A) {}
+ // error: the type parameter `T` must be explicitly specified in an
+ //        object type because its default value `Self` references the
+ //        type `Self`
+ ```
+ A trait object is defined over a single, fully-defined trait. With a regular
+ default parameter, this parameter can just be substituted in. However, if the
+ default parameter is `Self`, the trait changes for each concrete type; i.e.
+ `i32` will be expected to implement `A<i32>`, `bool` will be expected to
+ implement `A<bool>`, etc... These types will not share an implementation of a
+ fully-defined trait; instead they share implementations of a trait with
+ different parameters substituted in for each implementation. This is
+ irreconcilable with what we need to make a trait object work, and is thus
+ disallowed. Making the trait concrete by explicitly specifying the value of the
+ defaulted parameter will fix this issue. Fixed example:
+ ```
+ trait A<T=Self> {}
+ fn together_we_will_rule_the_galaxy(son: &A<i32>) {} // Ok!
+ ```
+ "##,
  E0439: r##"
  The length of the platform-intrinsic function `simd_shuffle`
  wasn't specified. Erroneous code example:
@@@ -3623,68 -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! {
             // between structures
      E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
             // between structures with the same definition
-     E0393, // the type parameter `{}` must be explicitly specified in an object
-            // type because its default value `{}` references the type `Self`"
      E0399, // trait items need to be implemented because the associated
             // 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
  }