@@ -221,9 +221,9 @@ fn declarations_ty<'db>(
221
221
first
222
222
} ;
223
223
if conflicting. is_empty ( ) {
224
- DeclaredTypeResult :: Ok ( declared_ty)
224
+ Ok ( declared_ty)
225
225
} else {
226
- DeclaredTypeResult :: Err ( (
226
+ Err ( (
227
227
declared_ty,
228
228
[ first] . into_iter ( ) . chain ( conflicting) . collect ( ) ,
229
229
) )
@@ -900,37 +900,88 @@ impl<'db> CallOutcome<'db> {
900
900
}
901
901
}
902
902
903
- /// Get the return type of the call, emitting diagnostics if needed.
903
+ /// Get the return type of the call, emitting default diagnostics if needed.
904
904
fn unwrap_with_diagnostic < ' a > (
905
905
& self ,
906
906
db : & ' db dyn Db ,
907
907
node : ast:: AnyNodeRef ,
908
908
builder : & ' a mut TypeInferenceBuilder < ' db > ,
909
909
) -> Type < ' db > {
910
- match self {
911
- Self :: Callable { return_ty } => * return_ty,
912
- Self :: RevealType {
910
+ match self . return_ty_result ( db, node, builder) {
911
+ Ok ( return_ty) => return_ty,
912
+ Err ( NotCallableError :: Type {
913
+ not_callable_ty,
913
914
return_ty,
914
- revealed_ty,
915
- } => {
915
+ } ) => {
916
916
builder. add_diagnostic (
917
917
node,
918
- "revealed-type" ,
919
- format_args ! ( "Revealed type is '{}'." , revealed_ty. display( db) ) ,
918
+ "call-non-callable" ,
919
+ format_args ! (
920
+ "Object of type '{}' is not callable." ,
921
+ not_callable_ty. display( db)
922
+ ) ,
920
923
) ;
921
- * return_ty
924
+ return_ty
922
925
}
923
- Self :: NotCallable { not_callable_ty } => {
926
+ Err ( NotCallableError :: UnionElement {
927
+ not_callable_ty,
928
+ called_ty,
929
+ return_ty,
930
+ } ) => {
924
931
builder. add_diagnostic (
925
932
node,
926
933
"call-non-callable" ,
927
934
format_args ! (
928
- "Object of type '{}' is not callable." ,
929
- not_callable_ty. display( db)
935
+ "Object of type '{}' is not callable (due to union element '{}')." ,
936
+ called_ty. display( db) ,
937
+ not_callable_ty. display( db) ,
930
938
) ,
931
939
) ;
932
- Type :: Unknown
940
+ return_ty
933
941
}
942
+ Err ( NotCallableError :: UnionElements {
943
+ not_callable_tys,
944
+ called_ty,
945
+ return_ty,
946
+ } ) => {
947
+ builder. add_diagnostic (
948
+ node,
949
+ "call-non-callable" ,
950
+ format_args ! (
951
+ "Object of type '{}' is not callable (due to union elements {})." ,
952
+ called_ty. display( db) ,
953
+ not_callable_tys. display( db) ,
954
+ ) ,
955
+ ) ;
956
+ return_ty
957
+ }
958
+ }
959
+ }
960
+
961
+ /// Get the return type of the call as a result.
962
+ fn return_ty_result < ' a > (
963
+ & self ,
964
+ db : & ' db dyn Db ,
965
+ node : ast:: AnyNodeRef ,
966
+ builder : & ' a mut TypeInferenceBuilder < ' db > ,
967
+ ) -> Result < Type < ' db > , NotCallableError < ' db > > {
968
+ match self {
969
+ Self :: Callable { return_ty } => Ok ( * return_ty) ,
970
+ Self :: RevealType {
971
+ return_ty,
972
+ revealed_ty,
973
+ } => {
974
+ builder. add_diagnostic (
975
+ node,
976
+ "revealed-type" ,
977
+ format_args ! ( "Revealed type is '{}'." , revealed_ty. display( db) ) ,
978
+ ) ;
979
+ Ok ( * return_ty)
980
+ }
981
+ Self :: NotCallable { not_callable_ty } => Err ( NotCallableError :: Type {
982
+ not_callable_ty : * not_callable_ty,
983
+ return_ty : Type :: Unknown ,
984
+ } ) ,
934
985
Self :: Union {
935
986
outcomes,
936
987
called_ty,
@@ -959,41 +1010,75 @@ impl<'db> CallOutcome<'db> {
959
1010
} ;
960
1011
union_builder = union_builder. add ( return_ty) ;
961
1012
}
1013
+ let return_ty = union_builder. build ( ) ;
962
1014
match not_callable[ ..] {
963
- [ ] => { }
964
- [ elem] => builder. add_diagnostic (
965
- node,
966
- "call-non-callable" ,
967
- format_args ! (
968
- "Object of type '{}' is not callable (due to union element '{}')." ,
969
- called_ty. display( db) ,
970
- elem. display( db) ,
971
- ) ,
972
- ) ,
973
- _ if not_callable. len ( ) == outcomes. len ( ) => builder. add_diagnostic (
974
- node,
975
- "call-non-callable" ,
976
- format_args ! (
977
- "Object of type '{}' is not callable." ,
978
- called_ty. display( db)
979
- ) ,
980
- ) ,
981
- _ => builder. add_diagnostic (
982
- node,
983
- "call-non-callable" ,
984
- format_args ! (
985
- "Object of type '{}' is not callable (due to union elements {})." ,
986
- called_ty. display( db) ,
987
- not_callable. display( db) ,
988
- ) ,
989
- ) ,
1015
+ [ ] => Ok ( return_ty) ,
1016
+ [ elem] => Err ( NotCallableError :: UnionElement {
1017
+ not_callable_ty : elem,
1018
+ called_ty : * called_ty,
1019
+ return_ty,
1020
+ } ) ,
1021
+ _ if not_callable. len ( ) == outcomes. len ( ) => Err ( NotCallableError :: Type {
1022
+ not_callable_ty : * called_ty,
1023
+ return_ty,
1024
+ } ) ,
1025
+ _ => Err ( NotCallableError :: UnionElements {
1026
+ not_callable_tys : not_callable. into_boxed_slice ( ) ,
1027
+ called_ty : * called_ty,
1028
+ return_ty,
1029
+ } ) ,
990
1030
}
991
- union_builder. build ( )
992
1031
}
993
1032
}
994
1033
}
995
1034
}
996
1035
1036
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
1037
+ enum NotCallableError < ' db > {
1038
+ /// The type is not callable.
1039
+ Type {
1040
+ not_callable_ty : Type < ' db > ,
1041
+ return_ty : Type < ' db > ,
1042
+ } ,
1043
+ /// A single union element is not callable.
1044
+ UnionElement {
1045
+ not_callable_ty : Type < ' db > ,
1046
+ called_ty : Type < ' db > ,
1047
+ return_ty : Type < ' db > ,
1048
+ } ,
1049
+ /// Multiple (but not all) union elements are not callable.
1050
+ UnionElements {
1051
+ not_callable_tys : Box < [ Type < ' db > ] > ,
1052
+ called_ty : Type < ' db > ,
1053
+ return_ty : Type < ' db > ,
1054
+ } ,
1055
+ }
1056
+
1057
+ impl < ' db > NotCallableError < ' db > {
1058
+ /// The return type that should be used when a call is not callable.
1059
+ fn return_ty ( & self ) -> Type < ' db > {
1060
+ match self {
1061
+ Self :: Type { return_ty, .. } => * return_ty,
1062
+ Self :: UnionElement { return_ty, .. } => * return_ty,
1063
+ Self :: UnionElements { return_ty, .. } => * return_ty,
1064
+ }
1065
+ }
1066
+
1067
+ /// The resolved type that was not callable.
1068
+ ///
1069
+ /// For unions, returns the union type itself, which may contain a mix of callable and
1070
+ /// non-callable types.
1071
+ fn called_ty ( & self ) -> Type < ' db > {
1072
+ match self {
1073
+ Self :: Type {
1074
+ not_callable_ty, ..
1075
+ } => * not_callable_ty,
1076
+ Self :: UnionElement { called_ty, .. } => * called_ty,
1077
+ Self :: UnionElements { called_ty, .. } => * called_ty,
1078
+ }
1079
+ }
1080
+ }
1081
+
997
1082
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
998
1083
enum IterationOutcome < ' db > {
999
1084
Iterable { element_ty : Type < ' db > } ,
0 commit comments