@@ -328,12 +328,19 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
328
328
. collect :: < Vec < _ > > ( ) ;
329
329
330
330
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
+ }
337
344
} else if coerced_fields. len ( ) > 1 {
338
345
if coerce_pointee_data. is_some ( ) {
339
346
let spans =
@@ -405,6 +412,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
405
412
}
406
413
res
407
414
}
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
+ }
408
418
_ => Err ( tcx
409
419
. dcx ( )
410
420
. emit_err ( errors:: CoerceUnsizedMay { span, trait_name : "DispatchFromDyn" } ) ) ,
@@ -898,23 +908,44 @@ fn visit_implementation_of_coerce_pointee_validity(
898
908
checker : & Checker < ' _ > ,
899
909
) -> Result < ( ) , ErrorGuaranteed > {
900
910
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 ( ) ) {
904
915
return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoUserValidityAssertion { span } ) ) ;
905
916
}
906
- let ty:: Adt ( def, _args ) = self_ty. kind ( ) else {
917
+ let ty:: Adt ( def, args ) = self_ty. kind ( ) else {
907
918
return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNotConcreteType { span } ) ) ;
908
919
} ;
909
920
let did = def. did ( ) ;
910
921
let Some ( info) = tcx. coerce_pointee_data ( ( ) ) . get ( & did) else {
911
922
return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNoUserValidityAssertion { span } ) ) ;
912
923
} ;
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
+ } ;
918
949
// Now get a more precise span of the `struct`.
919
950
let span = tcx. def_span ( did) ;
920
951
if !def. is_struct ( ) {
@@ -926,8 +957,28 @@ fn visit_implementation_of_coerce_pointee_validity(
926
957
return Err ( tcx. dcx ( ) . emit_err ( errors:: CoercePointeeNotTransparent { span } ) ) ;
927
958
}
928
959
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
+ ) ) ;
930
964
}
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
+
931
982
Ok ( ( ) )
932
983
}
933
984
@@ -937,24 +988,16 @@ fn try_extract_coerce_pointee_data<'tcx>(
937
988
info : & ty:: CoercePointeeInfo < ' tcx > ,
938
989
) -> Result < ( usize , DefId ) , ErrorGuaranteed > {
939
990
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) )
957
993
}
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
+ ) ) ,
958
1001
}
959
1002
}
960
1003
0 commit comments