mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
fix Bugzilla 24353 - add mutability check for foreach with opApply
Signed-off-by: royalpinto007 <royalpinto007@gmail.com>
This commit is contained in:
parent
f485dbfee1
commit
f5f7baeb19
2 changed files with 56 additions and 6 deletions
|
@ -779,14 +779,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
|
||||
Dsymbol sapplyOld = sapply; // 'sapply' will be NULL if and after 'inferApplyArgTypes' errors
|
||||
|
||||
/* Check for inference errors
|
||||
*/
|
||||
/* Check for inference errors and apply mutability checks inline */
|
||||
if (!inferApplyArgTypes(fs, sc, sapply))
|
||||
{
|
||||
/**
|
||||
Try and extract the parameter count of the opApply callback function, e.g.:
|
||||
int opApply(int delegate(int, float)) => 2 args
|
||||
*/
|
||||
bool foundMismatch = false;
|
||||
size_t foreachParamCount = 0;
|
||||
if (sapplyOld)
|
||||
|
@ -806,6 +801,19 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
auto tf = fparam.type.nextOf().isTypeFunction();
|
||||
foreachParamCount = tf.parameterList.length;
|
||||
foundMismatch = true;
|
||||
|
||||
// Mutability check
|
||||
if (fs.aggr && fs.aggr.type && fd.type && fs.aggr.type.isConst() && !fd.type.isConst())
|
||||
{
|
||||
// First error: The call site
|
||||
error(fs.loc, "mutable method `%s.%s` is not callable using a `const` object",
|
||||
fd.parent ? fd.parent.toPrettyChars() : "unknown", fd.toChars());
|
||||
|
||||
// Second error: Suggest how to fix
|
||||
errorSupplemental(fd.loc, "Consider adding `const` or `inout` here");
|
||||
|
||||
return setError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -824,6 +832,24 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
return setError();
|
||||
}
|
||||
|
||||
// If inference succeeds, proceed with post-checks
|
||||
if (sapply && sapply.isFuncDeclaration())
|
||||
{
|
||||
FuncDeclaration fd = sapply.isFuncDeclaration();
|
||||
|
||||
if (fs.aggr && fs.aggr.type && fd.type && fs.aggr.type.isConst() && !fd.type.isConst())
|
||||
{
|
||||
// First error: The call site
|
||||
error(fs.loc, "mutable method `%s.%s` is not callable using a `const` object",
|
||||
fd.parent ? fd.parent.toPrettyChars() : "unknown", fd.toChars());
|
||||
|
||||
// Second error: Suggest how to fix
|
||||
errorSupplemental(fd.loc, "Consider adding `const` or `inout` here");
|
||||
|
||||
return setError();
|
||||
}
|
||||
}
|
||||
|
||||
Type tab = fs.aggr.type.toBasetype();
|
||||
|
||||
if (tab.ty == Ttuple) // don't generate new scope for tuple loops
|
||||
|
|
24
compiler/test/fail_compilation/test24353.d
Normal file
24
compiler/test/fail_compilation/test24353.d
Normal file
|
@ -0,0 +1,24 @@
|
|||
// https://issues.dlang.org/show_bug.cgi?id=24353
|
||||
|
||||
/**
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/test24353.d(23): Error: mutable method `test24353.S.opApply` is not callable using a `const` object
|
||||
fail_compilation/test24353.d(14): Consider adding `const` or `inout` here
|
||||
---
|
||||
*/
|
||||
|
||||
|
||||
struct S
|
||||
{
|
||||
int opApply(int delegate(int) dg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void example()
|
||||
{
|
||||
const S s;
|
||||
foreach (e; s) {} // Error expected here
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue