Skip to content

Commit

Permalink
fix Issue 15811 - -transition=import and -transition=checkimport have…
Browse files Browse the repository at this point in the history
… oddly behaviors
  • Loading branch information
9rnsr committed Mar 19, 2016
1 parent 5053844 commit 0683977
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 140 deletions.
85 changes: 34 additions & 51 deletions src/dscope.d
Expand Up @@ -512,69 +512,52 @@ struct Scope
return null;
}

if (global.params.check10378)
Dsymbol sold = void;
if (global.params.bug10378 || global.params.check10378)
{
sold = searchScopes(flags | IgnoreSymbolVisibility);
if (!global.params.check10378)
return sold;

// Search both ways
flags |= SearchCheck10378;
}

auto sold = searchScopes(flags | SearchCheck10378 | IgnoreSymbolVisibility);
// First look in local scopes
Dsymbol s = searchScopes(flags | SearchLocalsOnly);
version (LOGSEARCH) if (s) printMsg("-Scope.search() found local", s);
if (!s)
{
// Second look in imported modules
s = searchScopes(flags | SearchImportsOnly);
version (LOGSEARCH) if (s) printMsg("-Scope.search() found import", s);

auto snew = searchScopes(flags | SearchCheck10378 | SearchLocalsOnly);
if (!snew)
snew = searchScopes(flags | SearchCheck10378 | SearchImportsOnly);
if (!snew)
/** Still find private symbols, so that symbols that weren't access
* checked by the compiler remain usable. Once the deprecation is over,
* this should be moved to search_correct instead.
*/
if (!s)
{
snew = searchScopes(flags | SearchCheck10378 | SearchLocalsOnly | IgnoreSymbolVisibility);
if (!snew)
snew = searchScopes(flags | SearchCheck10378 | SearchImportsOnly | IgnoreSymbolVisibility);
if (snew)
.deprecation(loc, "%s is not visible from module %s", snew.toPrettyChars(), _module.toChars());
}
s = searchScopes(flags | SearchLocalsOnly | IgnoreSymbolVisibility);
if (!s)
s = searchScopes(flags | SearchImportsOnly | IgnoreSymbolVisibility);

if (s && !(flags & IgnoreErrors))
.deprecation(loc, "%s is not visible from module %s", s.toPrettyChars(), _module.toChars());
version (LOGSEARCH) if (s) printMsg("-Scope.search() found imported private symbol", s);
}
}
if (global.params.check10378)
{
alias snew = s;
if (sold !is snew)
{
deprecation(loc, "local import search method found %s %s instead of %s %s",
sold ? sold.kind() : "nothing", sold ? sold.toPrettyChars() : null,
snew ? snew.kind() : "nothing", snew ? snew.toPrettyChars() : null);
}
return sold;
}

if (global.params.bug10378)
return searchScopes(flags | IgnoreSymbolVisibility);

// First look in local scopes
Dsymbol s = searchScopes(flags | SearchLocalsOnly);

if (s)
{
version (LOGSEARCH)
printMsg("-Scope.search() found local", s);
return s;
}

s = searchScopes(flags | SearchImportsOnly); // look in imported modules

if (s)
{
version (LOGSEARCH)
printMsg("-Scope.search() found import", s);
return s;
}

/** Still find private symbols, so that symbols that weren't access
* checked by the compiler remain usable. Once the deprecation is over,
* this should be moved to search_correct instead.
*/
s = searchScopes(flags | SearchLocalsOnly | IgnoreSymbolVisibility);
if (!s)
s = searchScopes(flags | SearchImportsOnly | IgnoreSymbolVisibility);

if (s)
{
version (LOGSEARCH)
printMsg("-Scope.search() found imported private symbol", s);
if (!(flags & IgnoreErrors))
.deprecation(loc, "%s is not visible from module %s", s.toPrettyChars(), _module.toChars());
if (global.params.bug10378)
s = sold;
}
return s;
}
Expand Down
2 changes: 1 addition & 1 deletion src/dsymbol.d
Expand Up @@ -1276,7 +1276,7 @@ public:
//printf("%s.ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident.toChars(), flags);
//if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0;

if (global.params.bug10378)
if (global.params.bug10378 && !(flags & SearchCheck10378))
flags &= ~(SearchImportsOnly | SearchLocalsOnly);

// Look in symbols declared in this module
Expand Down
60 changes: 31 additions & 29 deletions src/expression.d
Expand Up @@ -667,55 +667,57 @@ extern (C++) Expression searchUFCS(Scope* sc, UnaExp ue, Identifier ident)
return s;
}

int flags = 0;
Dsymbol s;

if (global.params.check10378)
Dsymbol sold = void;
if (global.params.bug10378 || global.params.check10378)
{
// Search both ways

auto sold = searchScopes(SearchCheck10378 | IgnoreSymbolVisibility);

auto snew = searchScopes(SearchCheck10378 | SearchLocalsOnly);
if (!snew)
snew = searchScopes(SearchCheck10378 | SearchImportsOnly);
if (!snew)
sold = searchScopes(flags | IgnoreSymbolVisibility);
if (!global.params.check10378)
{
snew = searchScopes(SearchCheck10378 | SearchLocalsOnly | IgnoreSymbolVisibility);
if (!snew)
snew = searchScopes(SearchCheck10378 | SearchImportsOnly | IgnoreSymbolVisibility);
if (snew)
.deprecation(loc, "%s is not visible from module %s", snew.toPrettyChars(), sc._module.toChars());
s = sold;
goto Lsearchdone;
}

if (sold !is snew)
{
deprecation(loc, "local import search method found %s %s instead of %s %s",
sold ? sold.kind() : "nothing", sold ? sold.toPrettyChars() : null,
snew ? snew.kind() : "nothing", snew ? snew.toPrettyChars() : null);
}
s = sold;
// Search both ways
flags |= SearchCheck10378;
}
else if (global.params.bug10378)
s = searchScopes(0 | IgnoreSymbolVisibility);
else

