Skip to content

Commit e62d26e

Browse files
committed
complete wf checks for Copy impls
1 parent 4dba5a5 commit e62d26e

File tree

2 files changed

+132
-12
lines changed

2 files changed

+132
-12
lines changed

chalk-solve/src/wf.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -534,14 +534,19 @@ impl WfWellKnownGoals {
534534
let ty = trait_ref.self_type_parameter(interner);
535535
let ty_data = ty.data(interner);
536536

537+
// Implementations for scalars, pointer types and never type are provided by libcore.
538+
// User implementations on types other than ADTs are forbidden.
537539
let (adt_id, substitution) = match ty_data {
538-
TyData::Apply(ApplicationTy {
539-
name: TypeName::Adt(adt_id),
540-
substitution,
541-
}) => (*adt_id, substitution),
542-
// TODO(areredify)
543-
// when #368 lands, extend this to handle everything accordingly
544-
_ => return None,
540+
TyData::Apply(ApplicationTy { name, substitution }) => match name {
541+
TypeName::Scalar(_)
542+
| TypeName::Raw(_)
543+
| TypeName::Ref(Mutability::Not)
544+
| TypeName::Never => return None,
545+
TypeName::Adt(adt_id) => (*adt_id, substitution),
546+
_ => return Some(GoalData::CannotProve(()).intern(interner)),
547+
},
548+
549+
_ => return Some(GoalData::CannotProve(()).intern(interner)),
545550
};
546551

547552
// not { Implemented(ImplSelfTy: Drop) }

tests/test/wf_lowering.rs

+120-5
Original file line numberDiff line numberDiff line change
@@ -712,19 +712,17 @@ fn struct_sized_constraints() {
712712

713713
#[test]
714714
fn copy_constraints() {
715-
lowering_error! {
715+
lowering_success! {
716716
program {
717717
#[lang(copy)]
718718
trait Copy { }
719719

720720
#[lang(drop)]
721721
trait Drop { }
722722

723-
struct S<T> { t: T }
723+
struct S<T1, T2> { t1: T1, t2: T2 }
724724

725-
impl<T> Copy for S<T> { }
726-
} error_msg {
727-
"trait impl for `Copy` does not meet well-formedness requirements"
725+
impl<T1, T2> Copy for S<T1, T2> where T1: Copy, T2: Copy { }
728726
}
729727
}
730728

@@ -744,6 +742,34 @@ fn copy_constraints() {
744742
}
745743
}
746744

745+
// Copy implementations for a struct with non-copy field
746+
lowering_error! {
747+
program {
748+
#[lang(copy)]
749+
trait Copy { }
750+
751+
struct S<T> { t: T }
752+
753+
impl<T> Copy for S<T> { }
754+
} error_msg {
755+
"trait impl for `Copy` does not meet well-formedness requirements"
756+
}
757+
}
758+
759+
lowering_error! {
760+
program {
761+
#[lang(copy)]
762+
trait Copy { }
763+
764+
struct S<T1, T2> { t1: T1, t2: T2 }
765+
766+
impl<T1, T2> Copy for S<T1, T2> where T2: Copy { }
767+
} error_msg {
768+
"trait impl for `Copy` does not meet well-formedness requirements"
769+
}
770+
}
771+
772+
// Copy implemenation for a Drop type
747773
lowering_error! {
748774
program {
749775
#[lang(copy)]
@@ -761,6 +787,95 @@ fn copy_constraints() {
761787
"trait impl for `Copy` does not meet well-formedness requirements"
762788
}
763789
}
790+
791+
// Tests for Copy impls for builtin types
792+
lowering_success! {
793+
program {
794+
#[lang(copy)]
795+
trait Copy { }
796+
797+
#[lang(drop)]
798+
trait Drop { }
799+
800+
impl Copy for u8 {}
801+
impl Copy for f32 {}
802+
impl Copy for char {}
803+
impl Copy for bool {}
804+
impl<T> Copy for *const T {}
805+
impl<T> Copy for *mut T {}
806+
impl<'a, T> Copy for &'a T {}
807+
impl Copy for ! {}
808+
}
809+
}
810+
811+
lowering_error! {
812+
program {
813+
#[lang(copy)]
814+
trait Copy { }
815+
816+
impl<'a, T> Copy for &'a mut T {}
817+
} error_msg {
818+
"trait impl for `Copy` does not meet well-formedness requirements"
819+
}
820+
}
821+
822+
lowering_error! {
823+
program {
824+
#[lang(copy)]
825+
trait Copy { }
826+
827+
#[object_safe]
828+
trait Trait {}
829+
830+
impl<'a> Copy for dyn Trait + 'a {}
831+
} error_msg {
832+
"trait impl for `Copy` does not meet well-formedness requirements"
833+
}
834+
}
835+
836+
lowering_error! {
837+
program {
838+
#[lang(copy)]
839+
trait Copy { }
840+
841+
impl Copy for fn(u32) {}
842+
} error_msg {
843+
"trait impl for `Copy` does not meet well-formedness requirements"
844+
}
845+
}
846+
847+
lowering_error! {
848+
program {
849+
#[lang(copy)]
850+
trait Copy { }
851+
852+
impl Copy for str {}
853+
} error_msg {
854+
"trait impl for `Copy` does not meet well-formedness requirements"
855+
}
856+
}
857+
858+
lowering_error! {
859+
program {
860+
#[lang(copy)]
861+
trait Copy { }
862+
863+
impl Copy for [u32; 4] {}
864+
} error_msg {
865+
"trait impl for `Copy` does not meet well-formedness requirements"
866+
}
867+
}
868+
869+
lowering_error! {
870+
program {
871+
#[lang(copy)]
872+
trait Copy { }
873+
874+
impl Copy for [u32] {}
875+
} error_msg {
876+
"trait impl for `Copy` does not meet well-formedness requirements"
877+
}
878+
}
764879
}
765880

766881
#[test]

0 commit comments

Comments
 (0)