diff --git a/Schema.Cpp.Test/ExemplarInterfaceTests.cs b/Schema.Cpp.Test/ExemplarInterfaceTests.cs index 6d966f6..fe3ec8f 100644 --- a/Schema.Cpp.Test/ExemplarInterfaceTests.cs +++ b/Schema.Cpp.Test/ExemplarInterfaceTests.cs @@ -43,6 +43,7 @@ public sealed class ExemplarInterfaceTests #include #include "EntityId.gen.hpp" + #include "ErrorCode.gen.hpp" #include "Position.gen.hpp" #include "RigidBody.gen.hpp" #include "Seconds.gen.hpp" @@ -124,6 +125,31 @@ public void TheErrorTypeComesFromTheSchema() Assert.Contains("holo::Result, ErrorCode>", code, StringComparison.Ordinal); } + /// + /// The header includes the error enum it names, so it compiles on its own. + /// + /// + /// The error type is the one named type a signature reaches without the schema's type + /// vocabulary naming it: every other name in a header arrives through Enum, + /// Object or Interface and takes its include along the way, while this one comes + /// off the schema root because a failure says the same thing everywhere. That asymmetry is how + /// it came to be emitted as a bare name with no include -- the header named + /// Result<T, ErrorCode> and declared nothing called ErrorCode, so it + /// compiled only where something else had already included the enum first. + /// + /// Asserted on the include rather than on a compile, because a compile in this suite pulls in + /// the whole generated set and would pass on the neighbour's include -- which is exactly the + /// accident being tested for. + /// + /// + [TestMethod] + public void TheHeaderIncludesTheErrorEnumItNames() + { + string code = Generate()["IPhysicsWorld.gen.hpp"]; + + Assert.Contains("#include \"ErrorCode.gen.hpp\"", code, StringComparison.Ordinal); + } + /// /// A target that has no fallible return is told which option to set, rather than handed a /// header that will not compile. diff --git a/Schema.Cpp/CppTypeMapper.cs b/Schema.Cpp/CppTypeMapper.cs index 7e1088a..b92ec15 100644 --- a/Schema.Cpp/CppTypeMapper.cs +++ b/Schema.Cpp/CppTypeMapper.cs @@ -217,7 +217,11 @@ private TypeReference MapResult(SchemaTypes.Result result) "A signature returns a Result, but the schema names no error type. Set the schema's error type to an enum it declares."); } - outcome.TypeArguments.Add(new TypeReference(schema.ErrorType.ToString())); + // Through `Generated` rather than as a bare name, so the header carries the enum's + // include. It is the one named type a signature can reach without the schema's type + // vocabulary naming it -- the error comes from the schema root rather than from the + // return type -- which is exactly how it came to be the one that was missed. + outcome.TypeArguments.Add(Generated(schema.ErrorType.ToString())); return outcome; }