-
Notifications
You must be signed in to change notification settings - Fork 423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve dyno scope resolve errors with lookup tracing #21637
Conversation
46ec3f9
to
6704e2e
Compare
c5cccc1
to
2159e25
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, but I still haven't looked at scope-queries.cpp. Might be a little bit until I get to that, so publishing my comments so far.
} else { | ||
msg += "it"; | ||
} | ||
wr.note(ast, msg, " was provided by the automatically-included modules"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notes and heading should have punctuation in their strings; it will be stripped in brief mode, and kept in detailed mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following what specifically you wanted me to change. Is it to add a period?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think so.
wr.note(locationOnly(elt.visibilityClauseId), errbegin, " the '", elt.visibilityStmtKind, "' statement", nameSuffix, " here:"); | ||
wr.code<ID,ID>(elt.visibilityClauseId, { elt.visibilityClauseId }); | ||
from = elt.renameFrom; | ||
first = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could first
be called something else, like switchModules
, or something to indicate when it will / won't be true, and what that means? It would help better explain the code on like 876.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intended to literally reflect whether or not we are writing the first line of output, because if it is the first line we want to include intro
. I'll add a comment to its declaration, though.
@@ -844,9 +951,82 @@ void ErrorAmbiguousIdentifier::write(ErrorWriterBase& wr) const { | |||
printedOne = true; | |||
wr.code<ID, ID>(id, { id }); | |||
} | |||
|
|||
// TODO: call describeSymbolSource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave this as a TODO for this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I intended to leave it as future work.
@@ -1233,6 +1233,41 @@ Resolver::issueErrorForFailedCallResolution(const uast::AstNode* astForErr, | |||
} | |||
} | |||
|
|||
void Resolver::issueErrorForFailedModuleDot(const Dot* dot, ID moduleId) { | |||
// figure out what name was used for the module in the Dot expression | |||
auto modName = moduleId.symbolName(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of reading the ID directly, could we use it to lookup the AST node or the module, and read the name from there? It seems more proper, at least to me because my mental model of IDs is that they are opaque unless absolutely necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will have more incremental reuse if we don't lookup the uAST from the ID. However in this case I don't think that the optimization is particularly key. Nonetheless I'd prefer to keep it the way it is.
frontend/lib/resolution/Resolver.cpp
Outdated
auto pair = namesWithErrorsEmitted.insert(ident->name()); | ||
if (pair.second) { | ||
// insertion took place so emit the error | ||
bool printFirstMention = identHasMoreMentions(ident); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something makes me uneasy about a purely syntactic check like identHasMoreMentions
. It says "more mentions this function", but what if I introduce a variable locally that shadows ident
, and then reference it? that shouldn't count as another mention, right?
I'd also rename printFirstMention
(imperative, "implementation detail" of the error) to mentionedMoreThanOnce
(or just hasMoreMentions
), which is a more "declarative" name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One way to solve this "problem" might be to keep a map of identifier -> [unknown occurrence]
in the Resolver , insert into it here, but defer reporting until the traversal is complete. The map can serve as a substitute for namesWithErrorsEmitted
, because you'd just iterate the map's keys once. It would also help you forego the additional traversal.
The only trouble would be: "how do I know when to issue the errors?" Maybe the answer is: whenever a function is left?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've renamed printFirstMention
and added a TODO comment
and shift warnHiddenFormalsQuery to use it --- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
For now, all names match the extern block. That is a TODO. This code currently uses workarounds to forget about the extern block resolution so that '--dyno' works with extern blocks. --- Signed-off-by: Michael Ferguson <[email protected]>
This is a belated follow-up to PR chapel-lang#19306. It is a bug that the production compiler allows this pattern today. --- Signed-off-by: Michael Ferguson <[email protected]>
Migrates the wording unchanged from PR chapel-lang#18731. For test/statements/errors/importIllegalExpr.chpl --- Signed-off-by: Michael Ferguson <[email protected]>
otherwise it relies on a bug to compile --- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
--- Signed-off-by: Michael Ferguson <[email protected]>
164f9f0
to
adbedf5
Compare
static bool | ||
doLookupInImportsAndUses(Context* context, | ||
const Scope* scope, | ||
const ResolvedVisibilityScope* resolving, | ||
const ResolvedVisibilityScope* cur, | ||
UniqueString name, | ||
bool onlyInnermost, | ||
bool skipPrivateVisibilities, | ||
VisibilitySymbols::ShadowScope shadowScope, | ||
NamedScopeSet& checkedScopes, | ||
std::vector<BorrowedIdsWithName>& result, | ||
bool& foundExternBlock, | ||
std::vector<VisibilityTraceElt>* traceCurPath, | ||
std::vector<ResultVisibilityTrace>* traceResult) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How many of these arguments do not change between recursive invocations? The list of args is making me think that we should have a wrapper struct that contains all the unchanging args, to avoid feeding them through every single function.
Some of the things that I think don't change and could be put in the struct:
- Context
resolving
onlyInnermost
checkedScopes
result
foundExternBlock
traceCurPath
traceResult
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree however I want to leave it as future work & the PR message already says this
Future Work:
...
change doLookupIn... functions to work with a struct instead of too many arguments.
doLookupInAutoModules(Context* context, | ||
const Scope* scope, | ||
const ResolvedVisibilityScope* resolving, | ||
UniqueString name, | ||
bool onlyInnermost, | ||
bool skipPrivateVisibilities, | ||
NamedScopeSet& checkedScopes, | ||
std::vector<BorrowedIdsWithName>& result, | ||
bool& foundExternBlock, | ||
std::vector<VisibilityTraceElt>* traceCurPath, | ||
std::vector<ResultVisibilityTrace>* traceResult) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This too would be a method on the struct I suggested in my previous comment (and so on)
// for error messages. The expectation is that the common case is that | ||
// they are both nullptr. | ||
// | ||
// if traceCurPath is not nullptr, it will be updated to reflect the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I misunderstand, you only ever push to traceCurPath
if both traceCurPath
and traceResult
are non-null.
|
||
// If we found any extern blocks, and there were no other symbols, | ||
// and extern block lookup was requested, use extern block lookup. | ||
if (checkExternBlocks && startSize == result.size() && foundExternBlock) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't doLookupInScope
return a found
bool? Why not store it here / on line 1214 and then avoid the startSize == result.size()
comparison/ even saving startSize?
--- Signed-off-by: Michael Ferguson <[email protected]>
This PR takes the following cleanup steps: * moves frontend/lib/framework/(parser-error-classes-list.cpp,resolution-error-classes-list.cpp} to the frontend/lib/parsing and frontend/lib/resolution directories, and similarly moves the headers * moves UnsupportedAsIdent to parser errors list since it is emitted by post-parse-checks * fix extra space in some error messages and avoids an unhelpful "In module" output for one error message (follow-up to PR #21637) * updates a number of loops like `for (auto elt : something())` to use `for (const auto& elt : something())` in cases where the element type is bigger than a pointer. The version without the `&` will cause a copy of the element on each iteration. Reviewed by @DanilaFe - thanks! - [x] full local testing - [x] no new `--dyno` failures
This is a follow-up to PR #21637. The dyno scope resolver's `doLookupIn...` functions have too many arguments and most of them do not change as these functions call each other. So, make them fields in a struct to make it easier to follow what is changing. Reviewed by @arezaii - thanks! - [x] full local testing - [x] no new failures with `--dyno`
PR chapel-lang#21637 added this error but it's currently off by default for --dyno so this test isn't testing a dyno error. --- Signed-off-by: Michael Ferguson <[email protected]>
PR chapel-lang#21637 added this error but it's currently off by default for --dyno so this test isn't testing a dyno error. --- Signed-off-by: Michael Ferguson <[email protected]>
PR chapel-lang#21637 added this error but it's currently off by default for --dyno so this test isn't testing a dyno error. --- Signed-off-by: Michael Ferguson <[email protected]>
This PR is intended to fix a failure with
--dyno
for the testPreviously, the dyno resolver was not causing an error, and then the production compiler's error handling did not print out the hint is used to, because the identifier
Bar
had been resolved toFoo
by the dyno scope resolver.This PR takes the following steps:
IllegalUseImport
error and emit it in post-parse checks. The wording of this error message is migrated completely from the production compiler where it was added in PR Change internal error to user error for bad import expression #18731.AmbiguousIdentifier
error toAmbiguousVisibilityIdentifier
and adds new errorsUnknownIdentifier
andAmbiguousIdentifier
. Note that these two new errors are currently disabled for--dyno
(but they are emitted when using the full dyno type and call resolver, e.g. in the dyno tests).NotInModule
error for the case such asrenameModRenameSymBadAccess2.chpl
described above.lookupNameInScopeTracing
which can record where matches came from for use in emitting errorsclass Scope
to track if it contained an extern block (extern { }
) so that further steps can be taken when looking for symbols in such a block.LOOKUP_EXTERN_BLOCKS
to enable search in extern blocksTests that now have different error message output (and will need .good file updates for
--dyno
):CountIdentifiersWithName
to support errors with parts like "first use this function" (the idea is that it's misleading to print that if the name is only used once in the function)M.N.symbol
whereM
contains apublic use N
. After PR simplify use/import shadowing #19306,public use
should not bring in the module name. I've created issue bug: public use should not bring in module name for function call #21640 about how these cases are compiling in production when they should not.NotInModule Example
IllegalUseImport Example
(The wording of this error message is migrated completely from the production compiler where it was added in PR #18731.)
UnknownIdentifier Example
(note, this error is currently disabled for
--dyno
as a workaround to problems unrelated to this PR)module M { x; }
AmbiguousIdentifier Example
(note, this error is currently disabled for
--dyno
as a workaround to problems unrelated to this PR)Tests Needing .good Update for
--dyno
After this PR, these tests will need .good file updates for
--dyno
:Future Work:
domain
to scope resolve in dyno and enable the dyno identifier-not-found error for--dyno
doLookupIn...
functions to work with a struct instead of too many arguments.Reviewed by @DanilaFe - thanks!
--dyno
testing