Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Hide module members #739

Closed
wants to merge 7 commits into from

7 participants

@MartinNowak
Collaborator
  • restrict visibility of module level symbols to given access rights
  • restrict access rights when searching across imported modules
@MartinNowak MartinNowak referenced this pull request
Closed

Fix imports #734

@MartinNowak
Collaborator

I eventually found the bug in the previous pulls. It was a missing 'return', which dmc nicely warned about. I also had to turn on optimizations when compiling dmd.

@yebblies
Collaborator

If only we had a better language that would catch these kinds of errors...

@WalterBright
  1. Need test cases to verify what it is doing.

  2. Does this address http://d.puremagic.com/issues/show_bug.cgi?id=313 ?

  3. What about http://d.puremagic.com/issues/show_bug.cgi?id=314 ?

@MartinNowak
Collaborator

This pull request is intended as a prerequisite for fixing protection and imports.
It is a protection fix and only addresses the issue that private symbols
can cause conflicts in dependent modules.

It is needed to fix selective imports properly IMO because access
checks alone would not solve ambiguities.

Does this address http://d.puremagic.com/issues/show_bug.cgi?id=313 ?

No, this needs a completely unrelated fix.

What about http://d.puremagic.com/issues/show_bug.cgi?id=314 ?

This is addressed by #734 which depends on this pull request.

@MartinNowak
Collaborator

Retest.
There was an unrelated FreeBSD semaphore failure.

@andralex
Owner

LGTM, please review. Do we need changes to the documentation? I don't think we currently have a detailed explanation of protection rules, so it's a good opportunity to get a document in along with these fresh changes.

@braddr braddr referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
MartinNowak added some commits
@MartinNowak MartinNowak hide private/package module level symbols
- restrict visibility of module level symbols to given access rights

- restrict access rights when searching across imported modules
bdfbf55
@MartinNowak MartinNowak adapt search_correct
- find private symbols
- take first symbol for ambiguous proposals
- don't report errors for Scope::search_correct
1d1f484
@MartinNowak MartinNowak partial-fix of #143 65c60c0
@MartinNowak MartinNowak fix issue 1238 cea27c7
@MartinNowak MartinNowak fix issue 1754 6d57170
@MartinNowak MartinNowak fix issue 2991 0d17e30
@MartinNowak MartinNowak more verbose search correct proposals
- print protection and kind
- print fully qualified name
401bc91
@andralex
Owner

ping

@MartinNowak
Collaborator

This pull contains a new approach on how overloads are handled.
Namely the visibility of an overload set is determined by the most visible overload.
After overload resolution we still perform an access check with the actual function.

That way overload resolution is not affected by the lookup origin which is an even bigger concern when the same concept is applied to struct/classes instead of modules. I hope I'll find some time to update DIP22 accordingly soon.

@Dicebot

@dawgfoto please ping me when DIP22 description gets updated to match pull.

@9rnsr
Collaborator

The 'symbol visibility concept' is not bad, but Dsymbol::overprot is not good to me. Because it requires enumerating overload list at least twice, and it doesn't work for TemplateDeclaration. I think that protection checks should be delayed for isOverloadable symbols (they would be properly done in overloadApply and findTemplateDeclaration).

@MartinNowak
Collaborator

I also think that the same rules should apply for UDTs. That might require a little more thought so finishing DIP22 is the first step.

@9rnsr
Collaborator

What means "UDT" ?

@MartinNowak
Collaborator

User-Defined Type, i.e. structs and classes. I just added it to http://wiki.dlang.org/Commonly-Used_Acronyms.

@quickfur

ping

Looks like this pull needs a rebase? I'd like to see this merged, as currently we have the ridiculous situation where private symbols in an imported module can conflict with public symbols imported from another module, when it should be clear that any reference to that symbol must refer to the public one. Specific example: std.regex declares a private symbol Stack, which means if you import another module with a public Stack, they will conflict.

@MartinNowak
Collaborator

