Skip to content

Commit

Permalink
?. is now same as ?as for the variant
Browse files Browse the repository at this point in the history
  • Loading branch information
borisbat committed Dec 26, 2024
1 parent 4bb29cc commit 3af4101
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 20 deletions.
3 changes: 3 additions & 0 deletions examples/test/unit_tests/variant.das
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def test
assert(t2[0] is i_value && t2[0] as i_value==1u)
assert(t2[1] is f_value && t2[1] as f_value==2.0)

// with the latest changes ?. is now same as ?as
/*
var f : Foo
var fp : Foo?
unsafe
Expand All @@ -103,6 +105,7 @@ def test
f.t = addr(t)
assert ( fp?.t?.i_value ?? 15u == 0x3f800000 ) // unsafe ?.i_value
assert ( fp?.t ?as i_value ?? 15u == 15u )
*/

var x : IorA
unsafe
Expand Down
37 changes: 17 additions & 20 deletions src/ast/ast_infer_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5481,7 +5481,7 @@ namespace das {
}
expr->fieldIndex = index;
} else if ( valT->isGoodVariantType() ) {
if ( !safeExpression(expr) ) {
if ( !safeExpression(expr) ) {
error("variant.field requires unsafe", "", "",
expr->at, CompilationError::unsafe);
return Visitor::visit(expr);
Expand Down Expand Up @@ -5562,27 +5562,38 @@ namespace das {
if ( auto opE = inferGenericOperatorWithName("?.",expr->at,expr->value,expr->name) ) return opE;
}
auto valT = expr->value->type;
if ( !valT->isPointer() || !valT->firstType ) {
if ( !(valT->isPointer() && valT->firstType) && !valT->isVariant() ) {
if ( verbose && !expr->no_promotion ) {
MatchingFunctions mf;
collectMissingOperators("?.`"+expr->name,mf,false);
collectMissingOperators("?.",mf,true);
if ( !mf.empty() ) {
reportDualFunctionNotFound("?.`"+expr->name, "can only safe dereference a pointer to a tuple, a structure or a handle " + describeType(valT),
reportDualFunctionNotFound("?.`"+expr->name, "can only safe dereference a variant or a pointer to a tuple, a structure or a handle " + describeType(valT),
expr->at, mf, {expr->value->type}, {expr->value->type, make_smart<TypeDecl>(Type::tString)}, true, false, true,
CompilationError::cant_get_field, 0, "");
} else {
error("can only safe dereference a pointer to a tuple, a structure or a handle " + describeType(valT), "", "",
error("can only safe dereference a variant or a pointer to a tuple, a structure or a handle " + describeType(valT), "", "",
expr->at, CompilationError::cant_get_field);
}
} else {
error("can only safe dereference a pointer to a tuple, a structure or a handle " + describeType(valT), "", "",
error("can only safe dereference a variant or a pointer to a tuple, a structure or a handle " + describeType(valT), "", "",
expr->at, CompilationError::cant_get_field);
}
return Visitor::visit(expr);
}
expr->value = Expression::autoDereference(expr->value);
if ( valT->firstType->structType ) {
if ( valT->isGoodVariantType() || valT->firstType->isGoodVariantType() ) {
int index = valT->variantFieldIndex(expr->name);
auto argSize = valT->isGoodVariantType() ? valT->argTypes.size() : valT->firstType->argTypes.size();
if ( index==-1 || index>=argSize ) {
error("can't get variant field '" + expr->name + "'", "", "",
expr->at, CompilationError::cant_get_field);
return Visitor::visit(expr);
}
reportAstChanged();
auto safeAs = make_smart<ExprSafeAsVariant>(expr->at, expr->value, expr->name);
return safeAs;
} else if ( valT->firstType->structType ) {
expr->field = valT->firstType->structType->findField(expr->name);
if ( !expr->field ) {
error("can't safe get field '" + expr->name + "'", "", "",
Expand All @@ -5607,20 +5618,6 @@ namespace das {
}
expr->fieldIndex = index;
expr->type = make_smart<TypeDecl>(*valT->firstType->argTypes[expr->fieldIndex]);
} else if ( valT->firstType->isGoodVariantType() ) {
if ( !safeExpression(expr) ) {
error("variant?.field requires unsafe", "", "",
expr->at, CompilationError::unsafe);
return Visitor::visit(expr);
}
int index = valT->variantFieldIndex(expr->name);
if ( index==-1 || index>=int(valT->firstType->argTypes.size()) ) {
error("can't get variant field '" + expr->name + "'", "", "",
expr->at, CompilationError::cant_get_field);
return Visitor::visit(expr);
}
expr->fieldIndex = index;
expr->type = make_smart<TypeDecl>(*valT->firstType->argTypes[expr->fieldIndex]);
} else {
error("can only safe dereference a pointer to a tuple, a structure or a handle " + describeType(valT), "", "",
expr->at, CompilationError::cant_get_field);
Expand Down

0 comments on commit 3af4101

Please sign in to comment.