@@ -15,6 +15,7 @@ use rustc_infer::traits::Obligation;
15
15
use rustc_middle:: ty:: adjustment:: CoerceUnsizedInfo ;
16
16
use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
17
17
use rustc_middle:: ty:: { self , suggest_constraining_type_params, Ty , TyCtxt , TypeVisitableExt } ;
18
+ use rustc_span:: symbol:: { kw, Ident } ;
18
19
use rustc_span:: { Span , DUMMY_SP } ;
19
20
use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
20
21
use rustc_trait_selection:: traits:: misc:: {
@@ -103,26 +104,50 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
103
104
104
105
let cause = traits:: ObligationCause :: misc ( DUMMY_SP , impl_did) ;
105
106
match type_allowed_to_implement_copy ( tcx, param_env, self_type, cause) {
106
- Ok ( ( ) ) => Ok ( ( ) ) ,
107
+ Ok ( ( ) ) => { }
107
108
Err ( CopyImplementationError :: InfringingFields ( fields) ) => {
108
109
let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
109
- Err ( infringing_fields_error (
110
+ return Err ( infringing_fields_error (
110
111
tcx,
111
112
fields. into_iter ( ) . map ( |( field, ty, reason) | ( tcx. def_span ( field. did ) , ty, reason) ) ,
112
113
LangItem :: Copy ,
113
114
impl_did,
114
115
span,
115
- ) )
116
+ ) ) ;
116
117
}
117
118
Err ( CopyImplementationError :: NotAnAdt ) => {
118
119
let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
119
- Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnNonAdt { span } ) )
120
+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnNonAdt { span } ) ) ;
120
121
}
121
122
Err ( CopyImplementationError :: HasDestructor ) => {
122
123
let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
123
- Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnTypeWithDtor { span } ) )
124
+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnTypeWithDtor { span } ) ) ;
125
+ }
126
+ }
127
+
128
+ // Let's additionally lint the fields of the copy impl.
129
+ if let ty:: Adt ( def, _) = * self_type. kind ( ) {
130
+ let impl_span = tcx. def_span ( impl_did) ;
131
+ let ( _, scope) = tcx. adjust_ident_and_get_scope (
132
+ Ident :: new ( kw:: Empty , impl_span) ,
133
+ def. did ( ) ,
134
+ tcx. local_def_id_to_hir_id ( impl_did) ,
135
+ ) ;
136
+ if tcx. crate_name ( scope. krate ) . as_str ( ) == "core" {
137
+ return Ok ( ( ) ) ;
138
+ }
139
+ println ! ( "{scope:?}" ) ;
140
+ let infringing_fields: Vec < _ > =
141
+ def. all_fields ( ) . filter ( |field| !field. vis . is_accessible_from ( scope, tcx) ) . collect ( ) ;
142
+ if !infringing_fields. is_empty ( ) {
143
+ rustc_middle:: span_bug!(
144
+ impl_span,
145
+ "{infringing_fields:#?} in {scope:#?} for {impl_did:#?}"
146
+ ) ;
124
147
}
125
148
}
149
+
150
+ Ok ( ( ) )
126
151
}
127
152
128
153
fn visit_implementation_of_const_param_ty (
0 commit comments