// First look in local scopes
s = searchScopes(flags | SearchLocalsOnly);
if (!s)
{
s = searchScopes(SearchLocalsOnly);
if (!s)
s = searchScopes(SearchImportsOnly);
// Second look in imported modules
s = searchScopes(flags | SearchImportsOnly);

/** Still find private symbols, so that symbols that weren't access
* checked by the compiler remain usable. Once the deprecation is over,
* this should be moved to search_correct instead.
*/
if (!s)
{
s = searchScopes(SearchLocalsOnly | IgnoreSymbolVisibility);
s = searchScopes(flags | SearchLocalsOnly | IgnoreSymbolVisibility);
if (!s)
s = searchScopes(SearchImportsOnly | IgnoreSymbolVisibility);
s = searchScopes(flags | SearchImportsOnly | IgnoreSymbolVisibility);

if (s)
.deprecation(loc, "%s is not visible from module %s", s.toPrettyChars(), sc._module.toChars());
}
}
if (global.params.check10378)
{
alias snew = s;
if (sold !is snew)
{
deprecation(loc, "local import search method found %s %s instead of %s %s",
sold ? sold.kind() : "nothing", sold ? sold.toPrettyChars() : null,
snew ? snew.kind() : "nothing", snew ? snew.toPrettyChars() : null);
}
if (global.params.bug10378)
s = sold;
}
Lsearchdone:

if (!s)
return ue.e1.type.Type.getProperty(loc, ident, 0);
Expand Down
3 changes: 0 additions & 3 deletions src/mars.d
Expand Up @@ -641,7 +641,6 @@ Language changes listed by -transition=id:
break;
case 10378:
global.params.bug10378 = true;
global.params.check10378 = false;
break;
case 14488:
global.params.vcomplex = true;
Expand All @@ -662,7 +661,6 @@ Language changes listed by -transition=id:
break;
case "checkimports":
global.params.check10378 = true;
global.params.bug10378 = false;
break;
case "complex":
global.params.vcomplex = true;
Expand All @@ -672,7 +670,6 @@ Language changes listed by -transition=id:
break;
case "import":
global.params.bug10378 = true;
global.params.check10378 = false;
break;
case "tls":
global.params.vtls = true;
Expand Down
23 changes: 0 additions & 23 deletions test/fail_compilation/checkimports.d

This file was deleted.

20 changes: 20 additions & 0 deletions test/fail_compilation/checkimports1a.d
@@ -0,0 +1,20 @@
// REQUIRED_ARGS: -transition=checkimports -de
/*
TEST_OUTPUT:
---
fail_compilation/checkimports1a.d(16): Deprecation: local import search method found struct imports.diag12598a.lines instead of variable checkimports1a.C.lines
---
*/


// new lookup + information
class C
{
void f()
{
import imports.diag12598a;
lines ~= "";
}

string[] lines;
}
20 changes: 20 additions & 0 deletions test/fail_compilation/checkimports1b.d
@@ -0,0 +1,20 @@
// REQUIRED_ARGS: -transition=import -transition=checkimports
/*
TEST_OUTPUT:
---
fail_compilation/checkimports1b.d(16): Deprecation: local import search method found struct imports.diag12598a.lines instead of variable checkimports1b.C.lines
fail_compilation/checkimports1b.d(16): Error: struct 'lines' is a type, not an lvalue
---
*/

// old lookup + information
class C
{
void f()
{
import imports.diag12598a;
lines ~= "";
}

string[] lines;
}
20 changes: 20 additions & 0 deletions test/fail_compilation/checkimports1c.d
@@ -0,0 +1,20 @@
// REQUIRED_ARGS: -transition=checkimports -transition=import
/*
TEST_OUTPUT:
---
fail_compilation/checkimports1c.d(16): Deprecation: local import search method found struct imports.diag12598a.lines instead of variable checkimports1c.C.lines
fail_compilation/checkimports1c.d(16): Error: struct 'lines' is a type, not an lvalue
---
*/

// old lookup + information (the order of switches is reverse)
class C
{
void f()
{
import imports.diag12598a;
lines ~= "";
}

string[] lines;
}
31 changes: 0 additions & 31 deletions test/fail_compilation/checkimports2.d

This file was deleted.

37 changes: 37 additions & 0 deletions test/fail_compilation/checkimports2a.d
@@ -0,0 +1,37 @@
// REQUIRED_ARGS: -transition=checkimports
/*
TEST_OUTPUT:
---
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.Y found in local import
fail_compilation/checkimports2a.d(27): Deprecation: local import search method found variable imports.imp1.Y instead of variable imports.imp2.Y
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.X found in local import
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.X found in local import
fail_compilation/checkimports2a.d(32): Error: no property 'X' for type 'checkimports2a.B'
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.Y found in local import
fail_compilation/checkimports2a.d(33): Error: no property 'Y' for type 'checkimports2a.B'
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.X found in local import
fail_compilation/checkimports2a.d(23): Deprecation: class checkimports2a.B variable imports.imp2.Y found in local import
---
*/

// new lookup + information

import imports.imp1;

enum X = 0;

class B
{
import imports.imp2;
static assert(X == 0); // imp2.X --> .X
int[Y] aa; // imp2.Y
}

class C : B
{
static assert(B.X == 0); // imp2.X --> error
static assert(B.Y == 2); // imp2.Y --> error

static assert(X == 0); // imp2.X --> .X
static assert(Y == 1); // imp2.Y --> imp1.Y
}

0 comments on commit 0683977

Please sign in to comment.