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

Error on impl functions prior to extends base #4648

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

dwblaikie
Copy link
Contributor

Since impl will need to be checked against the base class's virtual
functions, and on the basis of the information accumulation principle (I
think?).

This does produce an awkward sequence of diagnostics "can't have impl
without a base class" then "can't have base class after an impl". I
guess we'd prefer to only have the latter? Could defer the "impl without
base" until the end of the class to implement that correctly?

Oh, and currently this will only produce one of "base must come before
fields" or "base must come before impls" - I guess it'd be preferable to
produce both?

Since impl will need to be checked against the base class's virtual
functions, and on the basis of the information accumulation principle (I
think?).

This does produce an awkward sequence of diagnostics "can't have impl
without a base class" then "can't have base class after an impl". I
guess we'd prefer to only have the latter? Could defer the "impl without
base" until the end of the class to implement that correctly?

Oh, and currently this will only produce one of "base must come before
fields" or "base must come before impls" - I guess it'd be preferable to
produce both?
@@ -526,6 +526,21 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool {
return true;
}

// TODO: base must appear before virtual functions too
for (auto inst_id : context.inst_block_stack().PeekCurrentBlockContents()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I worry that re-traversing the current block could be excessively costly. Do you think it might be sufficient to rephrase ImplWithoutBase to say there hasn't been a base declaration yet, and not have a separate diagnostic when we actually reach the base declaration?

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 suppose - it's sort of awkward that that's different from the field-before-base error (though that's meaningfully different than the impl-before-base, since impl-before-base can be identified as invalid at the impl, without having to wait for the base)

But if we want to error on virtual/abstract-before-base (for consistency? for detecting whether the virtual functions shadows something in the base (& should be impl instead), etc?), we can't do it at the virtual function and would need to do this second pass, or some other mechanism?

This will only traverse the members that appear before the base decl, right? Which should be relatively few? (though not guaranteed - since we're currently saying you can have any number of non-virtual functions declared before the base decl)

Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose - it's sort of awkward that that's different from the field-before-base error (though that's meaningfully different than the impl-before-base, since impl-before-base can be identified as invalid at the impl, without having to wait for the base)

I see it as consistent: in both cases, we're diagnosing the error at the earliest point where it can be detected (and only there). The asymmetry between the two just reflects the asymmetry in the language rules: "impl must be preceded by base" is structurally different from "base must not be preceded by a field".

But if we want to error on virtual/abstract-before-base (for consistency? for detecting whether the virtual functions shadows something in the base (& should be impl instead), etc?), we can't do it at the virtual function and would need to do this second pass, or some other mechanism?

I'm not sure of the best way to implement that. Possibly there's somewhere ephemeral where we could track whether we've seen any virtual/abstract methods yet?

This will only traverse the members that appear before the base decl, right? Which should be relatively few? (though not guaranteed - since we're currently saying you can have any number of non-virtual functions declared before the base decl)

Yeah, I assume the prevailing style will be to put the base decl as close to the top of the class as possible, so the cost might not be that bad in practice. But even if performance isn't an issue, there's still the problem that IIUC this diagnostic can only catch issues that will also be caught (and caught earlier) by ImplWithoutBase. If that's the case, this diagnostic seems like unnecessary clutter.

Copy link
Contributor Author

@dwblaikie dwblaikie Dec 12, 2024

Choose a reason for hiding this comment

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

But if we want to error on virtual/abstract-before-base (for consistency? for detecting whether the virtual functions shadows something in the base (& should be impl instead), etc?), we can't do it at the virtual function and would need to do this second pass, or some other mechanism?

I'm not sure of the best way to implement that. Possibly there's somewhere ephemeral where we could track whether we've seen any virtual/abstract methods yet?

Yeah, this might be the best place to look further into - to answer some of the broader questions of vtable layout, etc, maybe we'll want some bigger change/more invasive representational features for dynamic classes. I've started a discussion ( #4671 ) to examine that.

Might hold off on this review (I can mark it closed, perhaps?) for now, then.

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