That's the point. It's a huge problem, but I currently lack the time for this. It also requires a rewrite rather than a rebase, becase too much code changed in this area. Also we should first finish DIP22 and get it approved.

@Dicebot Dicebot referenced this pull request in D-Programming-Language/phobos
Closed

[enh] Add analog of TypeTuple that does not auto-expand #1633

@MartinNowak
Collaborator
@MartinNowak
Collaborator

Closing this until we finish and approve DIP22. It's still a fundamental problem that needs to be addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 24, 2013
  1. @MartinNowak

    hide private/package module level symbols

    MartinNowak authored MartinNowak committed
    - restrict visibility of module level symbols to given access rights
    
    - restrict access rights when searching across imported modules
  2. @MartinNowak

    adapt search_correct

    MartinNowak authored MartinNowak committed
    - find private symbols
    - take first symbol for ambiguous proposals
    - don't report errors for Scope::search_correct
  3. @MartinNowak

    partial-fix of #143

    MartinNowak authored MartinNowak committed
  4. @MartinNowak

    fix issue 1238

    MartinNowak authored MartinNowak committed
  5. @MartinNowak

    fix issue 1754

    MartinNowak authored MartinNowak committed
  6. @MartinNowak

    fix issue 2991

    MartinNowak authored MartinNowak committed
  7. @MartinNowak

    more verbose search correct proposals

    MartinNowak authored MartinNowak committed
    - print protection and kind
    - print fully qualified name
