-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Change name poisoning implementation to allow better diagnostics #4764
Conversation
…soned` bit instead of `InstId::PoisonedName` value. This would allow to more easily change the API to support accessing the poisoning delcaration so we can have better name poisoning diagnosis. carbon-language#4622
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.
Generally LG, just some small comments that I think should be easy to fix and then merge.
toolchain/check/context.h
Outdated
struct LookupNameInExactScopeResult { | ||
SemIR::InstId inst_id; | ||
SemIR::AccessKind access_kind; | ||
bool is_poisoned = 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.
Style thing, structs would belong at the top (https://google.github.io/styleguide/cppguide.html#Declaration_Order).
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.
Done.
toolchain/check/context.h
Outdated
// Performs a name lookup in a specified scope, returning the referenced | ||
// instruction. Does not look into extended scopes. Returns an invalid | ||
// instruction if the name is not found. | ||
// instruction if the name is not found or poisoned. |
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 kind of sentence structure is difficult: does "not" apply to "found" only, or "found or poisoned"? Suggesting swapping order for clarity:
// instruction if the name is not found or poisoned. | |
// instruction if the name is poisoned or not found. |
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.
Done.
toolchain/check/context.h
Outdated
struct LookupNameInExactScopeResult { | ||
SemIR::InstId inst_id; | ||
SemIR::AccessKind access_kind; | ||
bool is_poisoned = 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.
Maybe add comments to the members? Note this is sort of an alternative to the documentation on LookupNameInExactScope (which I note doesn't explain access_kind
, but that's a pre-existing issue).
struct LookupNameInExactScopeResult { | |
SemIR::InstId inst_id; | |
SemIR::AccessKind access_kind; | |
bool is_poisoned = false; | |
struct LookupNameInExactScopeResult { | |
// The matching entity if found, or invalid if poisoned or not found. | |
SemIR::InstId inst_id; | |
// The access level required to use inst_id, if it's valid. | |
SemIR::AccessKind access_kind; | |
// Whether a poisoned entry was found. | |
bool is_poisoned = false; |
Or if you'd rather keep documentation on the function, maybe just add a note of where to look:
struct LookupNameInExactScopeResult { | |
SemIR::InstId inst_id; | |
SemIR::AccessKind access_kind; | |
bool is_poisoned = false; | |
// See LookupNameInExactScope for return information. | |
struct LookupNameInExactScopeResult { | |
SemIR::InstId inst_id; | |
SemIR::AccessKind access_kind; | |
bool is_poisoned = 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.
Added comments to the members, thanks!
toolchain/check/context.h
Outdated
// declaration, returning the referenced instruction. If scope_id is invalid, | ||
// uses the current contextual scope. | ||
// declaration. If found, returns the referenced instruction and false. If | ||
// poisoned, returns invalid instructions and true. poisoned. If scope_id is |
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.
Just a couple typos:
// poisoned, returns invalid instructions and true. poisoned. If scope_id is | |
// poisoned, returns an invalid instruction and true. If scope_id is |
Might also want to rewrap the comment after the fix.
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.
Done.
toolchain/check/context.h
Outdated
// poisoned, returns invalid instructions and true. poisoned. If scope_id is | ||
// invalid, uses the current contextual scope. |
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.
Maybe move the scope_id comment prior to the "If found", since it refers to the "specified scope" in the first sentence?
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.
Done.
toolchain/check/decl_name_stack.h
Outdated
// Adds a name to name lookup, or returns the existing instruction if this | ||
// Adds a name to name lookup if not already declared or poisoned in this | ||
// scope. If declared, returns the existing instruction and false. If | ||
// poisoned, returns invalid instruction and true. |
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.
"returns invalid instruction" feels like it's missing "an", how about one of:
// poisoned, returns invalid instruction and true. | |
// poisoned, returns an invalid instruction and true. |
// poisoned, returns invalid instruction and true. | |
// poisoned, returns invalid and true. |
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.
Added "an".
FWIW, I thought of "invalid instruction" as a term, but perhaps I should have used "InstId::Invalid" instead.
toolchain/check/decl_name_stack.h
Outdated
// Adds a name to name lookup if not already declared or poisoned in this | ||
// scope. If declared, returns the existing instruction and false. If | ||
// poisoned, returns invalid instruction and true. | ||
// TODO: Return the poisoning instruction if poisoned. | ||
// name has already been declared in this scope. |
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.
Looks like a typo:
// name has already been declared in this scope. |
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.
Done.
toolchain/check/decl_name_stack.h
Outdated
@@ -237,10 +237,14 @@ class DeclNameStack { | |||
auto AddNameOrDiagnose(NameContext name_context, SemIR::InstId target_id, | |||
SemIR::AccessKind access_kind) -> void; | |||
|
|||
// Adds a name to name lookup, or returns the existing instruction if this | |||
// Adds a name to name lookup if not already declared or poisoned in this |
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 phrasing makes it hard to tell whether "not" applies to "poisoned". I think this doesn't overwrite poisoned entries, so how about using "neither ... nor" to emphasize:
// Adds a name to name lookup if not already declared or poisoned in this | |
// Adds a name to name lookup if neither already declared nor poisoned in this |
If I'm wrong, swapping ordering could help:
// Adds a name to name lookup if not already declared or poisoned in this | |
// Adds a name to name lookup if poisoned or not already declared in this |
Or, "either" can also help make it clear "not" wouldn't apply to "poisoned":
// Adds a name to name lookup if not already declared or poisoned in this | |
// Adds a name to name lookup if either not already declared or poisoned in this |
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.
Done.
SemIR::InstId inst_id; | ||
// Whether the lookup found a poisoned name. | ||
bool is_poisoned = 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.
Is this default value used? I wonder if it might already be getting explicitly set, such that the default could be removed.
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 think it depends on how the struct is initialized, so this is safer.
If in some function definition you just do
LookupResult result;
Then I think nothing guarantees is_poisoned
would be false.
toolchain/check/context.h
Outdated
struct LookupNameInExactScopeResult { | ||
SemIR::InstId inst_id; | ||
SemIR::AccessKind access_kind; | ||
bool is_poisoned = 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.
Is this default necessary, or could it be removed?
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 think it depends on how the struct is initialized, so this is safer.
If in some function definition you just do
LookupNameInExactScopeResult result;
Then I think nothing guarantees is_poisoned
would be false.
Small thing on the Essentially, for now we're opting not to tag PRs and instead just rely on descriptions. That may change when we have more work going on, we'll wait and see. I'll update the code review docs tomorrow, but wanted to note here while the PR's pending. :) |
Change the implementation to use an explicit
is_poisoned
bit instead ofInstId::PoisonedName
value.Zero behavior change.
This would allow to more easily change the API to support accessing the poisoning declaration so we can have better name poisoning diagnosis.
#4622