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

Make HugrMut a trait #132

Merged
merged 11 commits into from
Jun 9, 2023
Merged

Make HugrMut a trait #132

merged 11 commits into from
Jun 9, 2023

Conversation

acl-cqc
Copy link
Contributor

@acl-cqc acl-cqc commented Jun 7, 2023

This turned out significantly harder than I'd expected, I'd not realized how much parameterization over hugr/ref/hugrmut there was in the builder. But I think I got there....

  • Anything returning a (new) HugrMut has to return an actual Hugr, it's the only concrete implementation of HugrMut we have.
  • Container having both base() and hugr() methods now seems a bit strange. But one is mutable and one is not....so left as is for now (TODO's can be removed if we are happy)?
  • Other things are variously parameterized over HugrMut and HugrMutRef...this was quite hard to satisfy rustc and I'm not sure I've got all these as consistent as I could have. The acid test will be when we have mutable views onto subregions and want to use HugrMut methods on those, but that's not in this PR!
  • Using Hugr::default() for a new module-rooted hugr is perhaps slightly tricky, could expose something there. (This was what the old HugrMut was using.)
  • Also made HugrMut be only pub(crate), but that's a separate commit (1bb79d2)

@@ -641,11 +640,11 @@ fn wire_up<T: Dataflow + ?Sized>(
/// Return None if Const kind
/// Panics if port not valid for Op or port is not Const/Value
fn check_classical_value(
base: &HugrMut,
base: &impl AsRef<Hugr>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could probably also be &impl HugrMut, but AsRef<Hugr> seems more general (? or is it)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At present HugrMut has AsRef<Hugr> as a prereq, so that'd be strictly less general - some AsRef<Hugr> things don't have the HugrMut methods (but probably could have if we wanted). However, in the future I hope that HugrMut will not require being able to retrieve an actual Hugr (even a reference), rather, HugrMut will be able to return an immutable view onto what might be only part of a Hugr. So if we wanted to plan ahead for that, I should change this here to HugrMut, but that will be another PR(-series)...

@acl-cqc acl-cqc requested review from aborgna-q and ss2165 June 8, 2023 08:27
@acl-cqc
Copy link
Contributor Author

acl-cqc commented Jun 8, 2023

@aborgna-q @ss2165 please co-ordinate who reviews this! :)

Copy link
Collaborator

@aborgna-q aborgna-q left a comment

Choose a reason for hiding this comment

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

LGTM

I'd centralize the AsRef traits in the main hugr module.
Probably also dropping DerefHugr in HugrView in favour of AsRef<Hugr> so that everything is uniform.

src/hugr/hugrmut.rs Outdated Show resolved Hide resolved
Comment on lines 121 to 122
/// Build the HUGR, returning an error if the graph is not valid.
fn finish(self) -> Result<Hugr, ValidationError>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This shouldn't be in the trait.
We can already dereference; finishing the hugr should be done by whatever builder struct you are using (or if you already have a Hugr just call validate).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I meant to call this out, sorry - it looked a bit dubious. Removing it entirely has meant that many of the impl<T: HugrMut> Container for SomeBuilder<T> have become impl Container for SomeBuilder<Hugr> which is to say, you can only call .finish_hugr when building a whole Hugr. Given that we are not doing mutable subregions yet, this is good :)

src/builder.rs Outdated Show resolved Hide resolved
src/builder.rs Outdated
/// Trait allowing treating type as (im)mutable reference to [`Hugr`]
pub trait HugrMutRef: AsMut<Hugr> + AsRef<Hugr> {}
impl<H: HugrMut> HugrMutRef for H {}
impl HugrMutRef for &mut Hugr {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we implement AsMut and AsRef instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At present HugrMutRef is a trait that one implements on top of AsMut and AsRef. AFAICS, the only purpose is to make it easy to parameterize (i.e. over T: HugrMutRef rather than T: AsMut<Hugr> + AsRef<Hugr>).

So, removed via bulk replace. (I have not gone through and checked whether any of them can be just : AsMut<Hugr> or : AsRef<Hugr> rather than + of both.)

This is a bit messy textually even if I think makes sense. (Sadly you can't define type HugrMutRef = AsRef<Hugr> + AsMut<Hugr> - type must really be a type not merely a bound.)

However, have kept in separate commit b48e2f6 in case you think this is too messy...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aborgna-q can you have a quick look at that b48e2f6 in case you think better of it....

Copy link
Collaborator

Choose a reason for hiding this comment

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

That works!

src/builder/build_traits.rs Outdated Show resolved Hide resolved
@acl-cqc
Copy link
Contributor Author

acl-cqc commented Jun 9, 2023

Somewhere there was a suggestion of dropping DerefHugr (in view.rs) in favour of AsRef - this might be good, but I think is separate to this PR.

Copy link
Member

@ss2165 ss2165 left a comment

Choose a reason for hiding this comment

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

👍 builder code base much nicer with this

@@ -624,7 +624,7 @@ pub(crate) mod test {
Ok((split, merge))
}

fn build_then_else_merge_from_if<T: HugrMutRef>(
Copy link
Member

Choose a reason for hiding this comment

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

do these actually need both Mut and Ref or is the Mut requirement sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They need it because the impl block is also parameterized like that...as I say I think we could probably go through and replace quite a few AsRef + AsMuts with one or the other, but I've not done that thorough an analysis here; consistency is helpful in itself and we can reconsider later if we really want.

@acl-cqc acl-cqc merged commit 118c4af into main Jun 9, 2023
@acl-cqc acl-cqc deleted the refactor/trait_hugrmut branch June 9, 2023 13:15
@aborgna-q aborgna-q mentioned this pull request Jun 12, 2023
doug-q added a commit that referenced this pull request Oct 21, 2024
Closes #132 

BREAKING CHANGE: `PreludeCodegen::emit_panic` now takes a single
configurable value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants