@@ -1092,21 +1092,32 @@ pub fn resolveDerefBinding(analyser: *Analyser, pointer: Type) error{OutOfMemory
10921092pub const BracketAccess = union (enum ) {
10931093 /// `lhs[index]`
10941094 single : ? u64 ,
1095- /// `lhs[start..]`
1096- open : ? u64 ,
1097- /// `lhs[start..end]`
1098- range : ? struct { u64 , u64 },
1095+ /// `lhs[start.. :sentinel]`
1096+ open : struct {
1097+ start : ? u64 ,
1098+ sentinel : ? InternPool.Index ,
1099+ },
1100+ /// `lhs[start..end :sentinel]`
1101+ range : struct {
1102+ bounds : ? struct { u64 , u64 },
1103+ sentinel : ? InternPool.Index ,
1104+ },
10991105
11001106 pub fn fromSlice (
11011107 analyser : * Analyser ,
11021108 handle : * DocumentStore.Handle ,
1103- start_node : Ast.Node.Index ,
1104- end_node_maybe : ? Ast.Node.Index ,
1109+ slice : Ast.full.Slice ,
11051110 ) error {OutOfMemory }! BracketAccess {
1106- const end_node = end_node_maybe orelse
1107- return .{ .open = try analyser .resolveIntegerLiteral (u64 , .of (start_node , handle )) };
1111+ const start_node = slice .ast .start ;
1112+ const end_node = slice .ast .end .unwrap () orelse
1113+ return .{
1114+ .open = .{
1115+ .start = try analyser .resolveIntegerLiteral (u64 , .of (start_node , handle )),
1116+ .sentinel = try analyser .resolveOptionalIPValue (slice .ast .sentinel , handle ),
1117+ },
1118+ };
11081119
1109- const range = blk : {
1120+ const bounds = blk : {
11101121 const start = try analyser .resolveIntegerLiteral (u64 , .of (start_node , handle )) orelse
11111122 break :blk null ;
11121123
@@ -1116,7 +1127,12 @@ pub const BracketAccess = union(enum) {
11161127 break :blk .{ start , end };
11171128 };
11181129
1119- return .{ .range = range };
1130+ return .{
1131+ .range = .{
1132+ .bounds = bounds ,
1133+ .sentinel = try analyser .resolveOptionalIPValue (slice .ast .sentinel , handle ),
1134+ },
1135+ };
11201136 }
11211137};
11221138
@@ -1185,8 +1201,8 @@ pub fn resolveBracketAccessTypeFromBinding(analyser: *Analyser, lhs_binding: Bin
11851201 },
11861202 .array = > | info | switch (rhs ) {
11871203 .single = > return try info .elem_ty .instanceTypeVal (analyser ),
1188- .open = > | start_maybe | {
1189- if (start_maybe ) | start | {
1204+ .open = > | access | {
1205+ if (access . start ) | start | {
11901206 result = .{ .array = null };
11911207 if (info .elem_count ) | elem_count | {
11921208 if (start <= elem_count ) {
@@ -1197,16 +1213,17 @@ pub fn resolveBracketAccessTypeFromBinding(analyser: *Analyser, lhs_binding: Bin
11971213 sentinel = info .sentinel ;
11981214 break :elem info .elem_ty ;
11991215 },
1200- .range = > | range_maybe | {
1201- if (range_maybe ) | range | {
1216+ .range = > | access | {
1217+ if (access . bounds ) | bounds | {
12021218 result = .{ .array = null };
12031219 if (info .elem_count ) | elem_count | {
1204- const start , const end = range ;
1220+ const start , const end = bounds ;
12051221 if (start <= end and start <= elem_count and end <= elem_count ) {
12061222 result = .{ .array = end - start };
12071223 }
12081224 }
12091225 }
1226+ sentinel = access .sentinel orelse .none ;
12101227 break :elem info .elem_ty ;
12111228 },
12121229 },
@@ -1215,8 +1232,9 @@ pub fn resolveBracketAccessTypeFromBinding(analyser: *Analyser, lhs_binding: Bin
12151232 .tuple , .array = > continue :elem info .elem_ty .data ,
12161233 else = > switch (rhs ) {
12171234 .single , .open = > return null ,
1218- .range = > | range_maybe | {
1219- const start , const end = range_maybe orelse return null ;
1235+ .range = > | access | {
1236+ if (access .sentinel != null ) return null ;
1237+ const start , const end = access .bounds orelse return null ;
12201238 if (start > end or start > 1 or end > 1 ) return null ;
12211239 result = .{ .array = end - start };
12221240 break :elem info .elem_ty ;
@@ -1226,11 +1244,12 @@ pub fn resolveBracketAccessTypeFromBinding(analyser: *Analyser, lhs_binding: Bin
12261244 .many , .slice , .c = > switch (rhs ) {
12271245 .single = > try info .elem_ty .instanceTypeVal (analyser ),
12281246 .open = > lhs ,
1229- .range = > | range_maybe | {
1230- if (range_maybe ) | range | {
1231- const start , const end = range ;
1247+ .range = > | access | {
1248+ if (access . bounds ) | bounds | {
1249+ const start , const end = bounds ;
12321250 result = .{ .array = if (start <= end ) end - start else null };
12331251 }
1252+ sentinel = access .sentinel orelse .none ;
12341253 break :elem info .elem_ty ;
12351254 },
12361255 },
@@ -1359,6 +1378,15 @@ fn allDigits(str: []const u8) bool {
13591378 return true ;
13601379}
13611380
1381+ fn resolveOptionalIPValue (
1382+ analyser : * Analyser ,
1383+ optional_node : Ast.Node.OptionalIndex ,
1384+ handle : * DocumentStore.Handle ,
1385+ ) error {OutOfMemory }! ? InternPool.Index {
1386+ const node = optional_node .unwrap () orelse return null ;
1387+ return try analyser .resolveInternPoolValue (.of (node , handle ));
1388+ }
1389+
13621390fn resolveInternPoolValue (analyser : * Analyser , options : ResolveOptions ) error {OutOfMemory }! ? InternPool.Index {
13631391 const old_resolve_number_literal_values = analyser .resolve_number_literal_values ;
13641392 analyser .resolve_number_literal_values = true ;
@@ -1978,10 +2006,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) error
19782006 = > {
19792007 const ptr_info = ast .fullPtrType (tree , node ).? ;
19802008
1981- const sentinel = if (ptr_info .ast .sentinel .unwrap ()) | sentinel |
1982- try analyser .resolveInternPoolValue (.of (sentinel , handle )) orelse .none
1983- else
1984- .none ;
2009+ const sentinel = try analyser .resolveOptionalIPValue (ptr_info .ast .sentinel , handle ) orelse .none ;
19852010
19862011 const elem_ty = try analyser .resolveTypeOfNodeInternal (.of (ptr_info .ast .child_type , handle )) orelse return null ;
19872012 if (! elem_ty .is_type_val ) return null ;
@@ -2004,10 +2029,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) error
20042029 const array_info = tree .fullArrayType (node ).? ;
20052030
20062031 const elem_count = try analyser .resolveIntegerLiteral (u64 , .of (array_info .ast .elem_count , handle ));
2007- const sentinel = if (array_info .ast .sentinel .unwrap ()) | sentinel |
2008- try analyser .resolveInternPoolValue (.of (sentinel , handle )) orelse .none
2009- else
2010- .none ;
2032+ const sentinel = try analyser .resolveOptionalIPValue (array_info .ast .sentinel , handle ) orelse .none ;
20112033
20122034 const elem_ty = try analyser .resolveTypeOfNodeInternal (.of (array_info .ast .elem_type , handle )) orelse return null ;
20132035 if (! elem_ty .is_type_val ) return null ;
@@ -2966,7 +2988,7 @@ fn resolveBindingOfNodeUncached(analyser: *Analyser, options: ResolveOptions) er
29662988
29672989 const sliced = try analyser .resolveBindingOfNodeInternal (.of (slice .ast .sliced , handle )) orelse return null ;
29682990
2969- const kind : BracketAccess = try .fromSlice (analyser , handle , slice . ast . start , slice . ast . end . unwrap () );
2991+ const kind : BracketAccess = try .fromSlice (analyser , handle , slice );
29702992
29712993 return .{
29722994 .type = try analyser .resolveBracketAccessTypeFromBinding (sliced , kind ) orelse return null ,
@@ -4617,12 +4639,12 @@ pub fn getFieldAccessType(
46174639 },
46184640 .ellipsis2 = > {
46194641 if (bracket_count == 1 ) {
4620- kind = .{ .open = null };
4642+ kind = .{ .open = .{ . start = null , . sentinel = .none } };
46214643 }
46224644 },
46234645 else = > {
46244646 if (bracket_count == 1 and kind == .open ) {
4625- kind = .{ .range = null };
4647+ kind = .{ .range = .{ . bounds = null , . sentinel = .none } };
46264648 }
46274649 },
46284650 }
0 commit comments