Skip to content

Commit

Permalink
Fix issue with type inference for result constructor.
Browse files Browse the repository at this point in the history
`global x = result("foo");` would end up having type `string` instead
of `result<string>`.
  • Loading branch information
rsmmr committed Dec 4, 2024
1 parent 9f6fb23 commit 3d2f4ed
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 9 deletions.
3 changes: 3 additions & 0 deletions hilti/toolchain/include/ast/builder/node-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class NodeFactory {
auto ctorResult(Expression* expr, const Meta& meta = {}) {
return hilti::ctor::Result::create(context(), expr, meta);
}
auto ctorResult(QualifiedType* type, const Meta& meta = {}) {
return hilti::ctor::Result::create(context(), type, meta);
}
auto ctorSet(Expressions exprs, Meta meta = {}) {
return hilti::ctor::Set::create(context(), std::move(exprs), std::move(meta));
}
Expand Down
21 changes: 14 additions & 7 deletions hilti/toolchain/include/ast/ctors/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
#include <utility>

#include <hilti/ast/ctor.h>
#include <hilti/ast/ctors/error.h>
#include <hilti/ast/expression.h>
#include <hilti/ast/expressions/ctor.h>
#include <hilti/ast/type.h>
#include <hilti/ast/types/auto.h>
#include <hilti/ast/types/error.h>
#include <hilti/ast/types/result.h>

Expand Down Expand Up @@ -36,24 +39,28 @@ class Result : public Ctor {
return {};
}

QualifiedType* type() const final {
if ( auto e = child<QualifiedType>(0) )
return e;
else
return child<Expression>(1)->type();
}
QualifiedType* type() const final { return child<QualifiedType>(0); }

void setType(ASTContext* ctx, QualifiedType* t) { setChild(ctx, 0, t); }

static auto create(ASTContext* ctx, Expression* expr, const Meta& meta = {}) {
return ctx->make<Result>(ctx,
{
nullptr,
QualifiedType::createAuto(ctx, meta),
expr,
},
meta);
}

static auto create(ASTContext* ctx, QualifiedType* type, const Meta& meta = {}) {
return ctx->make<Result>(ctx,
{
type,
expression::Ctor::create(ctx, ctor::Error::create(ctx, "<not set>", meta), meta),
},
meta);
}

protected:
Result(ASTContext* ctx, Nodes children, Meta meta) : Ctor(ctx, NodeTags, std::move(children), std::move(meta)) {}

Expand Down
2 changes: 1 addition & 1 deletion hilti/toolchain/src/compiler/codegen/ctors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ struct Visitor : hilti::visitor::PreOrder {
void operator()(ctor::Result* n) final {
auto t = cg->compile(n->type(), codegen::TypeUsage::Storage);

if ( n->value()->type()->type()->isA<type::Null>() )
if ( n->type()->type()->isA<type::Void>() )
result = fmt("::hilti::rt::Nothing{}");
else if ( auto e = n->value() )
result = fmt("%s(%s)", t, cg->compile(e));
Expand Down
2 changes: 1 addition & 1 deletion hilti/toolchain/src/compiler/coercer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct VisitorCtor : visitor::PreOrder {
}

if ( auto t = dst->type()->tryAs<type::Result>(); t && t->dereferencedType()->type()->isA<type::Void>() ) {
result = builder->ctorResult(builder->expressionCtor(builder->ctorNull()));
result = builder->ctorResult(t->dereferencedType());
return;
}

Expand Down
1 change: 1 addition & 0 deletions tests/Baseline/spicy.statements.assert/output
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
uncaught exception hilti::rt::AssertionFailure: failed expression '1 == 0' (fail.spicy:3:1-3:14)
uncaught exception hilti::rt::AssertionFailure: my error (fail2.spicy:3:1-3:27)
uncaught exception hilti::rt::AssertionFailure: my error (fail3.spicy:3:1-3:32)
uncaught exception hilti::rt::AssertionFailure: foo (fail4.spicy:4:1-4:9)
9 changes: 9 additions & 0 deletions tests/spicy/statements/assert.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# @TEST-EXEC-FAIL: spicyc -j fail.spicy >>output 2>&1
# @TEST-EXEC-FAIL: spicyc -j fail2.spicy >>output 2>&1
# @TEST-EXEC-FAIL: spicyc -j fail3.spicy >>output 2>&1
# @TEST-EXEC-FAIL: spicyc -j fail4.spicy >>output 2>&1
# @TEST-EXEC: btest-diff output

module Foo;
Expand All @@ -28,3 +29,11 @@ module Foo;
assert 1 == 0 : error"my error";

@TEST-END-FILE

@TEST-START-FILE fail4.spicy

module Foo;
global x = 0 : "foo";
assert x;

@TEST-END-FILE

0 comments on commit 3d2f4ed

Please sign in to comment.