Skip to content

Commit 7936bf7

Browse files
authored
Fix trying to infer type for $ within slicing and indexing
1 parent 1503911 commit 7936bf7

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

compiler/src/dmd/dcast.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,6 +3340,12 @@ Expression inferType(Expression e, Type t, int flag = 0)
33403340
die.e1 = inferType(die.e1, t, flag);
33413341
}
33423342
}
3343+
else if (die.e1.op == EXP.call || die.e1.op == EXP.dotIdentifier)
3344+
{
3345+
// Handle chained expressions like $.a(10).b(20) or $.a.b.c
3346+
// Recursively infer type for the left side
3347+
die.e1 = inferType(die.e1, t, flag);
3348+
}
33433349
return die;
33443350
}
33453351

@@ -3353,6 +3359,11 @@ Expression inferType(Expression e, Type t, int flag = 0)
33533359
ce.e1 = inferType(ce.e1, t, flag);
33543360
}
33553361
}
3362+
else if (ce.e1.op == EXP.call || ce.e1.op == EXP.dotIdentifier)
3363+
{
3364+
// Handle chained calls like $.a(10)(20) or $.a.b(20)
3365+
ce.e1 = inferType(ce.e1, t, flag);
3366+
}
33563367
return ce;
33573368
}
33583369

compiler/src/dmd/dsymbolsem.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,8 +2347,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
23472347
}
23482348
else
23492349
{
2350-
.error(dsym.loc, "%s `%s` - type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`",
2351-
dsym.kind, dsym.toPrettyChars, dsym.type.toChars(), toChars(dsym._init));
2350+
.error(dsym.loc, "%s `%s` - type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`",
2351+
dsym.kind, dsym.toPrettyChars, dsym.type.toChars(), toChars(dsym._init));
23522352
}
23532353
}
23542354
else

compiler/src/dmd/expressionsem.d

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5401,6 +5401,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
54015401
return;
54025402
}
54035403

5404+
if (sc.scopesym && sc.scopesym.isArrayScopeSymbol())
5405+
{
5406+
visit(cast(IdentifierExp)exp);
5407+
return;
5408+
}
5409+
54045410
// if not found, it's $ waiting for type inference via implicitCastTo
54055411
exp.type = Type.tvoid;
54065412
result = exp;
@@ -15662,6 +15668,22 @@ private Expression expressionSemanticWithParent(Expression e, Scope* sc, Express
1566215668
return v.result;
1566315669
}
1566415670

15671+
/******
15672+
* Check if an expression contains a DollarExp (for chained $ inference)
15673+
*/
15674+
private bool containsDollarExp(Expression e)
15675+
{
15676+
if (!e)
15677+
return false;
15678+
if (e.isDollarExp())
15679+
return true;
15680+
if (auto ce = e.isCallExp())
15681+
return containsDollarExp(ce.e1);
15682+
if (auto die = e.isDotIdExp())
15683+
return containsDollarExp(die.e1);
15684+
return false;
15685+
}
15686+
1566515687
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
1566615688
{
1566715689
//printf("dotIdSemanticPropX() %s\n", toChars(exp));
@@ -15670,7 +15692,7 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
1567015692

1567115693
if (exp.e1.type == Type.tvoid)
1567215694
{
15673-
if (exp.e1.isDollarExp())
15695+
if (exp.e1.isDollarExp() || containsDollarExp(exp.e1))
1567415696
{
1567515697
auto n = new DotIdExp(exp.loc, exp.e1, exp.ident);
1567615698
n.type = Type.tvoid;

compiler/test/runnable/dollarinfer.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
struct HasSlicing {
2+
int[] data;
3+
auto opSlice(size_t i, size_t j) { return data[i .. j]; }
4+
@property size_t opDollar() { return data.length; }
5+
}
6+
17
enum MyEnum { VALUE_A, VALUE_B, VALUE_C }
28

39
struct Data {
@@ -46,4 +52,9 @@ void main() {
4652
assert(slice[0] == 20);
4753

4854
assert(slice[$ - 1] == 50);
55+
56+
HasSlicing t;
57+
t.data = [1, 2, 3, 4, 5];
58+
auto x = t[0 .. $];
59+
assert(x.length == 5);
4960
}

0 commit comments

Comments
 (0)