From: bors Date: Tue, 26 Apr 2016 11:51:08 +0000 (-0700) Subject: Auto merge of #32989 - GuillaumeGomez:e0393, r=Manishearth X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=03bef4c43b2f51df6bfd558b57b492cb821dd5ec;hp=-c;p=rust.git Auto merge of #32989 - GuillaumeGomez:e0393, r=Manishearth Add E0393 error explanation Part of #32777. r? @Manishearth cc @steveklabnik --- 03bef4c43b2f51df6bfd558b57b492cb821dd5ec diff --combined src/librustc_typeck/diagnostics.rs index 582b9696bb1,db7ad844494..ad91bc9399f --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@@ -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; + let _: Box; } ``` @@@ -2706,7 -2727,7 +2706,7 @@@ following compiles correctly ``` fn main() { - let _: Box; + let _: Box; } ``` "##, @@@ -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 {} + + 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`, `bool` will be expected to + implement `A`, 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 {} + + fn together_we_will_rule_the_galaxy(son: &A) {} // 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 SpaceLlama for T { + default fn fly(&self) {} +} + +// non-default impl +// applies to all `Clone` T and overrides the previous impl +impl 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 SpaceLlama for T { + default fn fly(&self) {} // This is a parent implementation. +} + +// applies to all `Clone` T; overrides the previous impl +impl 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! { @@@ -3755,11 -3745,10 +3786,9 @@@ // 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 }