@@ -152,6 +152,7 @@ export ty_fn_args;
152
152
export type_constr;
153
153
export type_contains_params;
154
154
export type_contains_vars;
155
+ export type_kind;
155
156
export type_err;
156
157
export type_err_to_str;
157
158
export type_has_dynamic_size;
@@ -216,6 +217,7 @@ type ctxt =
216
217
rcache : creader_cache ,
217
218
short_names_cache : hashmap [ t, str] ,
218
219
has_pointer_cache: hashmap[ t, bool] ,
220
+ kind_cache: hashmap[ t, ast:: kind] ,
219
221
owns_heap_mem_cache: hashmap[ t, bool] ,
220
222
ast_ty_to_ty_cache: hashmap[ @ast:: ty, option:: t[ t] ] } ;
221
223
@@ -409,6 +411,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
409
411
rcache: mk_rcache ( ) ,
410
412
short_names_cache: map:: mk_hashmap ( ty:: hash_ty, ty:: eq_ty) ,
411
413
has_pointer_cache: map:: mk_hashmap ( ty:: hash_ty, ty:: eq_ty) ,
414
+ kind_cache: map:: mk_hashmap ( ty:: hash_ty, ty:: eq_ty) ,
412
415
owns_heap_mem_cache: map:: mk_hashmap ( ty:: hash_ty, ty:: eq_ty) ,
413
416
ast_ty_to_ty_cache: map:: mk_hashmap ( ast:: hash_ty, ast:: eq_ty) } ;
414
417
populate_type_store ( cx) ;
@@ -981,7 +984,10 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
981
984
ty_native ( _) { /* no-op */ }
982
985
ty_rec ( flds) {
983
986
for f: field in flds {
984
- if type_has_pointers ( cx, f. mt . ty ) { result = true ; }
987
+ if type_has_pointers ( cx, f. mt . ty ) {
988
+ result = true ;
989
+ break ;
990
+ }
985
991
}
986
992
}
987
993
ty_tag ( did, tps) {
@@ -990,8 +996,12 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
990
996
for aty: t in variant. args {
991
997
// Perform any type parameter substitutions.
992
998
let arg_ty = substitute_type_params ( cx, tps, aty) ;
993
- if type_has_pointers ( cx, arg_ty) { result = true ; }
999
+ if type_has_pointers ( cx, arg_ty) {
1000
+ result = true ;
1001
+ break ;
1002
+ }
994
1003
}
1004
+ if result { break ; }
995
1005
}
996
1006
}
997
1007
ty_res ( did, inner, tps) {
@@ -1005,6 +1015,122 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
1005
1015
ret result;
1006
1016
}
1007
1017
1018
+ fn type_kind ( cx : & ctxt , ty : & t ) -> ast:: kind {
1019
+ alt cx. kind_cache . find ( ty) {
1020
+ some ( result) { ret result; }
1021
+ none. { /* fall through */ }
1022
+ }
1023
+
1024
+ let result = ast:: kind_unique;
1025
+
1026
+ // Insert a default in case we loop back on self recursively.
1027
+ cx. kind_cache . insert ( ty, result) ;
1028
+
1029
+ alt struct( cx, ty) {
1030
+
1031
+ // Scalar types are unique-kind, no substructure.
1032
+ ty_nil. | ty_bot . | ty_bool . | ty_int . | ty_uint . | ty_float .
1033
+ | ty_machine ( _) | ty_char. | ty_native ( _) {
1034
+ // no-op
1035
+ }
1036
+
1037
+ // A handful of other built-in are unique too.
1038
+ ty_type. | ty_istr . | ty_native_fn ( _, _, _) {
1039
+ // no-op
1040
+ }
1041
+
1042
+ // Those things with refcounts-to-interior are just shared.
1043
+ ty_str. | ty_task . {
1044
+ result = kind_shared;
1045
+ }
1046
+
1047
+ // FIXME: obj is broken for now, since we aren't asserting
1048
+ // anything about its fields.
1049
+ ty_obj ( _) { result = kind_shared; }
1050
+
1051
+ // FIXME: the environment capture mode is not fully encoded
1052
+ // here yet, leading to weirdness around closure.
1053
+ ty_fn ( proto, _, _, _, _) {
1054
+ result = alt proto {
1055
+ ast : : proto_block. { ast:: kind_pinned }
1056
+ ast:: proto_closure. { ast:: kind_shared }
1057
+ _ { ast : : kind_unique }
1058
+ }
1059
+ }
1060
+
1061
+ // Those with refcounts-to-inner are the lower of their
1062
+ // inner and shared.
1063
+ ty_box ( mt) | ty_vec ( mt) {
1064
+ result = kind:: lower_kind ( ast:: kind_shared,
1065
+ type_kind ( cx, mt. ty ) ) ;
1066
+
1067
+ }
1068
+
1069
+ // FIXME: remove ports. Ports currently contribute 'shared'
1070
+ ty_port ( t) {
1071
+ result = kind:: lower_kind ( ast:: kind_shared,
1072
+ type_kind ( cx, t) ) ;
1073
+ }
1074
+
1075
+ // FIXME: remove chans. Chans currently contribute only
1076
+ // their inner.
1077
+ ty_chan ( t) {
1078
+ result = type_kind ( cx, t) ;
1079
+ }
1080
+
1081
+ // Pointers and unique boxes / vecs lower to whatever they point to.
1082
+ ty_ptr ( tm) | ty_ivec ( tm) {
1083
+ result = type_kind ( cx, tm. ty ) ;
1084
+ }
1085
+
1086
+ // Records lower to the lowest of their members.
1087
+ ty_rec ( flds) {
1088
+ for f: field in flds {
1089
+ result = kind:: lower_kind ( result, type_kind ( cx, f. mt . ty ) ) ;
1090
+ if result == ast:: kind_pinned { break ; }
1091
+ }
1092
+ }
1093
+
1094
+ // Tags lower to the lowest of their variants.
1095
+ ty_tag ( did, tps) {
1096
+ let variants = tag_variants ( cx, did) ;
1097
+ for variant: variant_info in variants {
1098
+ for aty: t in variant. args {
1099
+ // Perform any type parameter substitutions.
1100
+ let arg_ty = substitute_type_params ( cx, tps, aty) ;
1101
+ result = kind:: lower_kind ( result, type_kind ( cx, arg_ty) ) ;
1102
+ if result == ast:: kind_pinned { break ; }
1103
+ }
1104
+ if result == ast:: kind_pinned { break ; }
1105
+ }
1106
+ }
1107
+
1108
+ // Resources are always pinned.
1109
+ ty_res ( did, inner, tps) {
1110
+ result = ast:: kind_pinned;
1111
+ }
1112
+
1113
+ ty_var ( _) { fail; }
1114
+
1115
+ ty_param ( _) {
1116
+ // FIXME: this should contribute the kind-bound of the typaram,
1117
+ // when those exist.
1118
+ }
1119
+
1120
+ ty_constr ( t, _) {
1121
+ result = type_kind ( cx, t) ;
1122
+ }
1123
+
1124
+ _ {
1125
+ cx. sess . bug ( "missed case: " + ty_to_str ( cx, ty) ) ;
1126
+ }
1127
+
1128
+ }
1129
+
1130
+ cx. kind_cache . insert ( ty, result) ;
1131
+ ret result;
1132
+ }
1133
+
1008
1134
1009
1135
// FIXME: should we just return true for native types in
1010
1136
// type_is_scalar?
0 commit comments