Esempio n. 1
0
    def try_rehom(rhs: Expression, expected_type: AnnotatedTypeName):
        if rhs.annotated_type.is_public():
            raise ValueError(
                'Cannot change the homomorphism of a public value')

        if rhs.annotated_type.is_private_at_me(rhs.analysis):
            # The value is @me, so we can just insert a ReclassifyExpr to change
            # the homomorphism of this value, just like we do for public values.
            return TypeCheckVisitor.make_rehom(rhs, expected_type)

        if isinstance(rhs, ReclassifyExpr) and not isinstance(rhs, RehomExpr):
            # rhs is a valid ReclassifyExpr, i.e. the argument is public or @me-private
            # To create an expression with the correct homomorphism,
            # just change the ReclassifyExpr's output homomorphism
            rhs.homomorphism = expected_type.homomorphism
        elif isinstance(rhs, PrimitiveCastExpr):
            # Ignore primitive cast & recurse
            rhs.expr = TypeCheckVisitor.try_rehom(rhs.expr, expected_type)
        elif isinstance(rhs, FunctionCallExpr) and isinstance(rhs.func, BuiltinFunction) and rhs.func.is_ite() \
                and rhs.args[0].annotated_type.is_public():
            # Argument is public_cond ? true_val : false_val. Try to rehom both true_val and false_val
            rhs.args[1] = TypeCheckVisitor.try_rehom(rhs.args[1],
                                                     expected_type)
            rhs.args[2] = TypeCheckVisitor.try_rehom(rhs.args[2],
                                                     expected_type)
        else:
            raise TypeMismatchException(expected_type, rhs.annotated_type, rhs)

        # Rehom worked without throwing, change annotated_type and return
        rhs.annotated_type = rhs.annotated_type.with_homomorphism(
            expected_type.homomorphism)
        return rhs
Esempio n. 2
0
    def implicitly_converted_to(expr: Expression, t: TypeName) -> Expression:
        if isinstance(expr, ReclassifyExpr) and not expr.privacy.is_all_expr():
            # Cast the argument of the ReclassifyExpr instead
            expr.expr = TypeCheckVisitor.implicitly_converted_to(expr.expr, t)
            expr.annotated_type.type_name = expr.expr.annotated_type.type_name
            return expr

        assert expr.annotated_type.type_name.is_primitive_type()
        cast = PrimitiveCastExpr(t.clone(), expr, is_implicit=True).override(
            parent=expr.parent,
            statement=expr.statement,
            line=expr.line,
            column=expr.column)
        cast.elem_type.parent = cast
        expr.parent = cast
        cast.annotated_type = AnnotatedTypeName(
            t.clone(), expr.annotated_type.privacy_annotation.clone(),
            expr.annotated_type.homomorphism).override(parent=cast)
        return cast