-
Notifications
You must be signed in to change notification settings - Fork 593
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
Unit
Cycle Fixes & Cleanup SyntaxTreeBase
#3496
base: main
Are you sure you want to change the base?
Unit
Cycle Fixes & Cleanup SyntaxTreeBase
#3496
Conversation
Unit
Cycle Fixed & Cleanup SyntaxTreeBase
Unit
Cycle Fixed & Cleanup SyntaxTreeBase
Unit
Cycle Fixes & Cleanup SyntaxTreeBase
… 'Contained', and 'Type'.
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 would be helpeful to explain which cycles the various destroy() functions break.
@@ -356,7 +347,9 @@ namespace Slice | |||
KindValue | |||
}; | |||
|
|||
Builtin(const UnitPtr& unit, Kind kind); | |||
Builtin(UnitPtr unit, Kind kind); | |||
void destroy(); |
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 don't understand the logic of destroy(). Which cycle are you breaking?
Update: ok, it's because Unit holds onto a list of Builtins. The modern approach is for the Builtin to hold a weak_ptr<Unit>
. This way, no cycle and no need for Builtin::destroy.
_name(std::move(name)) | ||
: _container(container), | ||
_name(std::move(name)), | ||
_unit(container->unit()) |
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 am puzzled by this code: instead of keeping _unit, you could just return _container->unit(), and then you don't need any destroy, since destroy() doesn't clear _container.
The classes we use to represent Slice definitions in the parser rely heavily on inheritance. The base of all these types is
SyntaxTreeBase
. This PR's focus is on moving stuff out ofSyntaxTreeBase
and into more appropriate places,further up the inheritance tree.
Specifically:
SyntaxTreeBase
has a default implementation ofvisit
which is no-op. This is bad.It means that you can call
Builtin::visit
. But what does it even mean to visit a built in type?This
visit
function was moved up toContained
, which represents a Slice definition.These are the only sensible things to visit.
Also,
visit
is now pure virtual. Every type should (and does) implement it's own visit logic.SyntaxTreeBase
also holds aUnitPtr
field. This was removed.We had to jump through hoops to get this to work for
Unit
, since this means it holds ashared_ptr
to itself... Also, it made us unable to provide a default constructor forSyntaxTreeBase
.So. This field was removed and replaced with a pure virtual
unit()
function.Contained
holds aUnitPtr
field, and returns it in it's implementation.Whereas
Unit
implements this function withshared_from_this
.By slimming down
SyntaxTreeBase
in these ways, I was able to completely eliminate it's constructor, along with the constructors forType
andContainer
.A result of this is that #3358 is fixed.