From 6925ba376ee030738d5634574b3f3e353fd19d47 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 26 Jul 2026 00:32:19 +0100 Subject: Allow multiple bounds for Rust trait object type --- .../compiler/output/lang/rust/RustWriter.java | 9 +++++++- .../output/lang/rust/ast/RustTraitObjectType.java | 24 ++++++++++++++-------- .../compiler/output/lang/rust/RustWriterTests.java | 15 +++++++++++++- .../lang/rust/ast/RustTraitObjectTypeMatcher.java | 4 ++-- 4 files changed, 40 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java index fe12f9f..6d92c5c 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriter.java @@ -814,7 +814,14 @@ public class RustWriter implements AutoCloseable { private void writeTraitObjectType(RustTraitObjectType traitObjectType) throws IOException { this.writer.write("dyn "); - this.writeType(traitObjectType.bound()); + + writeWithSeparator( + traitObjectType.bounds(), + this::writeType, + () -> { + this.writer.write(" + "); + } + ); } private void writeTupleType(RustTupleType tupleType) throws IOException { diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectType.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectType.java index 406a8bd..ef4506c 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectType.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectType.java @@ -5,22 +5,30 @@ package org.zwobble.hobgoblin.compiler.output.lang.rust.ast; // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType imports // Custom area end: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType imports -public record RustTraitObjectType(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath bound) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType { +public record RustTraitObjectType(java.util.List bounds) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType { public static org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder arbitrary() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath.arbitrary().build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(java.util.List.of()); } - public record Builder(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath bound) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder { + public record Builder(java.util.List bounds) implements org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType.Builder { public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType build() { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType(bound); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType(bounds); } - public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder withBound(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath bound) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(bound); + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder withBounds(java.util.List bounds) { + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(bounds); } - public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder withBound(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath.Builder bound) { - return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(bound.build()); + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder addBound(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath bound) { + var bounds = new java.util.ArrayList(this.bounds); + bounds.add(bound); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(bounds); + } + + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder addBound(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath.Builder bound) { + var bounds = new java.util.ArrayList(this.bounds); + bounds.add(bound.build()); + return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder(bounds); } // Custom area start: org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.Builder body diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java index 8946855..1b3fdac 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustWriterTests.java @@ -1078,7 +1078,7 @@ public class RustWriterTests { @Test public void traitObjectTypeWithSingleTraitBound() throws IOException { var rust = RustTraitObjectType.arbitrary() - .withBound(RustPath.of("Any")) + .addBound(RustPath.of("Any")) .build(); var string = write(writer -> writer.writeType(rust)); @@ -1086,6 +1086,19 @@ public class RustWriterTests { assertThat(string, equalTo("dyn Any")); } + @Test + public void traitObjectTypeWithMultipleTraitBounds() throws IOException { + var rust = RustTraitObjectType.arbitrary() + .addBound(RustPath.of("Any")) + .addBound(RustPath.of("Sync")) + .addBound(RustPath.of("Send")) + .build(); + + var string = write(writer -> writer.writeType(rust)); + + assertThat(string, equalTo("dyn Any + Sync + Send")); + } + @Test public void tupleTypeSingleton() throws IOException { var rust = RustTupleType.arbitrary() diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectTypeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectTypeMatcher.java index 8d79f6d..021f7e0 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectTypeMatcher.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/output/lang/rust/ast/RustTraitObjectTypeMatcher.java @@ -28,9 +28,9 @@ public class RustTraitObjectTypeMatcher implements org.zwobble.precisely.Matcher return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType.class, this.submatchers); } - public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectTypeMatcher withBound(org.zwobble.precisely.Matcher bound) { + public org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectTypeMatcher withBounds(org.zwobble.precisely.Matcher> bounds) { var submatchers = new java.util.ArrayList>(this.submatchers); - submatchers.add(org.zwobble.precisely.Matchers.has("bound", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType::bound, bound)); + submatchers.add(org.zwobble.precisely.Matchers.has("bounds", org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType::bounds, bounds)); return new org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectTypeMatcher(submatchers); } -- cgit v1.2.3