@@ -824,7 +824,110 @@ There are a few interesting things to note here:
824
824
# Unresolved questions
825
825
[unresolved-questions]: #unresolved-questions
826
826
827
- There are none.
827
+ ## 1 . When do suitability of defaults need to be proven?
828
+
829
+ Consider a trait `Foo<T>` defined as:
830
+
831
+ ```rust
832
+ trait Foo<T> {
833
+ type Bar: Clone = Vec<T>;
834
+ }
835
+ ```
836
+
837
+ Let's also assume the following implementation of ` Clone ` :
838
+
839
+ ``` rust
840
+ impl <T : Clone > Clone for Vec <T > { ... }
841
+ ```
842
+
843
+ To prove that ` Vec<T>: Clone ` , we must prove that ` T: Clone ` .
844
+ However, ` Foo<T> ` does not say that ` T: Clone ` so is its definition valid?
845
+ If the suitability of ` Vec<T> ` is checked where ` Foo<T> ` is defined (1),
846
+ then we don't know that ` T: Clone ` and so the definition must be rejected.
847
+ To make the compiler admit ` Foo<T> ` , we would have to write:
848
+
849
+ ``` rust
850
+ trait Foo <T : Clone > {
851
+ type Bar : Clone = Vec <T >;
852
+ }
853
+ ```
854
+
855
+ Now it is provable that ` T: Clone ` so ` Vec<T>: Clone ` which is what was required.
856
+
857
+ If instead the suitability of defaults are checked in ` impl ` ementations (2),
858
+ then proving ` Vec<T>: Clone ` would not be required in ` Foo<T> ` 's definition and
859
+ so then ` Foo<T> ` would type-check. As a result, it would be admissible to write:
860
+
861
+ ``` rust
862
+ #[derive(Copy , Clone )]
863
+ struct A ;
864
+
865
+ struct B ;
866
+
867
+ impl Foo <A > for B {}
868
+ ```
869
+
870
+ since ` Vec<A>: Clone ` holds.
871
+
872
+ With condition (2), strictly more programs are accepted than with (1).
873
+ It may be that useful programs are rejected if we enforce (1) rather than (2).
874
+ However, it would also be the more conservative choice, allowing us to move
875
+ towards (2) when necessary. As it is currently unclear what solution is best,
876
+ this question is left unresolved.
877
+
878
+ ## 1. Where are cycles checked?
879
+
880
+ [ playground ] : https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e823eea5e7ecba5da78cff225e0adaf9
881
+
882
+ Consider a program * ([ playground] )* :
883
+
884
+ ``` rust
885
+ #![feature(associated_type_defaults)]
886
+
887
+ trait A {
888
+ type B = Self :: C ; // B defaults to C,
889
+ type C = Self :: B ; // C defaults to B, and we have a cycle!
890
+ }
891
+
892
+ impl A for () {}
893
+
894
+ fn _foo () {
895
+ let _x : <() as A >:: B ;
896
+ }
897
+
898
+ // Removing this function will make the example compile.
899
+ fn main () {
900
+ let _x : <() as A >:: B ;
901
+ }
902
+ ```
903
+
904
+ Currently, this results in a crash. This will need to be fixed.
905
+ At the very latest, ` impl A for () {} ` should have been an error.
906
+
907
+ ``` rust
908
+ trait A {
909
+ type B = Self :: C ;
910
+ type C = Self :: B ;
911
+ }
912
+
913
+ impl A for () {} // This OK but shouldn't be.
914
+ ```
915
+
916
+ If cycles are checked for in ` impl A for () ` , then it would be valid to write:
917
+
918
+ ``` rust
919
+ trait A {
920
+ type B = Self :: C ;
921
+ type C = Self :: B ;
922
+ }
923
+
924
+ impl A for () {
925
+ type B = u8 ; // The cycle is broken!
926
+ }
927
+ ```
928
+
929
+ Alternatively, cycles could be checked for in ` A ` 's definition.
930
+ This is similar to the previous question in (1).
828
931
829
932
# Future possibilities
830
933
[ future-possibilities ] : #future-possibilities
0 commit comments