@@ -15,6 +15,7 @@ use rustc_infer::traits::Obligation;
1515use rustc_middle:: ty:: adjustment:: CoerceUnsizedInfo ;
1616use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
1717use rustc_middle:: ty:: { self , suggest_constraining_type_params, Ty , TyCtxt , TypeVisitableExt } ;
18+ use rustc_span:: symbol:: { kw, Ident } ;
1819use rustc_span:: { Span , DUMMY_SP } ;
1920use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
2021use rustc_trait_selection:: traits:: misc:: {
@@ -103,26 +104,50 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
103104
104105 let cause = traits:: ObligationCause :: misc ( DUMMY_SP , impl_did) ;
105106 match type_allowed_to_implement_copy ( tcx, param_env, self_type, cause) {
106- Ok ( ( ) ) => Ok ( ( ) ) ,
107+ Ok ( ( ) ) => { }
107108 Err ( CopyImplementationError :: InfringingFields ( fields) ) => {
108109 let span = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) . self_ty . span ;
109- Err ( infringing_fields_error (
110+ return Err ( infringing_fields_error (
110111 tcx,
111112 fields. into_iter ( ) . map ( |( field, ty, reason) | ( tcx. def_span ( field. did ) , ty, reason) ) ,
112113 LangItem :: Copy ,
113114 impl_did,
114115 span,
115- ) )
116+ ) ) ;
116117 }
117118 Err ( CopyImplementationError :: NotAnAdt ) => {
118119 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 } ) ) ;
120121 }
121122 Err ( CopyImplementationError :: HasDestructor ) => {
122123 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+ ) ;
124147 }
125148 }
149+
150+ Ok ( ( ) )
126151}
127152
128153fn visit_implementation_of_const_param_ty (
0 commit comments