@@ -25,14 +25,21 @@ use rustc_trait_selection::traits::ObligationCtxt;
2525use rustc_trait_selection:: traits:: { self , ObligationCause } ;
2626use std:: collections:: BTreeMap ;
2727
28- pub fn check_trait ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) {
28+ pub fn check_trait ( tcx : TyCtxt < ' _ > , trait_def_id : DefId ) -> Result < ( ) , ErrorGuaranteed > {
2929 let lang_items = tcx. lang_items ( ) ;
30- Checker { tcx, trait_def_id }
31- . check ( lang_items. drop_trait ( ) , visit_implementation_of_drop)
32- . check ( lang_items. copy_trait ( ) , visit_implementation_of_copy)
33- . check ( lang_items. const_param_ty_trait ( ) , visit_implementation_of_const_param_ty)
34- . check ( lang_items. coerce_unsized_trait ( ) , visit_implementation_of_coerce_unsized)
35- . check ( lang_items. dispatch_from_dyn_trait ( ) , visit_implementation_of_dispatch_from_dyn) ;
30+ let checker = Checker { tcx, trait_def_id } ;
31+ let mut res = checker. check ( lang_items. drop_trait ( ) , visit_implementation_of_drop) ;
32+ res = res. and ( checker. check ( lang_items. copy_trait ( ) , visit_implementation_of_copy) ) ;
33+ res = res. and (
34+ checker. check ( lang_items. const_param_ty_trait ( ) , visit_implementation_of_const_param_ty) ,
35+ ) ;
36+ res = res. and (
37+ checker. check ( lang_items. coerce_unsized_trait ( ) , visit_implementation_of_coerce_unsized) ,
38+ ) ;
39+ res. and (
40+ checker
41+ . check ( lang_items. dispatch_from_dyn_trait ( ) , visit_implementation_of_dispatch_from_dyn) ,
42+ )
3643}
3744
3845struct Checker < ' tcx > {
@@ -41,33 +48,40 @@ struct Checker<'tcx> {
4148}
4249
4350impl < ' tcx > Checker < ' tcx > {
44- fn check < F > ( & self , trait_def_id : Option < DefId > , mut f : F ) -> & Self
51+ fn check < F > ( & self , trait_def_id : Option < DefId > , mut f : F ) -> Result < ( ) , ErrorGuaranteed >
4552 where
46- F : FnMut ( TyCtxt < ' tcx > , LocalDefId ) ,
53+ F : FnMut ( TyCtxt < ' tcx > , LocalDefId ) -> Result < ( ) , ErrorGuaranteed > ,
4754 {
55+ let mut res = Ok ( ( ) ) ;
4856 if Some ( self . trait_def_id ) == trait_def_id {
4957 for & impl_def_id in self . tcx . hir ( ) . trait_impls ( self . trait_def_id ) {
50- f ( self . tcx , impl_def_id) ;
58+ res = res . and ( f ( self . tcx , impl_def_id) ) ;
5159 }
5260 }
53- self
61+ res
5462 }
5563}
5664
57- fn visit_implementation_of_drop ( tcx : TyCtxt < ' _ > , impl_did : LocalDefId ) {
65+ fn visit_implementation_of_drop (
66+ tcx : TyCtxt < ' _ > ,
67+ impl_did : LocalDefId ,
68+ ) -> Result < ( ) , ErrorGuaranteed > {
5869 // Destructors only work on local ADT types.
5970 match tcx. type_of ( impl_did) . instantiate_identity ( ) . kind ( ) {
60- ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => return ,
61- ty:: Error ( _) => return ,
71+ ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => return Ok ( ( ) ) ,
72+ ty:: Error ( _) => return Ok ( ( ) ) ,
6273 _ => { }
6374 }
6475
6576 let impl_ = tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) ;
6677
67- tcx. dcx ( ) . emit_err ( errors:: DropImplOnWrongItem { span : impl_. self_ty . span } ) ;
78+ Err ( tcx. dcx ( ) . emit_err ( errors:: DropImplOnWrongItem { span : impl_. self_ty . span } ) )
6879}
6980
70- fn visit_implementation_of_copy ( tcx : TyCtxt < ' _ > , impl_did : LocalDefId ) {
81+ fn visit_implementation_of_copy (
82+ tcx : TyCtxt < ' _ > ,
83+ impl_did : LocalDefId ,
84+ ) -> Result < ( ) , ErrorGuaranteed > {
7185 debug ! ( "visit_implementation_of_copy: impl_did={:?}" , impl_did) ;
7286
7387 let self_type = tcx. type_of ( impl_did) . instantiate_identity ( ) ;
@@ -79,59 +93,68 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
7993 debug ! ( "visit_implementation_of_copy: self_type={:?} (free)" , self_type) ;
8094
8195 let span = match tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) {
82- hir:: Impl { polarity : hir:: ImplPolarity :: Negative ( _) , .. } => return ,
96+ hir:: Impl { polarity : hir:: ImplPolarity :: Negative ( _) , .. } => return Ok ( ( ) ) ,
8397 hir:: Impl { self_ty, .. } => self_ty. span ,
8498 } ;
8599
86100 let cause = traits:: ObligationCause :: misc ( span, impl_did) ;
87101 match type_allowed_to_implement_copy ( tcx, param_env, self_type, cause) {
88- Ok ( ( ) ) => { }
102+ Ok ( ( ) ) => Ok ( ( ) ) ,
89103 Err ( CopyImplementationError :: InfringingFields ( fields) ) => {
90- infringing_fields_error ( tcx, fields, LangItem :: Copy , impl_did, span) ;
104+ Err ( infringing_fields_error ( tcx, fields, LangItem :: Copy , impl_did, span) )
91105 }
92106 Err ( CopyImplementationError :: NotAnAdt ) => {
93- tcx. dcx ( ) . emit_err ( errors:: CopyImplOnNonAdt { span } ) ;
107+ Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnNonAdt { span } ) )
94108 }
95109 Err ( CopyImplementationError :: HasDestructor ) => {
96- tcx. dcx ( ) . emit_err ( errors:: CopyImplOnTypeWithDtor { span } ) ;
110+ Err ( tcx. dcx ( ) . emit_err ( errors:: CopyImplOnTypeWithDtor { span } ) )
97111 }
98112 }
99113}
100114
101- fn visit_implementation_of_const_param_ty ( tcx : TyCtxt < ' _ > , impl_did : LocalDefId ) {
115+ fn visit_implementation_of_const_param_ty (
116+ tcx : TyCtxt < ' _ > ,
117+ impl_did : LocalDefId ,
118+ ) -> Result < ( ) , ErrorGuaranteed > {
102119 let self_type = tcx. type_of ( impl_did) . instantiate_identity ( ) ;
103120 assert ! ( !self_type. has_escaping_bound_vars( ) ) ;
104121
105122 let param_env = tcx. param_env ( impl_did) ;
106123
107124 let span = match tcx. hir ( ) . expect_item ( impl_did) . expect_impl ( ) {
108- hir:: Impl { polarity : hir:: ImplPolarity :: Negative ( _) , .. } => return ,
125+ hir:: Impl { polarity : hir:: ImplPolarity :: Negative ( _) , .. } => return Ok ( ( ) ) ,
109126 impl_ => impl_. self_ty . span ,
110127 } ;
111128
112129 let cause = traits:: ObligationCause :: misc ( span, impl_did) ;
113130 match type_allowed_to_implement_const_param_ty ( tcx, param_env, self_type, cause) {
114- Ok ( ( ) ) => { }
131+ Ok ( ( ) ) => Ok ( ( ) ) ,
115132 Err ( ConstParamTyImplementationError :: InfrigingFields ( fields) ) => {
116- infringing_fields_error ( tcx, fields, LangItem :: ConstParamTy , impl_did, span) ;
133+ Err ( infringing_fields_error ( tcx, fields, LangItem :: ConstParamTy , impl_did, span) )
117134 }
118135 Err ( ConstParamTyImplementationError :: NotAnAdtOrBuiltinAllowed ) => {
119- tcx. dcx ( ) . emit_err ( errors:: ConstParamTyImplOnNonAdt { span } ) ;
136+ Err ( tcx. dcx ( ) . emit_err ( errors:: ConstParamTyImplOnNonAdt { span } ) )
120137 }
121138 }
122139}
123140
124- fn visit_implementation_of_coerce_unsized ( tcx : TyCtxt < ' _ > , impl_did : LocalDefId ) {
141+ fn visit_implementation_of_coerce_unsized (
142+ tcx : TyCtxt < ' _ > ,
143+ impl_did : LocalDefId ,
144+ ) -> Result < ( ) , ErrorGuaranteed > {
125145 debug ! ( "visit_implementation_of_coerce_unsized: impl_did={:?}" , impl_did) ;
126146
127147 // Just compute this for the side-effects, in particular reporting
128148 // errors; other parts of the code may demand it for the info of
129149 // course.
130150 let span = tcx. def_span ( impl_did) ;
131- tcx. at ( span) . coerce_unsized_info ( impl_did) ;
151+ tcx. at ( span) . ensure ( ) . coerce_unsized_info ( impl_did)
132152}
133153
134- fn visit_implementation_of_dispatch_from_dyn ( tcx : TyCtxt < ' _ > , impl_did : LocalDefId ) {
154+ fn visit_implementation_of_dispatch_from_dyn (
155+ tcx : TyCtxt < ' _ > ,
156+ impl_did : LocalDefId ,
157+ ) -> Result < ( ) , ErrorGuaranteed > {
135158 debug ! ( "visit_implementation_of_dispatch_from_dyn: impl_did={:?}" , impl_did) ;
136159
137160 let span = tcx. def_span ( impl_did) ;
@@ -166,26 +189,28 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
166189 match ( source. kind ( ) , target. kind ( ) ) {
167190 ( & Ref ( r_a, _, mutbl_a) , Ref ( r_b, _, mutbl_b) )
168191 if infcx. at ( & cause, param_env) . eq ( DefineOpaqueTypes :: No , r_a, * r_b) . is_ok ( )
169- && mutbl_a == * mutbl_b => { }
170- ( & RawPtr ( tm_a) , & RawPtr ( tm_b) ) if tm_a. mutbl == tm_b. mutbl => ( ) ,
192+ && mutbl_a == * mutbl_b =>
193+ {
194+ Ok ( ( ) )
195+ }
196+ ( & RawPtr ( tm_a) , & RawPtr ( tm_b) ) if tm_a. mutbl == tm_b. mutbl => Ok ( ( ) ) ,
171197 ( & Adt ( def_a, args_a) , & Adt ( def_b, args_b) ) if def_a. is_struct ( ) && def_b. is_struct ( ) => {
172198 if def_a != def_b {
173199 let source_path = tcx. def_path_str ( def_a. did ( ) ) ;
174200 let target_path = tcx. def_path_str ( def_b. did ( ) ) ;
175201
176- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynCoercion {
202+ return Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynCoercion {
177203 span,
178204 trait_name : "DispatchFromDyn" ,
179205 note : true ,
180206 source_path,
181207 target_path,
182- } ) ;
183-
184- return ;
208+ } ) ) ;
185209 }
186210
211+ let mut res = Ok ( ( ) ) ;
187212 if def_a. repr ( ) . c ( ) || def_a. repr ( ) . packed ( ) {
188- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynRepr { span } ) ;
213+ res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynRepr { span } ) ) ;
189214 }
190215
191216 let fields = & def_a. non_enum_variant ( ) . fields ;
@@ -207,11 +232,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
207232 infcx. at ( & cause, param_env) . eq ( DefineOpaqueTypes :: No , ty_a, ty_b)
208233 {
209234 if ok. obligations . is_empty ( ) {
210- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynZST {
235+ res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynZST {
211236 span,
212237 name : field. name ,
213238 ty : ty_a,
214- } ) ;
239+ } ) ) ;
215240
216241 return false ;
217242 }
@@ -222,13 +247,13 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
222247 . collect :: < Vec < _ > > ( ) ;
223248
224249 if coerced_fields. is_empty ( ) {
225- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSingle {
250+ res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSingle {
226251 span,
227252 trait_name : "DispatchFromDyn" ,
228253 note : true ,
229- } ) ;
254+ } ) ) ;
230255 } else if coerced_fields. len ( ) > 1 {
231- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynMulti {
256+ res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynMulti {
232257 span,
233258 coercions_note : true ,
234259 number : coerced_fields. len ( ) ,
@@ -244,7 +269,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
244269 } )
245270 . collect :: < Vec < _ > > ( )
246271 . join ( ", " ) ,
247- } ) ;
272+ } ) ) ;
248273 } else {
249274 let ocx = ObligationCtxt :: new ( & infcx) ;
250275 for field in coerced_fields {
@@ -261,21 +286,25 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
261286 }
262287 let errors = ocx. select_all_or_error ( ) ;
263288 if !errors. is_empty ( ) {
264- infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ;
289+ res = Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( errors) ) ;
265290 }
266291
267292 // Finally, resolve all regions.
268293 let outlives_env = OutlivesEnvironment :: new ( param_env) ;
269- let _ = ocx. resolve_regions_and_report_errors ( impl_did, & outlives_env) ;
294+ res = res . and ( ocx. resolve_regions_and_report_errors ( impl_did, & outlives_env) ) ;
270295 }
296+ res
271297 }
272- _ => {
273- tcx . dcx ( ) . emit_err ( errors :: CoerceUnsizedMay { span , trait_name : "DispatchFromDyn" } ) ;
274- }
298+ _ => Err ( tcx
299+ . dcx ( )
300+ . emit_err ( errors :: CoerceUnsizedMay { span , trait_name : "DispatchFromDyn" } ) ) ,
275301 }
276302}
277303
278- pub fn coerce_unsized_info < ' tcx > ( tcx : TyCtxt < ' tcx > , impl_did : LocalDefId ) -> CoerceUnsizedInfo {
304+ pub fn coerce_unsized_info < ' tcx > (
305+ tcx : TyCtxt < ' tcx > ,
306+ impl_did : LocalDefId ,
307+ ) -> Result < CoerceUnsizedInfo , ErrorGuaranteed > {
279308 debug ! ( "compute_coerce_unsized_info(impl_did={:?})" , impl_did) ;
280309 let span = tcx. def_span ( impl_did) ;
281310
@@ -292,8 +321,6 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
292321 let param_env = tcx. param_env ( impl_did) ;
293322 assert ! ( !source. has_escaping_bound_vars( ) ) ;
294323
295- let err_info = CoerceUnsizedInfo { custom_kind : None } ;
296-
297324 debug ! ( "visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)" , source, target) ;
298325
299326 let infcx = tcx. infer_ctxt ( ) . build ( ) ;
@@ -337,14 +364,13 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
337364 if def_a != def_b {
338365 let source_path = tcx. def_path_str ( def_a. did ( ) ) ;
339366 let target_path = tcx. def_path_str ( def_b. did ( ) ) ;
340- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSame {
367+ return Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSame {
341368 span,
342369 trait_name : "CoerceUnsized" ,
343370 note : true ,
344371 source_path,
345372 target_path,
346- } ) ;
347- return err_info;
373+ } ) ) ;
348374 }
349375
350376 // Here we are considering a case of converting
@@ -419,12 +445,11 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
419445 . collect :: < Vec < _ > > ( ) ;
420446
421447 if diff_fields. is_empty ( ) {
422- tcx. dcx ( ) . emit_err ( errors:: CoerceUnsizedOneField {
448+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoerceUnsizedOneField {
423449 span,
424450 trait_name : "CoerceUnsized" ,
425451 note : true ,
426- } ) ;
427- return err_info;
452+ } ) ) ;
428453 } else if diff_fields. len ( ) > 1 {
429454 let item = tcx. hir ( ) . expect_item ( impl_did) ;
430455 let span = if let ItemKind :: Impl ( hir:: Impl { of_trait : Some ( t) , .. } ) = & item. kind {
@@ -433,7 +458,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
433458 tcx. def_span ( impl_did)
434459 } ;
435460
436- tcx. dcx ( ) . emit_err ( errors:: CoerceUnsizedMulti {
461+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoerceUnsizedMulti {
437462 span,
438463 coercions_note : true ,
439464 number : diff_fields. len ( ) ,
@@ -442,9 +467,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
442467 . map ( |& ( i, a, b) | format ! ( "`{}` (`{}` to `{}`)" , fields[ i] . name, a, b) )
443468 . collect :: < Vec < _ > > ( )
444469 . join ( ", " ) ,
445- } ) ;
446-
447- return err_info;
470+ } ) ) ;
448471 }
449472
450473 let ( i, a, b) = diff_fields[ 0 ] ;
@@ -453,8 +476,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
453476 }
454477
455478 _ => {
456- tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynStruct { span, trait_name : "CoerceUnsized" } ) ;
457- return err_info;
479+ return Err ( tcx
480+ . dcx ( )
481+ . emit_err ( errors:: DispatchFromDynStruct { span, trait_name : "CoerceUnsized" } ) ) ;
458482 }
459483 } ;
460484
@@ -477,7 +501,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
477501 let outlives_env = OutlivesEnvironment :: new ( param_env) ;
478502 let _ = ocx. resolve_regions_and_report_errors ( impl_did, & outlives_env) ;
479503
480- CoerceUnsizedInfo { custom_kind : kind }
504+ Ok ( CoerceUnsizedInfo { custom_kind : kind } )
481505}
482506
483507fn infringing_fields_error (
0 commit comments