@@ -586,3 +586,200 @@ fn struct_unsizing() {
586586 }
587587 }
588588}
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