@@ -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