Fix #20763 - Inconsistent handling of type + value in typeof expressions (#20798)

* Fix #20763 - Inconsistent handling of type + value in typeof expressions

* Add supplemental error

---------

Co-authored-by: Dennis Korpel <dennis@sarc.nl>
This commit is contained in:
Dennis 2025-01-29 11:26:01 +01:00 committed by GitHub
parent 3b863b9c28
commit 28bc5c6e74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 60 additions and 8 deletions

View file

@ -14769,11 +14769,16 @@ private bool checkArithmetic(Expression e, EXP op)
return true;
}
// FIXME: Existing code relies on adding / subtracting types in typeof() expressions:
// alias I = ulong; alias U = typeof(I + 1u);
// https://github.com/dlang/dmd/issues/20763
if (op == EXP.add || op == EXP.min)
if ((op == EXP.add || op == EXP.min) && e.isTypeExp())
{
// @@@DEPRECATED_2.121@@@
// Deprecated in 2.111
// In 2.121, remove this branch to let `checkValue` raise the error
deprecation(e.loc, "type `%s` has no value", e.toChars);
if (!e.type.isOpaqueType)
deprecationSupplemental(e.loc, "perhaps use `%s.init`", e.toChars);
return false;
}
return e.checkValue();
}
@ -14844,6 +14849,8 @@ bool checkValue(Expression e)
if (auto te = e.isTypeExp())
{
error(e.loc, "type `%s` has no value", e.toChars());
if (!e.type.isOpaqueType)
errorSupplemental(e.loc, "perhaps use `%s.init`", e.toChars());
return true;
}

View file

@ -7609,6 +7609,18 @@ bool checkRetType(TypeFunction tf, const ref Loc loc)
return false;
}
/// Returns: whether `t` is a struct/class/enum without a body
bool isOpaqueType(Type t)
{
if (auto te = t.isTypeEnum())
return te.sym.members is null;
if (auto ts = t.isTypeStruct())
return ts.sym.members is null;
if (auto tc = t.isTypeClass())
return tc.sym.members is null;
return false;
}
/******************************* Private *****************************************/