Skip to content

Commit

Permalink
Reorder PURExxx values then remove ugly function isPureBypassingInfer…
Browse files Browse the repository at this point in the history
…enceX()

By this, we can use following convenient conditions to chech inference process.

- isPureBypassingInference() == PUREimpure
  The function is already determined to impure.
- isPureBypassingInference() == PUREfwdref
  The function is in inference process.
- isPureBypassingInference() >= PUREfwdref
  The function is in inference process or determined to pure.
- isPureBypassingInference() >= PUREweak
  The function is already determined to pure.
  • Loading branch information
9rnsr committed Jan 26, 2015
1 parent f4c2c4b commit 29691e0
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 21 deletions.
1 change: 0 additions & 1 deletion src/declaration.h
Expand Up @@ -626,7 +626,6 @@ class FuncDeclaration : public Declaration
bool hasOverloads();
PURE isPure();
PURE isPureBypassingInference();
bool isPureBypassingInferenceX();
bool setImpure();
bool isSafe();
bool isSafeBypassingInference();
Expand Down
16 changes: 8 additions & 8 deletions src/expression.c
Expand Up @@ -2384,19 +2384,19 @@ void Expression::checkPurity(Scope *sc, FuncDeclaration *f)

// Find the closest pure parent of the calling function
FuncDeclaration *outerfunc = sc->func;
while ( outerfunc->toParent2() &&
!outerfunc->isPureBypassingInference() &&
outerfunc->toParent2()->isFuncDeclaration())
while (outerfunc->toParent2() &&
outerfunc->isPureBypassingInference() == PUREimpure &&
outerfunc->toParent2()->isFuncDeclaration())
{
outerfunc = outerfunc->toParent2()->isFuncDeclaration();
if (outerfunc->type->ty == Terror)
return;
}

FuncDeclaration *calledparent = f;
while ( calledparent->toParent2() &&
!calledparent->isPureBypassingInference() &&
calledparent->toParent2()->isFuncDeclaration())
while (calledparent->toParent2() &&
calledparent->isPureBypassingInference() == PUREimpure &&
calledparent->toParent2()->isFuncDeclaration())
{
calledparent = calledparent->toParent2()->isFuncDeclaration();
if (calledparent->type->ty == Terror)
Expand All @@ -2408,7 +2408,7 @@ void Expression::checkPurity(Scope *sc, FuncDeclaration *f)
if (!f->isPure() && calledparent != outerfunc)
{
FuncDeclaration *ff = outerfunc;
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInferenceX() : ff->setImpure())
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
{
error("pure function '%s' cannot call impure function '%s'",
ff->toPrettyChars(), f->toPrettyChars());
Expand Down Expand Up @@ -2453,7 +2453,7 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v)
* functions must be pure.
*/
FuncDeclaration *ff = sc->func;
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInferenceX() : ff->setImpure())
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
{
error("pure function '%s' cannot access mutable static data '%s'",
ff->toPrettyChars(), v->toChars());
Expand Down
7 changes: 1 addition & 6 deletions src/func.c
Expand Up @@ -473,7 +473,7 @@ void FuncDeclaration::semantic(Scope *sc)
/* If the parent's purity is inferred, then this function's purity needs
* to be inferred first.
*/
if (fd && fd->isPureBypassingInferenceX())
if (fd && fd->isPureBypassingInference() >= PUREweak)
tf->purity = PUREfwdref; // default to pure
}
}
Expand Down Expand Up @@ -3553,11 +3553,6 @@ PURE FuncDeclaration::isPureBypassingInference()
return isPure();
}

bool FuncDeclaration::isPureBypassingInferenceX()
{
return !(flags & FUNCFLAGpurityInprocess) && isPure() != PUREimpure;
}

/**************************************
* The function is doing something impure,
* so mark it as impure.
Expand Down
7 changes: 5 additions & 2 deletions src/mtype.c
Expand Up @@ -6039,6 +6039,7 @@ bool TypeFunction::hasLazyParameters()

bool TypeFunction::parameterEscapes(Parameter *p)
{
purityLevel();

/* Scope parameters do not escape.
* Allow 'lazy' to imply 'scope' -
Expand All @@ -6057,12 +6058,14 @@ bool TypeFunction::parameterEscapes(Parameter *p)
return true;

if (purity > PUREweak)
{ /* With pure functions, we need only be concerned if p escapes
{
/* With pure functions, we need only be concerned if p escapes
* via any return statement.
*/
Type* tret = nextOf()->toBasetype();
if (!isref && !tret->hasPointers())
{ /* The result has no references, so p could not be escaping
{
/* The result has no references, so p could not be escaping
* that way.
*/
return false;
Expand Down
8 changes: 4 additions & 4 deletions src/mtype.h
Expand Up @@ -589,10 +589,10 @@ enum TRUSTformat
enum PURE
{
PUREimpure = 0, // not pure at all
PUREweak = 1, // no mutable globals are read or written
PUREconst = 2, // parameters are values or const
PUREstrong = 3, // parameters are values or immutable
PUREfwdref = 4, // it's pure, but not known which level yet
PUREfwdref = 1, // it's pure, but not known which level yet
PUREweak = 2, // no mutable globals are read or written
PUREconst = 3, // parameters are values or const
PUREstrong = 4, // parameters are values or immutable
};

RET retStyle(TypeFunction *tf);
Expand Down

0 comments on commit 29691e0

Please sign in to comment.