Skip to content
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

Merged
merged 3 commits into from
Jan 8, 2025

Conversation

bricknerb
Copy link
Contributor

@bricknerb bricknerb commented Jan 7, 2025

Change the implementation to use an explicit is_poisoned bit instead of InstId::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

…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
@github-actions github-actions bot requested a review from josh11b January 7, 2025 13:10
@bricknerb bricknerb requested a review from jonmeow January 7, 2025 13:11
Copy link
Contributor

@jonmeow jonmeow left a 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.

Comment on lines 227 to 231
struct LookupNameInExactScopeResult {
SemIR::InstId inst_id;
SemIR::AccessKind access_kind;
bool is_poisoned = false;
};
Copy link
Contributor

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).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// 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.
Copy link
Contributor

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:

Suggested change
// instruction if the name is not found or poisoned.
// instruction if the name is poisoned or not found.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 227 to 230
struct LookupNameInExactScopeResult {
SemIR::InstId inst_id;
SemIR::AccessKind access_kind;
bool is_poisoned = false;
Copy link
Contributor

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).

Suggested change
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:

Suggested change
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;

Copy link
Contributor Author

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!

// 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple typos:

Suggested change
// 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 216 to 217
// poisoned, returns invalid instructions and true. poisoned. If scope_id is
// invalid, uses the current contextual scope.
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// 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.
Copy link
Contributor

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:

Suggested change
// poisoned, returns invalid instruction and true.
// poisoned, returns an invalid instruction and true.
Suggested change
// poisoned, returns invalid instruction and true.
// poisoned, returns invalid and true.

Copy link
Contributor Author

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.

// 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a typo:

Suggested change
// name has already been declared in this scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -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
Copy link
Contributor

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:

Suggested change
// 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:

Suggested change
// 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":

Suggested change
// 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

Copy link
Contributor Author

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;
Copy link
Contributor

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.

Copy link
Contributor Author

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.

struct LookupNameInExactScopeResult {
SemIR::InstId inst_id;
SemIR::AccessKind access_kind;
bool is_poisoned = false;
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@jonmeow jonmeow changed the title [NFC] Change name poisoning implementation to allow better diagnostics Change name poisoning implementation to allow better diagnostics Jan 8, 2025
@jonmeow
Copy link
Contributor

jonmeow commented Jan 8, 2025

Small thing on the [NFC] tag -- we were talking about that in today's toolchain meeting, and it's an LLVM practice we'd prefer not to adopt (mainly because of the relationship with post-commit reviews in LLVM). Here I dropped it from the PR title; if you'd like to note it on a PR, just add something like "This change is only refactoring." That's the core thing I think you're trying to capture by adding it, but I think the description is also fine as-is.

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. :)

@bricknerb bricknerb added this pull request to the merge queue Jan 8, 2025
Merged via the queue into carbon-language:trunk with commit 74395ce Jan 8, 2025
8 checks passed
@bricknerb bricknerb deleted the poison2 branch January 8, 2025 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants