def test_unify_ir0_certain_nontrivial_with_variadic_type_variable() -> None: result = _unify( (ir0.FunctionTypeExpr( type_literal('int'), arg_exprs=(type_literal('float'), type_literal('double'), local_type_literal('T'), type_literal('char'), type_literal('void'))), ), (ir0.FunctionTypeExpr( type_literal('int'), arg_exprs=(type_literal('float'), type_literal('double'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local( cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), type_literal('void'))), ), expr_variables={'T'}, pattern_variables={'Ts'}) assert result.kind == UnificationResultKind.CERTAIN assert result.value_by_pattern_variable == () assert result.value_by_expanded_pattern_variable == ( (ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), (local_type_literal('T'), type_literal('char'))), )
def test_unify_ir0_certain_nontrivial_with_variadic_type_variable_matches_empty_list_suffix( ): result = _unify([ ir0.FunctionTypeExpr(type_literal('int'), arg_exprs=[type_literal('float')]) ], [ ir0.FunctionTypeExpr(type_literal('int'), arg_exprs=[ type_literal('float'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local( cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)) ]) ], expr_variables=set(), pattern_variables={'Ts'}) assert result.kind == UnificationResultKind.CERTAIN assert result.value_by_pattern_variable == [] assert result.value_by_expanded_pattern_variable == [ (ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), []), ]
def test_unify_ir0_term_equality_variadic_type_expansion(expr1, expr2): result = _unify([expr1], [expr2], expr_variables={'Ts'}, pattern_variables={'Us'}) assert result.kind == UnificationResultKind.CERTAIN assert result.value_by_pattern_variable == [ (ir0.AtomicTypeLiteral.for_local('Us', expr_type=ir0.TypeType(), is_variadic=True), ir0.AtomicTypeLiteral.for_local('Ts', expr_type=ir0.TypeType(), is_variadic=True)), ] assert result.value_by_expanded_pattern_variable == []
def template(cpp_type: str, num_args: int): return ir0.AtomicTypeLiteral.for_nonlocal_template( cpp_type, args=[ir0.TemplateArgType(ir0.TypeType(), is_variadic=False)] * num_args, is_metafunction_that_may_return_error=False, may_be_alias=False)
def compute_merged_header_for_linking(main_module_name: str, object_file_content: ObjectFileContent, identifier_generator: Iterator[str], coverage_collection_enabled: bool): template_defns = [] check_if_error_specializations = [] toplevel_content = [] split_template_name_by_old_name_and_result_element_name: Dict[Tuple[ str, str], str] = dict() for module_info in object_file_content.modules_by_name.values(): template_defns += module_info.ir0_header.template_defns check_if_error_specializations += module_info.ir0_header.check_if_error_specializations toplevel_content += module_info.ir0_header.toplevel_content for key, value in module_info.ir0_header.split_template_name_by_old_name_and_result_element_name: split_template_name_by_old_name_and_result_element_name[ key] = value # template <typename> # struct CheckIfError { # using type = void; # }; check_if_error_template_main_definition = ir0.TemplateSpecialization( args=(ir0.TemplateArgDecl(expr_type=ir0.TypeType(), name='T', is_variadic=False), ), patterns=None, body=(ir0.Typedef(name='type', expr=ir0.AtomicTypeLiteral.for_nonlocal_type( 'void', may_be_alias=False)), ), is_metafunction=True) template_defns.append( ir0.TemplateDefn( main_definition=check_if_error_template_main_definition, specializations=tuple(check_if_error_specializations), name='CheckIfError', description='', result_element_names=frozenset(('type', )))) public_names = object_file_content.modules_by_name[ main_module_name].ir0_header.public_names.union(['CheckIfError']) merged_header = ir0.Header( template_defns=tuple(template_defns), check_if_error_specializations=(), toplevel_content=tuple(toplevel_content), split_template_name_by_old_name_and_result_element_name=tuple( (k, v) for k, v in split_template_name_by_old_name_and_result_element_name.items()), public_names=public_names) if coverage_collection_enabled: return merged_header return optimize_header(header=merged_header, context_object_file_content=ObjectFileContent({}), identifier_generator=identifier_generator, linking_final_header=True)
def template_member_access(class_expr: ir0.Expr, member_name: str, num_args: int): return ir0.ClassMemberAccess( class_type_expr=class_expr, member_name=member_name, member_type=ir0.TemplateType( args=[ir0.TemplateArgType(ir0.TypeType(), is_variadic=False)] * num_args))
def _add_to_type_set_helper(all_false_list_if_not_present: ir0.Expr, all_false_list: ir0.Expr, s: ir0.Expr, t: ir0.Expr): return _metafunction_call( template_expr=GlobalLiterals.ADD_TO_TYPE_SET_HELPER, args=[all_false_list_if_not_present, all_false_list, s, t], instantiation_might_trigger_static_asserts=False, member_name='type', member_type=ir0.TypeType())
def test_unify_ir0_certain_nontrivial_with_variadic_type_variable_does_not_match( ) -> None: result = _unify( (ir0.FunctionTypeExpr(type_literal('int'), arg_exprs=()), ), (ir0.FunctionTypeExpr(type_literal('int'), arg_exprs=( type_literal('float'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local( cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), )), ), expr_variables=set(), pattern_variables={'Ts'}) assert result.kind == UnificationResultKind.IMPOSSIBLE
def test_unify_ir0_variadic_type_variable_matches_multiple_variadics(): result = _unify([ ir0.FunctionTypeExpr( type_literal('int'), arg_exprs=[ type_literal('float'), type_literal('double'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), type_literal('char'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Us', expr_type=ir0.TypeType(), is_variadic=True)), type_literal('void') ]) ], [ ir0.FunctionTypeExpr(type_literal('int'), arg_exprs=[ type_literal('float'), type_literal('double'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local( cpp_type='Vs', expr_type=ir0.TypeType(), is_variadic=True)), type_literal('void') ]) ], expr_variables={'Ts', 'Us'}, pattern_variables={'Vs'}) assert result.kind == UnificationResultKind.CERTAIN assert result.value_by_pattern_variable == [] assert result.value_by_expanded_pattern_variable == [ (ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Vs', expr_type=ir0.TypeType(), is_variadic=True)), [ ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Ts', expr_type=ir0.TypeType(), is_variadic=True)), type_literal('char'), ir0.VariadicTypeExpansion( ir0.AtomicTypeLiteral.for_local(cpp_type='Us', expr_type=ir0.TypeType(), is_variadic=True)) ]), ]
lambda: ir0.Int64BinaryOpExpr(literal(1), literal(2), op='+'), lambda: ir0.BoolBinaryOpExpr(literal(True), literal(False), op='||'), lambda: ir0.NotExpr(literal(True)), lambda: ir0.UnaryMinusExpr(literal(1)), lambda: ir0.TemplateInstantiation( template_expr=ir0.AtomicTypeLiteral.for_nonlocal_template( cpp_type='std::vector', args=[], is_metafunction_that_may_return_error=False, may_be_alias=False), args=[], instantiation_might_trigger_static_asserts=False), lambda: ir0.TemplateInstantiation( template_expr=ir0.AtomicTypeLiteral.for_nonlocal_template( cpp_type='std::vector', args=[ir0.TemplateArgType(ir0.TypeType(), is_variadic=False)], is_metafunction_that_may_return_error=False, may_be_alias=False), args=[type_literal('int')], instantiation_might_trigger_static_asserts=False), lambda: ir0.ClassMemberAccess(class_type_expr=type_literal('MyClass'), member_name='value_type', member_type=ir0.TypeType()), ], ids=[ 'Literal', 'AtomicTypeLiteral', 'PointerTypeExpr', 'ReferenceTypeExpr', 'RvalueReferenceTypeExpr', 'ConstTypeExpr',
def type_member_access(class_expr: ir0.Expr, member_name: str): return ir0.ClassMemberAccess(class_type_expr=class_expr, member_name=member_name, member_type=ir0.TypeType())
def _variadic_type_arg_type(): return ir0.TemplateArgType(expr_type=ir0.TypeType(), is_variadic=True)
def _fold_types_to_type(acc: ir0.Expr, f: ir0.Expr, ts: ir0.Expr): return _metafunction_call(template_expr=GlobalLiterals.FOLD_TYPES_TO_TYPE, args=[acc, f, ts], instantiation_might_trigger_static_asserts=True, member_name='type', member_type=ir0.TypeType())
def _get_first_error(*args: ir0.Expr): return _metafunction_call(template_expr=GlobalLiterals.GET_FIRST_ERROR, args=args, instantiation_might_trigger_static_asserts=False, member_name='type', member_type=ir0.TypeType())
ir0.TemplateType([_type_arg_type(), _bool_arg_type()]), is_variadic=False), _local_bool('b'), ir0.VariadicTypeExpansion(_local_variadic_bool('bs')) ], type_expr=_fold_bools_to_type( _local_metafunction_call( 'F', arg_types=[_type_arg_type(), _bool_arg_type()], args=[_local_type('Acc'), _local_bool('b')], instantiation_might_trigger_static_asserts=True, member_name='type', member_type=ir0.TypeType()), ir0.AtomicTypeLiteral.for_local( 'F', ir0.TemplateType([_type_arg_type(), _bool_arg_type()]), is_variadic=False), ir0.VariadicTypeExpansion(_local_variadic_bool('bs')))) ]) # template <typename L> # struct BoolListToSet; # # template <bool... bs> # struct BoolListToSet<BoolList<bs...>> { # using type = typename FoldBoolsToType<BoolList<>, AddToBoolSet, bs...>::type; # };
def local_type_literal(cpp_type: str): return ir0.AtomicTypeLiteral.for_local(cpp_type, expr_type=ir0.TypeType(), is_variadic=False)
def _local_variadic_type(cpp_type: str): return ir0.AtomicTypeLiteral.for_local(cpp_type, ir0.TypeType(), is_variadic=True)
def _variadic_type_arg_decl(name: str): return ir0.TemplateArgDecl(expr_type=ir0.TypeType(), name=name, is_variadic=True)
def _type_arg_type() -> ir0.TemplateArgType: return ir0.TemplateArgType(expr_type=ir0.TypeType(), is_variadic=False)