@@ -586,3 +586,200 @@ fn struct_unsizing() {
586
586
}
587
587
}
588
588
}
589
+
590
+ #[ test]
591
+ fn dispatch_from_dyn ( ) {
592
+ test ! {
593
+ program {
594
+ #[ lang( dispatch_from_dyn) ]
595
+ trait DispatchFromDyn <T > { }
596
+
597
+ impl <' a, T , U > DispatchFromDyn <& ' a U > for & ' a T { }
598
+ }
599
+
600
+ // Smoke test that DispatchFromDyn works just like any other impl.
601
+ goal {
602
+ forall<' a> {
603
+ & ' a u8 : DispatchFromDyn <& ' a u8 >
604
+ }
605
+ } yields {
606
+ "Unique"
607
+ }
608
+ }
609
+ }
610
+
611
+ #[ test]
612
+ fn dispatch_from_dyn_wf ( ) {
613
+ lowering_success ! {
614
+ program {
615
+ #[ lang( dispatch_from_dyn) ]
616
+ trait DispatchFromDyn <T > { }
617
+
618
+ #[ one_zst]
619
+ struct PhantomData <T > { }
620
+
621
+ struct Foo <T > {
622
+ f: * mut T ,
623
+ f2: PhantomData <u8 >,
624
+ }
625
+
626
+ // References and pointers
627
+ impl <' a, T , U > DispatchFromDyn <& ' a U > for & ' a T { }
628
+ impl <' a, T , U > DispatchFromDyn <& ' a mut U > for & ' a mut T { }
629
+ impl <T , U > DispatchFromDyn <* const U > for * const T { }
630
+ impl <T , U > DispatchFromDyn <* mut U > for * mut T { }
631
+
632
+ // Struct
633
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
634
+ }
635
+ }
636
+
637
+ // Reference: mutability mismatch
638
+ lowering_error ! {
639
+ program {
640
+ #[ lang( dispatch_from_dyn) ]
641
+ trait DispatchFromDyn <T > { }
642
+
643
+ impl <' a, T , U > DispatchFromDyn <& ' a U > for & ' a mut T { }
644
+ } error_msg {
645
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
646
+ }
647
+ }
648
+
649
+ // Raw pointer: mutability mismatch
650
+ lowering_error ! {
651
+ program {
652
+ #[ lang( dispatch_from_dyn) ]
653
+ trait DispatchFromDyn <T > { }
654
+
655
+ impl <' a, T , U > DispatchFromDyn <* mut U > for * const T { }
656
+ } error_msg {
657
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
658
+ }
659
+ }
660
+
661
+ // No non-ZST fields
662
+ lowering_error ! {
663
+ program {
664
+ #[ lang( dispatch_from_dyn) ]
665
+ trait DispatchFromDyn <T > { }
666
+
667
+ #[ one_zst]
668
+ struct PhantomData <T > { }
669
+
670
+ struct Foo <T > {
671
+ f: PhantomData <T >,
672
+ }
673
+
674
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
675
+ } error_msg {
676
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
677
+ }
678
+ }
679
+
680
+ // Too many fields
681
+ lowering_error ! {
682
+ program {
683
+ #[ lang( dispatch_from_dyn) ]
684
+ trait DispatchFromDyn <T > { }
685
+
686
+ struct Foo <T > {
687
+ f: * mut T ,
688
+ f2: u8 ,
689
+ }
690
+
691
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
692
+ } error_msg {
693
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
694
+ }
695
+ }
696
+
697
+ // Field does not impl DispatchFromDyn
698
+ lowering_error ! {
699
+ program {
700
+ #[ lang( dispatch_from_dyn) ]
701
+ trait DispatchFromDyn <T > { }
702
+
703
+ struct Foo <T > {
704
+ f: T ,
705
+ }
706
+
707
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
708
+ } error_msg {
709
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
710
+ }
711
+ }
712
+
713
+ // Field type does not change
714
+ lowering_error ! {
715
+ program {
716
+ #[ lang( dispatch_from_dyn) ]
717
+ trait DispatchFromDyn <T > { }
718
+
719
+ #[ one_zst]
720
+ struct PhantomData <T > { }
721
+
722
+ struct Foo <T > {
723
+ f: * const u8 ,
724
+ f2: PhantomData <T >,
725
+ }
726
+
727
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
728
+ } error_msg {
729
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
730
+ }
731
+ }
732
+
733
+ // Different definitions
734
+ lowering_error ! {
735
+ program {
736
+ #[ lang( dispatch_from_dyn) ]
737
+ trait DispatchFromDyn <T > { }
738
+
739
+ struct Foo <T > {
740
+ f: * const T ,
741
+ }
742
+
743
+ struct Bar <T > {
744
+ f: * const T ,
745
+ }
746
+
747
+ impl <T , U > DispatchFromDyn <Bar <U >> for Foo <T > { }
748
+ } error_msg {
749
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
750
+ }
751
+ }
752
+
753
+ // Not a struct
754
+ lowering_error ! {
755
+ program {
756
+ #[ lang( dispatch_from_dyn) ]
757
+ trait DispatchFromDyn <T > { }
758
+
759
+ enum Foo <T > {
760
+ Bar ( * const T ) ,
761
+ }
762
+
763
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
764
+ } error_msg {
765
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
766
+ }
767
+ }
768
+
769
+ // repr(C)
770
+ lowering_error ! {
771
+ program {
772
+ #[ lang( dispatch_from_dyn) ]
773
+ trait DispatchFromDyn <T > { }
774
+
775
+ #[ repr( C ) ]
776
+ struct Foo <T > {
777
+ f: * mut T ,
778
+ }
779
+
780
+ impl <T , U > DispatchFromDyn <Foo <U >> for Foo <T > { }
781
+ } error_msg {
782
+ "trait impl for `DispatchFromDyn` does not meet well-formedness requirements"
783
+ }
784
+ }
785
+ }
0 commit comments