This page is out of date. Refresh to see the latest.
View
10 src/access.c
@@ -410,3 +410,13 @@ void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
cd->accessCheck(loc, sc, d);
}
}
+
+enum PROT moduleVisibility(Module *from, Module *to)
+{
+ if (from == to)
+ return PROTprivate;
+ else if (from && to && from->parent && from->parent == to->parent)
+ return PROTpackage;
+ else
+ return PROTpublic;
+}
View
3  src/declaration.h
@@ -661,7 +661,7 @@ struct FuncDeclaration : Declaration
void appendExp(Expression *e);
void appendState(Statement *s);
char *mangle();
- const char *toPrettyChars();
+ const char *toPrettyChars(bool verbose=false);
int isMain();
int isWinMain();
int isDllMain();
@@ -691,6 +691,7 @@ struct FuncDeclaration : Declaration
int canInline(int hasthis, int hdrscan, int statementsToo);
Expression *expandInline(InlineScanState *iss, Expression *ethis, Expressions *arguments, Statement **ps);
const char *kind();
+ enum PROT overprot();
void toDocBuffer(OutBuffer *buf, Scope *sc);
FuncDeclaration *isUnique();
void checkNestedReference(Scope *sc, Loc loc);
View
99 src/dsymbol.c
@@ -178,35 +178,42 @@ char *Dsymbol::toChars()
return ident ? ident->toChars() : (char *)"__anonymous";
}
-const char *Dsymbol::toPrettyChars()
-{ Dsymbol *p;
- char *s;
- char *q;
- size_t len;
+const char *Dsymbol::toPrettyChars(bool verbose)
+{
//printf("Dsymbol::toPrettyChars() '%s'\n", toChars());
- if (!parent)
+ if (!verbose && !parent)
return toChars();
- len = 0;
- for (p = this; p; p = p->parent)
+ OutBuffer buf;
+ if (verbose)
+ {
+ if (enum PROT p = prot())
+ {
+ buf.writestring(Pprotectionnames[p]);
+ buf.writeByte(' ');
+ }
+ buf.writestring(kind());
+ buf.writeByte(' ');
+ }
+
+ size_t len = 0;
+ for (Dsymbol *p = this; p; p = p->parent)
len += strlen(p->toChars()) + 1;
- s = (char *)mem.malloc(len);
- q = s + len - 1;
+ buf.reserve(len);
+ char *q = (char*)buf.data + buf.offset + len - 1;
*q = 0;
- for (p = this; p; p = p->parent)
+ for (Dsymbol *p = this; p; p = p->parent)
{
+ if (p != this) *--q = '.';
char *t = p->toChars();
len = strlen(t);
q -= len;
memcpy(q, t, len);
- if (q == s)
- break;
- q--;
- *q = '.';
}
- return s;
+ assert(q == (char*)buf.data + buf.offset);
+ return buf.extractData();
}
Loc& Dsymbol::getLoc()
@@ -364,7 +371,7 @@ void Dsymbol::inlineScan()
/*********************************************
* Search for ident as member of s.
* Input:
- * flags: 1 don't find private members
+ * flags: 1 don't restrict visibility
* 2 don't give error messages
* 4 return NULL if ambiguous
* Returns:
@@ -397,7 +404,7 @@ void *symbol_search_fp(void *arg, const char *seed)
Dsymbol *s = (Dsymbol *)arg;
Module::clearCache();
- return s->search(0, id, 4|2);
+ return s->search(0, id, 1|2);
}
Dsymbol *Dsymbol::search_correct(Identifier *ident)
@@ -405,7 +412,10 @@ Dsymbol *Dsymbol::search_correct(Identifier *ident)
if (global.gag)
return NULL; // don't do it for speculative compiles; too time consuming
- return (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, this, idchars);
+ Dsymbol *s = search(0, ident, 1|2); // repeat search including private symbols
+ if (!s)
+ s = (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, this, idchars);
+ return s;
}
/***************************************
@@ -438,8 +448,8 @@ Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id)
{
sm = s->search_correct(id);
if (sm)
- error("template identifier '%s' is not a member of '%s %s', did you mean '%s %s'?",
- id->toChars(), s->kind(), s->toChars(), sm->kind(), sm->toChars());
+ error("template identifier '%s' is not a member of '%s %s', did you mean '%s'?",
+ id->toChars(), s->kind(), s->toChars(), sm->toPrettyChars(true));
else
error("template identifier '%s' is not a member of '%s %s'",
id->toChars(), s->kind(), s->toChars());
@@ -743,6 +753,11 @@ enum PROT Dsymbol::prot()
return PROTpublic;
}
+enum PROT Dsymbol::overprot()
+{
+ return prot();
+}
+
/*************************************
* Do syntax copy of an array of Dsymbol's.
*/
@@ -848,27 +863,49 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
// Look in symbols declared in this module
Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
//printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0);
- if (s)
- {
- //printf("\ts = '%s.%s'\n",toChars(),s->toChars());
- }
- else if (imports)
+ if (!s)
+ s = searchImports(loc, ident, flags, PROTprivate);
+ return s;
+}
+
+/* Search the imports for symbol ident.
+ * Parameter:
+ * loc, ident, flags - as Dsymbol::search
+ * visibility - restricts the visibility of symbols
+ * Returns:
+ * NULL if not found
+ */
+Dsymbol *ScopeDsymbol::searchImports(Loc loc, Identifier *ident, int flags, enum PROT visibility)
+{
+ Dsymbol *s = NULL;
+ if (imports)
{
OverloadSet *a = NULL;
+ Module *thisModule = NULL;
// Look in imported modules
for (size_t i = 0; i < imports->dim; i++)
{ Dsymbol *ss = (*imports)[i];
Dsymbol *s2;
- // If private import, don't search it
- if (flags & 1 && prots[i] == PROTprivate)
+ // If restricted import, don't search it
+ if (!(flags & 1) && prots[i] < visibility)
continue;
//printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport());
- /* Don't find private members if ss is a module
- */
- s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0);
+ Module *m;
+ if (!(flags & 1) && (m = ss->isModule()) != NULL)
+ {
+ if (!thisModule)
+ thisModule = getAccessModule();
+ enum PROT mvisibility = moduleVisibility(thisModule, m);
+ if (mvisibility < visibility) // restrict visibility
+ mvisibility = visibility;
+ s2 = m->search(loc, ident, flags, mvisibility);
+ }
+ else
+ s2 = ss->search(loc, ident, flags);
+
if (!s)
s = s2;
else if (s2 && s != s2)
View
4 src/dsymbol.h
@@ -150,7 +150,7 @@ struct Dsymbol : Object
static Dsymbols *arraySyntaxCopy(Dsymbols *a);
- virtual const char *toPrettyChars();
+ virtual const char *toPrettyChars(bool verbose=false);
virtual const char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol
virtual int apply(Dsymbol_apply_ft_t fp, void *param);
@@ -192,6 +192,7 @@ struct Dsymbol : Object
virtual char *mangle();
virtual int needThis(); // need a 'this' pointer?
virtual enum PROT prot();
+ virtual enum PROT overprot();
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
virtual int oneMember(Dsymbol **ps, Identifier *ident);
static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL);
@@ -272,6 +273,7 @@ struct ScopeDsymbol : Dsymbol
ScopeDsymbol(Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
+ Dsymbol *searchImports(Loc loc, Identifier *ident, int flags, enum PROT visibility);
void importScope(Dsymbol *s, enum PROT protection);
int isforwardRef();
void defineRef(Dsymbol *s);
View
18 src/expression.c
@@ -2908,7 +2908,7 @@ Expression *IdentifierExp::semantic(Scope *sc)
{
s = sc->search_correct(ident);
if (s)
- error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
+ error("undefined identifier %s, did you mean '%s'?", ident->toChars(), s->toPrettyChars(true));
else
error("undefined identifier %s", ident->toChars());
}
@@ -6899,12 +6899,15 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
{
ScopeExp *ie = (ScopeExp *)eright;
- /* Disable access to another module's private imports.
- * The check for 'is sds our current module' is because
- * the current module should have access to its own imports.
+ /* Restrict access to another module's symbols.
*/
- Dsymbol *s = ie->sds->search(loc, ident,
- (ie->sds->isModule() && ie->sds != sc->module) ? 1 : 0);
+ Dsymbol *s;
+ if (Module *m = ie->sds->isModule())
+ { enum PROT visibility = moduleVisibility(sc->module, m);
+ s = m->search(loc, ident, 0, visibility);
+ }
+ else
+ s = ie->sds->search(loc, ident, 0);
if (s)
{
/* Check for access before resolving aliases because public
@@ -7034,8 +7037,7 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
}
s = ie->sds->search_correct(ident);
if (s)
- error("undefined identifier '%s', did you mean '%s %s'?",
- ident->toChars(), s->kind(), s->toChars());
+ error("undefined identifier '%s', did you mean '%s'?", ident->toChars(), s->toPrettyChars(true));
else
error("undefined identifier '%s'", ident->toChars());
return new ErrorExp();
View
21 src/func.c
@@ -646,7 +646,7 @@ void FuncDeclaration::semantic(Scope *sc)
}
if (s)
- error("does not override any function, did you mean to override '%s'?", s->toPrettyChars());
+ error("does not override any function, did you mean to override '%s'?", s->toPrettyChars(true));
else
error("does not override any function");
}
@@ -2896,12 +2896,12 @@ void FuncDeclaration::appendState(Statement *s)
}
}
-const char *FuncDeclaration::toPrettyChars()
+const char *FuncDeclaration::toPrettyChars(bool verbose)
{
if (isMain())
return "D main";
else
- return Dsymbol::toPrettyChars();
+ return Dsymbol::toPrettyChars(verbose);
}
int FuncDeclaration::isMain()
@@ -3210,6 +3210,21 @@ const char *FuncDeclaration::kind()
return "function";
}
+static int maxProt(void *arg, FuncDeclaration *f)
+{
+ enum PROT nprot = f->prot();
+ if (nprot > *(enum PROT*)arg) // take looser one
+ *(enum PROT*)arg = nprot;
+ return 0;
+}
+
+enum PROT FuncDeclaration::overprot()
+{
+ enum PROT result = prot();
+ overloadApply(this, &maxProt, &result);
+ return result;
+}
+
void FuncDeclaration::checkNestedReference(Scope *sc, Loc loc)
{
//printf("FuncDeclaration::checkNestedReference() %s\n", toChars());
View
5 src/import.c
@@ -233,17 +233,18 @@ void Import::semantic(Scope *sc)
#else
sc->protection = PROTpublic;
#endif
+ enum PROT visibility = moduleVisibility(getAccessModule(), mod);
for (size_t i = 0; i < aliasdecls.dim; i++)
{ Dsymbol *s = aliasdecls[i];
//printf("\tImport alias semantic('%s')\n", s->toChars());
- if (mod->search(loc, names[i], 0))
+ if (mod->search(loc, names[i], 0, visibility))
s->semantic(sc);
else
{
s = mod->search_correct(names[i]);
if (s)
- mod->error(loc, "import '%s' not found, did you mean '%s %s'?", names[i]->toChars(), s->kind(), s->toChars());
+ mod->error(loc, "import '%s' not found, did you mean '%s'?", names[i]->toChars(), s->toPrettyChars(true));
else
mod->error(loc, "import '%s' not found", names[i]->toChars());
}
View
4 src/init.c
@@ -202,8 +202,8 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needI
{
s = ad->search_correct(id);
if (s)
- error(loc, "'%s' is not a member of '%s', did you mean '%s %s'?",
- id->toChars(), t->toChars(), s->kind(), s->toChars());
+ error(loc, "'%s' is not a member of '%s', did you mean '%s'?",
+ id->toChars(), t->toChars(), s->toPrettyChars(true));
else
error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
errors = 1;
View
18 src/module.c
@@ -77,6 +77,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
searchCacheIdent = NULL;
searchCacheSymbol = NULL;
searchCacheFlags = 0;
+ searchCacheVisibility = PROTundefined;
semanticstarted = 0;
semanticRun = 0;
decldefs = NULL;
@@ -869,6 +870,11 @@ int Module::needModuleInfo()
Dsymbol *Module::search(Loc loc, Identifier *ident, int flags)
{
+ return search(loc, ident, flags, PROTprivate);
+}
+
+Dsymbol *Module::search(Loc loc, Identifier *ident, int flags, enum PROT visibility)
+{
/* Since modules can be circularly referenced,
* need to stop infinite recursive searches.
* This is done with the cache.
@@ -878,7 +884,8 @@ Dsymbol *Module::search(Loc loc, Identifier *ident, int flags)
Dsymbol *s;
if (insearch)
s = NULL;
- else if (searchCacheIdent == ident && searchCacheFlags == flags)
+ else if (searchCacheIdent == ident && searchCacheFlags == flags &&
+ searchCacheVisibility == visibility)
{
s = searchCacheSymbol;
//printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null");
@@ -886,12 +893,19 @@ Dsymbol *Module::search(Loc loc, Identifier *ident, int flags)
else
{
insearch = 1;
- s = ScopeDsymbol::search(loc, ident, flags);
+ s = symtab ? symtab->lookup(ident) : NULL;
+ // restrict visibility of top level symbols based on access
+ enum PROT prot;
+ if (s && !(flags & 1) && (prot = s->overprot()) != PROTundefined && prot < visibility)
+ s = NULL;
+ if (!s)
+ s = ScopeDsymbol::searchImports(loc, ident, flags, visibility);
insearch = 0;
searchCacheIdent = ident;
searchCacheSymbol = s;
searchCacheFlags = flags;
+ searchCacheVisibility = visibility;
}
return s;
}
View
4 src/module.h
@@ -79,6 +79,7 @@ struct Module : Package
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
+ enum PROT searchCacheVisibility;
int semanticstarted; // has semantic() been started?
int semanticRun; // has semantic() been done?
@@ -134,6 +135,7 @@ struct Module : Package
void gendocfile();
int needModuleInfo();
Dsymbol *search(Loc loc, Identifier *ident, int flags);
+ Dsymbol *search(Loc loc, Identifier *ident, int flags, enum PROT visibility);
Dsymbol *symtabInsert(Dsymbol *s);
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
@@ -175,6 +177,8 @@ struct Module : Package
Module *isModule() { return this; }
};
+// access.c
+enum PROT moduleVisibility(Module *from, Module *to);
struct ModuleDeclaration
{
View
11 src/mtype.c
@@ -2014,7 +2014,8 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
if (this != Type::terror)
{
if (s)
- error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
+ error(loc, "no property '%s' for type '%s', did you mean '%s'?",
+ ident->toChars(), toChars(), s->toPrettyChars(true));
else
error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
}
@@ -6641,8 +6642,8 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
{
sm = s->search_correct(id);
if (sm)
- error(loc, "identifier '%s' of '%s' is not defined, did you mean '%s %s'?",
- id->toChars(), toChars(), sm->kind(), sm->toChars());
+ error(loc, "identifier '%s' of '%s' is not defined, did you mean '%s'?",
+ id->toChars(), toChars(), sm->toPrettyChars(true));
else
error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
}
@@ -6742,9 +6743,9 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
Identifier *id = new Identifier(p, TOKidentifier);
s = sc->search_correct(id);
if (s)
- error(loc, "undefined identifier %s, did you mean %s %s?", p, s->kind(), s->toChars());
+ error(loc, "undefined identifier '%s', did you mean '%s'?", p, s->toPrettyChars(true));
else
- error(loc, "undefined identifier %s", p);
+ error(loc, "undefined identifier '%s'", p);
}
*pt = Type::terror;
}
View
11 src/scope.c
@@ -243,7 +243,7 @@ void Scope::mergeCallSuper(Loc loc, unsigned cs)
}
}
-Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
+Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags)
{ Dsymbol *s;
Scope *sc;
@@ -275,7 +275,7 @@ Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
if (sc->scopesym)
{
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
- s = sc->scopesym->search(loc, ident, 0);
+ s = sc->scopesym->search(loc, ident, flags);
if (s)
{
if (global.params.Dversion > 1 &&
@@ -411,7 +411,7 @@ void *scope_search_fp(void *arg, const char *seed)
Scope *sc = (Scope *)arg;
Module::clearCache();
- Dsymbol *s = sc->search(0, id, NULL);
+ Dsymbol *s = sc->search(0, id, NULL, 1|2);
return s;
}
@@ -420,5 +420,8 @@ Dsymbol *Scope::search_correct(Identifier *ident)
if (global.gag)
return NULL; // don't do it for speculative compiles; too time consuming
- return (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars);
+ Dsymbol *s = search(0, ident, NULL, 1|2); // repeat search including private symbols
+ if (!s)
+ s = (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars);
+ return s;
}
View
2  src/scope.h
@@ -122,7 +122,7 @@ struct Scope
void mergeCallSuper(Loc loc, unsigned cs);
- Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
+ Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags=0);
Dsymbol *search_correct(Identifier *ident);
Dsymbol *insert(Dsymbol *s);
View
2  src/template.c
@@ -5474,7 +5474,7 @@ TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc)
{
s = sc->search_correct(id);
if (s)
- error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars());
+ error("template '%s' is not defined, did you mean '%s'?", id->toChars(), s->toPrettyChars(true));
else
error("template '%s' is not defined", id->toChars());
return NULL;
View
3  test/compilable/imports/test1238a.d
@@ -0,0 +1,3 @@
+module imports.test1238a;
+
+private int zuiop;
View
3  test/compilable/imports/test1238b.d
@@ -0,0 +1,3 @@
+module imports.test1238b;
+
+public int zuiop;
View
5 test/compilable/imports/test1754a.d
@@ -0,0 +1,5 @@
+module imports.test1754a;
+
+private void bar()
+{
+}
View
5 test/compilable/imports/test1754b.d
@@ -0,0 +1,5 @@
+module imports.test1754b;
+
+void bar()
+{
+}
View
5 test/compilable/imports/test2991.d
@@ -0,0 +1,5 @@
+module imports.test2991;
+
+private void foo()
+{
+}
View
10 test/compilable/test1238.d
@@ -0,0 +1,10 @@
+module test1238;
+
+import imports.test1238a;
+import imports.test1238b;
+
+void foo()
+{
+ int qwert = zuiop;
+}
+
View
9 test/compilable/test1754.d
@@ -0,0 +1,9 @@
+module test1754;
+
+import imports.test1754a;
+import imports.test1754b;
+
+void foo()
+{
+ bar();
+}
View
12 test/compilable/test2991.d
@@ -0,0 +1,12 @@
+module test2991;
+
+void foo()
+{
+}
+
+class C
+{
+ import imports.test2991;
+
+ void bar() { foo(); }
+}
View
2  test/fail_compilation/diag9004.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag9004.d(4): Error: undefined identifier FooT.T
+fail_compilation/diag9004.d(4): Error: undefined identifier 'FooT.T'
fail_compilation/diag9004.d(8): Error: template diag9004.bar does not match any function template declaration. Candidates are:
fail_compilation/diag9004.d(4): diag9004.bar(FooT)(FooT foo, FooT.T x)
fail_compilation/diag9004.d(8): Error: template diag9004.bar(FooT)(FooT foo, FooT.T x) cannot deduce template function from argument types !()(Foo!(int),int)
View
8 test/fail_compilation/diag9191.d
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag9191.d(16): Error: function diag9191.C1.aaa does not override any function, did you mean to override 'diag9191.B1.aa'?
-fail_compilation/diag9191.d(21): Error: function diag9191.C2.aaa does not override any function, did you mean to override 'diag9191.I1.a'?
-fail_compilation/diag9191.d(31): Error: function diag9191.C3.foo does not override any function, did you mean to override 'diag9191.B2._foo'?
-fail_compilation/diag9191.d(36): Error: function diag9191.C4.toStringa does not override any function, did you mean to override 'object.Object.toString'?
+fail_compilation/diag9191.d(16): Error: function diag9191.C1.aaa does not override any function, did you mean to override 'public function diag9191.B1.aa'?
+fail_compilation/diag9191.d(21): Error: function diag9191.C2.aaa does not override any function, did you mean to override 'public function diag9191.I1.a'?
+fail_compilation/diag9191.d(31): Error: function diag9191.C3.foo does not override any function, did you mean to override 'public function diag9191.B2._foo'?
+fail_compilation/diag9191.d(36): Error: function diag9191.C4.toStringa does not override any function, did you mean to override 'public function object.Object.toString'?
---
*/
View
4 test/fail_compilation/fail61.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail61.d(22): Error: no property 'B' for type 'fail61.A.B', did you mean 'C'?
-fail_compilation/fail61.d(23): Error: no property 'B' for type 'fail61.A.B', did you mean 'C'?
+fail_compilation/fail61.d(22): Error: no property 'B' for type 'fail61.A.B', did you mean 'public variable fail61.A.B.C'?
+fail_compilation/fail61.d(23): Error: no property 'B' for type 'fail61.A.B', did you mean 'public variable fail61.A.B.C'?
fail_compilation/fail61.d(32): Error: no property 'A2' for type 'fail61.B2'
fail_compilation/fail61.d(41): Error: this for foo needs to be type B3 not type fail61.C3
---
View
3  test/fail_compilation/imports/test143.d
@@ -0,0 +1,3 @@
+module imports.test143;
+
+package int x = 5;
View
12 test/fail_compilation/test143.d
@@ -0,0 +1,12 @@
+module test143; // Bugzilla 143
+
+import imports.test143;
+
+void bar(int)
+{
+}
+
+void foo()
+{
+ bar(x);
+}
Something went wrong with that request. Please try again.