@@ -328,12 +328,19 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
328328 . collect :: < Vec < _ > > ( ) ;
329329
330330 if coerced_fields. is_empty ( ) {
331- // `CoercePointeeValidated` will report a more specific error
332- res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSingle {
333- span,
334- trait_name : "DispatchFromDyn" ,
335- note : true ,
336- } ) ) ;
331+ if coerce_pointee_data. is_some ( ) {
332+ // `CoercePointeeValidated` will report a more specific error
333+ res = Err ( tcx. dcx ( ) . span_delayed_bug (
334+ span,
335+ "a more specific error from CoercePointee is expected" ,
336+ ) )
337+ } else {
338+ res = Err ( tcx. dcx ( ) . emit_err ( errors:: DispatchFromDynSingle {
339+ span,
340+ trait_name : "DispatchFromDyn" ,
341+ note : true ,
342+ } ) ) ;
343+ }
337344 } else if coerced_fields. len ( ) > 1 {
338345 if coerce_pointee_data. is_some ( ) {
339346 let spans =
@@ -405,6 +412,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
405412 }
406413 res
407414 }
415+ ( & Adt ( def, _) , _) if tcx. coerce_pointee_data ( ( ) ) . contains_key ( & def. did ( ) ) => {
416+ Err ( tcx. dcx ( ) . span_delayed_bug ( span, "a specific error for CoercePointee is expected" ) )
417+ }
408418 _ => Err ( tcx
409419 . dcx ( )
410420 . emit_err ( errors:: CoerceUnsizedMay { span, trait_name : "DispatchFromDyn" } ) ) ,
@@ -898,23 +908,44 @@ fn visit_implementation_of_coerce_pointee_validity(
898908 checker : & Checker < ' _ > ,
899909) -> Result < ( ) , ErrorGuaranteed > {
900910 let tcx = checker. tcx ;
901- let self_ty = tcx. impl_trait_ref ( checker. impl_def_id ) . unwrap ( ) . instantiate_identity ( ) . self_ty ( ) ;
902- let span = tcx. def_span ( checker. impl_def_id ) ;
903- if !tcx. is_builtin_derived ( checker. impl_def_id . into ( ) ) {
911+ let impl_did = checker. impl_def_id ;
912+ let self_ty = tcx. impl_trait_ref ( impl_did) . unwrap ( ) . instantiate_identity ( ) . self_ty ( ) ;
913+ let span = tcx. def_span ( impl_did) ;
914+ if !tcx. is_builtin_derived ( impl_did. into ( ) ) {
904915 return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoUserValidityAssertion { span } ) ) ;
905916 }
906- let ty:: Adt ( def, _args ) = self_ty. kind ( ) else {
917+ let ty:: Adt ( def, args ) = self_ty. kind ( ) else {
907918 return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNotConcreteType { span } ) ) ;
908919 } ;
909920 let did = def. did ( ) ;
910921 let Some ( info) = tcx. coerce_pointee_data ( ( ) ) . get ( & did) else {
911922 return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoUserValidityAssertion { span } ) ) ;
912923 } ;
913- if let & ty:: CoercePointeeInfo :: Duplicated { impls } = info {
914- return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeMultipleDerive {
915- spans : impls. iter ( ) . copied ( ) . map ( |did| tcx. def_span ( did) ) . collect ( ) ,
916- } ) ) ;
917- }
924+ let pointee_idx = match info {
925+ & ty:: CoercePointeeInfo :: Validated { pointee_index_in_args, .. } => pointee_index_in_args,
926+ ty:: CoercePointeeInfo :: PointeeUnnormalized { ty, .. } => {
927+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeNotGenericPointee {
928+ span,
929+ got : ty. to_string ( ) ,
930+ } ) ) ;
931+ }
932+ ty:: CoercePointeeInfo :: PointeeIsConst { konst, .. } => {
933+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeNotGenericPointee {
934+ span,
935+ got : konst. to_string ( ) ,
936+ } ) ) ;
937+ }
938+ ty:: CoercePointeeInfo :: Duplicated { impls } => {
939+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeMultipleDerive {
940+ spans : impls. iter ( ) . copied ( ) . map ( |did| tcx. def_span ( did) ) . collect ( ) ,
941+ } ) ) ;
942+ }
943+ ty:: CoercePointeeInfo :: PointeeNotFound { ty, .. } => {
944+ return Err ( tcx
945+ . dcx ( )
946+ . emit_err ( errors:: CoercePointeeNoPointee { span, ty : ty. to_string ( ) } ) ) ;
947+ }
948+ } ;
918949 // Now get a more precise span of the `struct`.
919950 let span = tcx. def_span ( did) ;
920951 if !def. is_struct ( ) {
@@ -926,8 +957,28 @@ fn visit_implementation_of_coerce_pointee_validity(
926957 return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNotTransparent { span } ) ) ;
927958 }
928959 if def. all_fields ( ) . next ( ) . is_none ( ) {
929- return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoField { span } ) ) ;
960+ return Err ( tcx. dcx ( ) . span_delayed_bug (
961+ span,
962+ "a specific error from CoercePointee is expected in CoerceUnsized coherence check" ,
963+ ) ) ;
930964 }
965+
966+ let infcx = tcx. infer_ctxt ( ) . build ( TypingMode :: non_body_analysis ( ) ) ;
967+ let param_env = tcx. param_env ( impl_did) ;
968+ let ocx = ObligationCtxt :: new ( & infcx) ;
969+ let cause = ObligationCause :: misc ( span, impl_did) ;
970+ let pointee_ty = args. type_at ( pointee_idx) ;
971+ let obligation = Obligation :: new (
972+ tcx,
973+ cause,
974+ param_env,
975+ ty:: TraitRef :: new ( tcx, tcx. require_lang_item ( LangItem :: Sized , None ) , [ pointee_ty] ) ,
976+ ) ;
977+ ocx. register_obligation ( obligation) ;
978+ if ocx. select_all_or_error ( ) . is_empty ( ) {
979+ return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeMissingMaybeSized { span } ) ) ;
980+ }
981+
931982 Ok ( ( ) )
932983}
933984
@@ -937,24 +988,16 @@ fn try_extract_coerce_pointee_data<'tcx>(
937988 info : & ty:: CoercePointeeInfo < ' tcx > ,
938989) -> Result < ( usize , DefId ) , ErrorGuaranteed > {
939990 match info {
940- ty:: CoercePointeeInfo :: PointeeUnnormalized { ty, .. } => Err ( tcx
941- . dcx ( )
942- . emit_err ( errors:: CoercePointeePointeeNotGenericPointee { span, got : ty. to_string ( ) } ) ) ,
943- ty:: CoercePointeeInfo :: PointeeIsConst { konst, .. } => {
944- Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeePointeeNotGenericPointee {
945- span,
946- got : konst. to_string ( ) ,
947- } ) )
948- }
949- ty:: CoercePointeeInfo :: Validated { pointee_index_in_args, impl_def_id } => {
950- Ok ( ( * pointee_index_in_args, * impl_def_id) )
951- }
952- ty:: CoercePointeeInfo :: Duplicated { .. } => Err ( tcx
953- . dcx ( )
954- . span_delayed_bug ( span, "a special error for duplicated CoercePointee is expected" ) ) ,
955- ty:: CoercePointeeInfo :: PointeeNotFound { ty, .. } => {
956- Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoPointee { span, ty : ty. to_string ( ) } ) )
991+ & ty:: CoercePointeeInfo :: Validated { pointee_index_in_args, impl_def_id } => {
992+ Ok ( ( pointee_index_in_args, impl_def_id) )
957993 }
994+ ty:: CoercePointeeInfo :: PointeeUnnormalized { .. }
995+ | ty:: CoercePointeeInfo :: PointeeIsConst { .. }
996+ | ty:: CoercePointeeInfo :: PointeeNotFound { .. }
997+ | ty:: CoercePointeeInfo :: Duplicated { .. } => Err ( tcx. dcx ( ) . span_delayed_bug (
998+ span,
999+ "a more specific error for malformed CoercePointee is expected" ,
1000+ ) ) ,
9581001 }
9591002}
9601003
0 commit comments