@@ -147,34 +147,40 @@ impl<'tcx> ParameterEnvironment<'tcx> {
147
147
self_type : Ty < ' tcx > , span : Span )
148
148
-> Result < ( ) , CopyImplementationError > {
149
149
// FIXME: (@jroesch) float this code up
150
- tcx. infer_ctxt ( None , Some ( self . clone ( ) ) , Reveal :: ExactMatch ) . enter ( |infcx| {
151
- let adt = match self_type. sty {
152
- ty:: TyAdt ( adt, substs) => match adt. adt_kind ( ) {
153
- AdtKind :: Struct | AdtKind :: Union => {
154
- for field in adt. all_fields ( ) {
155
- let field_ty = field. ty ( tcx, substs) ;
156
- if infcx. type_moves_by_default ( field_ty, span) {
157
- return Err ( CopyImplementationError :: InfrigingField (
158
- field. name ) )
159
- }
150
+ tcx. infer_ctxt ( None , Some ( self . clone ( ) ) , Reveal :: NotSpecializable ) . enter ( |infcx| {
151
+ let ( adt, substs) = match self_type. sty {
152
+ ty:: TyAdt ( adt, substs) => ( adt, substs) ,
153
+ _ => return Err ( CopyImplementationError :: NotAnAdt )
154
+ } ;
155
+
156
+ let field_implements_copy = |field : & ty:: FieldDef | {
157
+ let cause = traits:: ObligationCause :: dummy ( ) ;
158
+ match traits:: fully_normalize ( & infcx, cause, & field. ty ( tcx, substs) ) {
159
+ Ok ( ty) => !infcx. type_moves_by_default ( ty, span) ,
160
+ Err ( ..) => false
161
+ }
162
+ } ;
163
+
164
+ match adt. adt_kind ( ) {
165
+ AdtKind :: Struct | AdtKind :: Union => {
166
+ for field in adt. all_fields ( ) {
167
+ if !field_implements_copy ( field) {
168
+ return Err ( CopyImplementationError :: InfrigingField (
169
+ field. name ) )
160
170
}
161
- adt
162
171
}
163
- AdtKind :: Enum => {
164
- for variant in & adt. variants {
165
- for field in & variant. fields {
166
- let field_ty = field. ty ( tcx, substs) ;
167
- if infcx. type_moves_by_default ( field_ty, span) {
168
- return Err ( CopyImplementationError :: InfrigingVariant (
169
- variant. name ) )
170
- }
172
+ }
173
+ AdtKind :: Enum => {
174
+ for variant in & adt. variants {
175
+ for field in & variant. fields {
176
+ if !field_implements_copy ( field) {
177
+ return Err ( CopyImplementationError :: InfrigingVariant (
178
+ variant. name ) )
171
179
}
172
180
}
173
- adt
174
181
}
175
- } ,
176
- _ => return Err ( CopyImplementationError :: NotAnAdt )
177
- } ;
182
+ }
183
+ }
178
184
179
185
if adt. has_dtor ( ) {
180
186
return Err ( CopyImplementationError :: HasDestructor ) ;
0 commit comments