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

Disallow creating instances of abstract classes #4381

Merged
merged 21 commits into from
Oct 12, 2024

Conversation

dwblaikie
Copy link
Contributor

@dwblaikie dwblaikie commented Oct 8, 2024

A good first-pass, at least. (abstract adapters are rejected with this change, though pending further language design discussion)

Taking notes here:
Newly added diagnostics (+ tested, - untested):
ClassAbstractHere (note, tested in several paths)
AbstractTypeInAdaptDecl+ (not sure if this is correct - is it valid to adapt an abstract type?)
AbstractTypeInConversion- (equivalent IncompleteTypeInConversion is also untested, so I'm not sure if/how to reach this)
AbstractTypeInFunctionParam+
AbstractTypeInFunctionReturnType- (Failures about "initialization of abstract type" seem to block the return type error? That doesn't seem as useful as actually erroring on the return type)
AbstractTypeInInit++
AbstractTypeInLetDecl+
AbstractTypeInValueConversion++
AbstractTypeInVarDecl++ (Field and Variable)
Copy link
Contributor

@zygoloid zygoloid left a comment

Choose a reason for hiding this comment

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

The intended model is that you cannot create objects of abstract class types, but you can have values of abstract class types -- the value representation in that case is a pointer to the instance, so it doesn't need the class to be non-abstract. So I think we would want to remove some of these checks; I'll point out which ones.

toolchain/check/context.h Outdated Show resolved Hide resolved
toolchain/check/handle_binding_pattern.cpp Outdated Show resolved Hide resolved
toolchain/check/handle_class.cpp Outdated Show resolved Hide resolved
toolchain/check/testdata/class/fail_abstract.carbon Outdated Show resolved Hide resolved
Comment on lines 966 to 971
CARBON_DIAGNOSTIC(AbstractTypeInValueConversion, Error,
"forming value of abstract type `{0}`",
SemIR::TypeId);
CARBON_DIAGNOSTIC(AbstractTypeInConversion, Error,
"invalid use of abstract type `{0}`",
SemIR::TypeId);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we don't want to diagnose in these two cases, only when initializing.

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 (this also included adding null DiagnosticBuilder - open to riffing on the API (currently just uses the default ctor to create a null DiagnosticBuilder, but could use a named ctor of some kind - and has explicit bool conversion which could be some more explicitly named function))

Copy link
Contributor

Choose a reason for hiding this comment

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

I think a named constructor would be nice. Maybe even a method on DiagnosticEmitter, say BuildSuppressed or something, so you don't need to repeat the template argument.

toolchain/check/handle_binding_pattern.cpp Outdated Show resolved Hide resolved
toolchain/check/handle_function.cpp Outdated Show resolved Hide resolved
Copy link
Contributor Author

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

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

Handled feedback, and did a more major pass on the test coverage, splitting things (I feel like maybe I /should/ be writing those tests differently to, for example, share the definition of the abstract class rather than redefining it in even split - though it's so short importing it doesn't seem much more legible either - totally open to suggestions there).

Did manage to get test coverage on the return type check (at a call site to, rather than a definition of the abstract-returning function).

toolchain/check/context.h Outdated Show resolved Hide resolved
Comment on lines 966 to 971
CARBON_DIAGNOSTIC(AbstractTypeInValueConversion, Error,
"forming value of abstract type `{0}`",
SemIR::TypeId);
CARBON_DIAGNOSTIC(AbstractTypeInConversion, Error,
"invalid use of abstract type `{0}`",
SemIR::TypeId);
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 (this also included adding null DiagnosticBuilder - open to riffing on the API (currently just uses the default ctor to create a null DiagnosticBuilder, but could use a named ctor of some kind - and has explicit bool conversion which could be some more explicitly named function))

toolchain/check/handle_binding_pattern.cpp Outdated Show resolved Hide resolved
toolchain/check/handle_function.cpp Outdated Show resolved Hide resolved
toolchain/check/testdata/class/fail_abstract.carbon Outdated Show resolved Hide resolved
Copy link
Contributor

@zygoloid zygoloid left a comment

Choose a reason for hiding this comment

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

Thanks, looks good.

@@ -55,6 +55,7 @@ class DiagnosticEmitter {
DiagnosticBuilder(DiagnosticBuilder&&) noexcept = default;
auto operator=(DiagnosticBuilder&&) noexcept
-> DiagnosticBuilder& = default;
DiagnosticBuilder() : emitter_(nullptr) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

A brief comment here would be handy.

toolchain/check/convert.cpp Outdated Show resolved Hide resolved
Comment on lines 966 to 971
CARBON_DIAGNOSTIC(AbstractTypeInValueConversion, Error,
"forming value of abstract type `{0}`",
SemIR::TypeId);
CARBON_DIAGNOSTIC(AbstractTypeInConversion, Error,
"invalid use of abstract type `{0}`",
SemIR::TypeId);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think a named constructor would be nice. Maybe even a method on DiagnosticEmitter, say BuildSuppressed or something, so you don't need to repeat the template argument.

@dwblaikie dwblaikie added this pull request to the merge queue Oct 12, 2024
Merged via the queue into carbon-language:trunk with commit d491387 Oct 12, 2024
8 checks passed
@dwblaikie dwblaikie deleted the disallow_abstract_instance branch October 12, 2024 16:04
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