diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/check.cpp | 287 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 96 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 72 | ||||
-rw-r--r-- | src/mir/helpers.cpp | 18 | ||||
-rw-r--r-- | src/mir/helpers.hpp | 43 | ||||
-rw-r--r-- | src/mir/operations.hpp | 12 | ||||
-rw-r--r-- | src/trans/codegen.cpp | 12 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 5 |
8 files changed, 186 insertions, 359 deletions
diff --git a/src/mir/check.cpp b/src/mir/check.cpp index aa76139f..24157f41 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -9,293 +9,12 @@ #include "mir.hpp" #include <hir/visitor.hpp> #include <hir_typeck/static.hpp> +#include <mir/helpers.hpp> -namespace { - const unsigned int STMT_TERM = ~0u; - - #define MIR_BUG(state, ...) ( (state).print_bug( [&](auto& _os){_os << __VA_ARGS__; } ) ) - #define MIR_ASSERT(state, cnd, ...) do { if( !(cnd) ) (state).print_bug( [&](auto& _os){_os << "ASSERT " #cnd " failed - " << __VA_ARGS__; } ); } while(0) - #define MIR_TODO(state, ...) ( (state).print_todo( [&](auto& _os){_os << __VA_ARGS__; } ) ) - - struct MirCheckFailure { - }; - - struct State { - typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > t_args; - - const StaticTraitResolve& resolve; - const ::HIR::ItemPath& path; - const ::MIR::Function& fcn; - const t_args& args; - const ::HIR::TypeRef& ret_type; - - unsigned int bb_idx = 0; - unsigned int stmt_idx = 0; - const ::HIR::SimplePath* m_lang_Box; - - Span sp; - - State(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const t_args& args, const ::HIR::TypeRef& ret_type): - resolve(resolve), - path(path), - fcn(fcn), - args(args), - ret_type(ret_type) - { - if( resolve.m_crate.m_lang_items.count("owned_box") > 0 ) { - m_lang_Box = &resolve.m_crate.m_lang_items.at("owned_box"); - } - } - - void set_cur_stmt(unsigned int bb_idx, unsigned int stmt_idx) { - this->bb_idx = bb_idx; - this->stmt_idx = stmt_idx; - } - void set_cur_stmt_term(unsigned int bb_idx) { - this->bb_idx = bb_idx; - this->stmt_idx = STMT_TERM; - } - - void print_bug(::std::function<void(::std::ostream& os)> cb) const { - print_msg("ERROR", cb); - } - void print_todo(::std::function<void(::std::ostream& os)> cb) const { - print_msg("TODO", cb); - } - void print_msg(const char* tag, ::std::function<void(::std::ostream& os)> cb) const - { - auto& os = ::std::cerr; - os << "MIR " << tag << ": " << this->path << " BB" << this->bb_idx << "/"; - if( this->stmt_idx == STMT_TERM ) { - os << "TERM"; - } - else { - os << this->stmt_idx; - } - os << ": "; - cb(os); - os << ::std::endl; - // TODO: Throw something? Or mark an error so the rest of the function can be checked. - throw MirCheckFailure {}; - } - - const ::HIR::TypeRef& get_lvalue_type(::HIR::TypeRef& tmp, const ::MIR::LValue& val) const - { - TU_MATCH(::MIR::LValue, (val), (e), - (Variable, - return this->fcn.named_variables.at(e); - ), - (Temporary, - return this->fcn.temporaries.at(e.idx); - ), - (Argument, - return this->args.at(e.idx).second; - ), - (Static, - TU_MATCHA( (e.m_data), (pe), - (Generic, - MIR_ASSERT(*this, pe.m_params.m_types.empty(), "Path params on static"); - const auto& s = resolve.m_crate.get_static_by_path(sp, pe.m_path); - return s.m_type; - ), - (UfcsKnown, - MIR_TODO(*this, "LValue::Static - UfcsKnown - " << e); - ), - (UfcsUnknown, - MIR_BUG(*this, "Encountered UfcsUnknown in LValue::Static - " << e); - ), - (UfcsInherent, - MIR_TODO(*this, "LValue::Static - UfcsInherent - " << e); - ) - ) - ), - (Return, - return this->ret_type; - ), - (Field, - const auto& ty = this->get_lvalue_type(tmp, *e.val); - TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), - ( - MIR_BUG(*this, "Field access on unexpected type - " << ty); - ), - // Array and Slice use LValue::Field when the index is constant and known-good - (Array, - return *te.inner; - ), - (Slice, - return *te.inner; - ), - (Tuple, - MIR_ASSERT(*this, e.field_index < te.size(), "Field index out of range in tuple " << e.field_index << " >= " << te.size()); - return te[e.field_index]; - ), - (Path, - MIR_ASSERT(*this, te.binding.is_Struct(), "Field on non-Struct - " << ty); - const auto& str = *te.binding.as_Struct(); - TU_MATCHA( (str.m_data), (se), - (Unit, - MIR_BUG(*this, "Field on unit-like struct - " << ty); - ), - (Tuple, - MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in tuple-struct"); - const auto& fld = se[e.field_index]; - if( monomorphise_type_needed(fld.ent) ) { - tmp = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, fld.ent); - this->resolve.expand_associated_types(sp, tmp); - return tmp; - } - else { - return fld.ent; - } - ), - (Named, - MIR_ASSERT(*this, e.field_index < se.size(), "Field index out of range in struct"); - const auto& fld = se[e.field_index].second; - if( monomorphise_type_needed(fld.ent) ) { - tmp = monomorphise_type(sp, str.m_params, te.path.m_data.as_Generic().m_params, fld.ent); - this->resolve.expand_associated_types(sp, tmp); - return tmp; - } - else { - return fld.ent; - } - ) - ) - ) - ) - ), - (Deref, - const auto& ty = this->get_lvalue_type(tmp, *e.val); - TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), - ( - MIR_BUG(*this, "Deref on unexpected type - " << ty); - ), - (Path, - if( const auto* inner_ptr = this->is_type_owned_box(ty) ) - { - return *inner_ptr; - } - else { - MIR_BUG(*this, "Deref on unexpected type - " << ty); - } - ), - (Pointer, - return *te.inner; - ), - (Borrow, - return *te.inner; - ) - ) - ), - (Index, - const auto& ty = this->get_lvalue_type(tmp, *e.val); - TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), - ( - MIR_BUG(*this, "Index on unexpected type - " << ty); - ), - (Slice, - return *te.inner; - ), - (Array, - return *te.inner; - ) - ) - ), - (Downcast, - const auto& ty = this->get_lvalue_type(tmp, *e.val); - TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te), - ( - MIR_BUG(*this, "Downcast on unexpected type - " << ty); - ), - (Path, - MIR_ASSERT(*this, te.binding.is_Enum() || te.binding.is_Union(), "Downcast on non-Enum"); - if( te.binding.is_Enum() ) - { - const auto& enm = *te.binding.as_Enum(); - const auto& variants = enm.m_variants; - MIR_ASSERT(*this, e.variant_index < variants.size(), "Variant index out of range"); - const auto& variant = variants[e.variant_index]; - // TODO: Make data variants refer to associated types (unify enum and struct handling) - TU_MATCHA( (variant.second), (ve), - (Value, - ), - (Unit, - ), - (Tuple, - // HACK! Create tuple. - ::std::vector< ::HIR::TypeRef> tys; - for(const auto& fld : ve) - tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.ent) ); - tmp = ::HIR::TypeRef( mv$(tys) ); - this->resolve.expand_associated_types(sp, tmp); - return tmp; - ), - (Struct, - // HACK! Create tuple. - ::std::vector< ::HIR::TypeRef> tys; - for(const auto& fld : ve) - tys.push_back( monomorphise_type(sp, enm.m_params, te.path.m_data.as_Generic().m_params, fld.second.ent) ); - tmp = ::HIR::TypeRef( mv$(tys) ); - this->resolve.expand_associated_types(sp, tmp); - return tmp; - ) - ) - } - else - { - const auto& unm = *te.binding.as_Union(); - MIR_ASSERT(*this, e.variant_index < unm.m_variants.size(), "Variant index out of range"); - const auto& variant = unm.m_variants[e.variant_index]; - const auto& var_ty = variant.second.ent; - - if( monomorphise_type_needed(var_ty) ) { - tmp = monomorphise_type(sp, unm.m_params, te.path.m_data.as_Generic().m_params, variant.second.ent); - this->resolve.expand_associated_types(sp, tmp); - return tmp; - } - else { - return var_ty; - } - } - ) - ) - ) - ) - throw ""; - } - - const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const - { - if( m_lang_Box ) - { - if( ! ty.m_data.is_Path() ) { - return nullptr; - } - const auto& te = ty.m_data.as_Path(); - - if( ! te.path.m_data.is_Generic() ) { - return nullptr; - } - const auto& pe = te.path.m_data.as_Generic(); - - if( pe.m_path != *m_lang_Box ) { - return nullptr; - } - // TODO: Properly assert? - return &pe.m_params.m_types.at(0); - } - else - { - return nullptr; - } - } - }; -} - -void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const State::t_args& args, const ::HIR::TypeRef& ret_type) +void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type) { Span sp; - State state { resolve, path, fcn, args, ret_type }; + ::MIR::TypeResolve state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn }; // Validation rules: // [CFA] = Control Flow Analysis diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp new file mode 100644 index 00000000..9948a3b3 --- /dev/null +++ b/src/mir/cleanup.cpp @@ -0,0 +1,96 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * mir/cleanup.cpp + * - MIR Cleanup + * + * Removes artefacts left after monomorphisation + * - Converts <Trait as Trait>::method() into a vtable call + * - Replaces constants by their value + */ +#include "main_bindings.hpp" +#include "mir.hpp" +#include <hir/visitor.hpp> +#include <hir_typeck/static.hpp> +#include <mir/helpers.hpp> + +void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type) +{ + Span sp; + ::MIR::TypeResolve state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn }; + + for(auto& block : fcn.blocks) + { + for(auto& stmt : block.statements) + { + if( stmt.is_Assign() ) + { + auto& se = stmt.as_Assign(); + + TU_IFLET( ::MIR::RValue, se.src, Constant, e, + // TODO: Replace `Const` with actual values + ) + } + } + + TU_IFLET( ::MIR::Terminator, block.terminator, CallPath, e, + + // Detect calling `<Trait as Trait>::method()` and replace with vtable call + if( e.fcn_path.m_data.is_UfcsKnown() && e.fcn_path.m_data.as_UfcsKnown().type->m_data.is_TraitObject() ) + { + const auto& pe = e.fcn_path.m_data.as_UfcsKnown(); + const auto& te = pe.type->m_data.as_TraitObject(); + // TODO: What if the method is from a supertrait? + if( pe.trait == te.m_trait.m_path ) + { + assert( te.m_trait.m_trait_ptr ); + const auto& trait = *te.m_trait.m_trait_ptr; + + // 1. Get the vtable index for this function + if( trait.m_value_indexes.count(pe.item) == 0 ) + BUG(sp, "Calling method '" << pe.item << "' of " << pe.trait << " which isn't in the vtable"); + unsigned int vtable_idx = trait.m_value_indexes.at( pe.item ); + + // 2. Load from the vtable + auto vtable_ty_spath = pe.trait.m_path; + vtable_ty_spath.m_components.back() += "#vtable"; + const auto& vtable_ref = resolve.m_crate.get_struct_by_path(sp, vtable_ty_spath); + // Copy the param set from the trait in the trait object + ::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone(); + // - Include associated types on bound + for(const auto& ty_b : te.m_trait.m_type_bounds) { + auto idx = trait.m_type_indexes.at(ty_b.first); + if(vtable_params.m_types.size() <= idx) + vtable_params.m_types.resize(idx+1); + vtable_params.m_types[idx] = ty_b.second.clone(); + } + auto vtable_ty = ::HIR::TypeRef::new_pointer( + ::HIR::BorrowType::Shared, + ::HIR::TypeRef( ::HIR::GenericPath(vtable_ty_spath, mv$(vtable_params)), &vtable_ref ) + ); + + // Allocate a temporary for the vtable pointer itself + auto vtable_lv = ::MIR::LValue::make_Temporary({ static_cast<unsigned int>(fcn.temporaries.size()) }); + fcn.temporaries.push_back( mv$(vtable_ty) ); + // - Load the vtable and store it + auto vtable_rval = ::MIR::RValue::make_DstMeta({ + ::MIR::LValue::make_Deref({ box$(e.args.front().clone()) }) + }); + block.statements.push_back( ::MIR::Statement::make_Assign({ vtable_lv.clone(), mv$(vtable_rval) }) ); + + // Update the terminator with the new information. + auto vtable_fcn = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(vtable_lv) })), vtable_idx }); + auto new_term = ::MIR::Terminator::make_CallValue({ + e.ret_block, e.panic_block, + mv$(e.ret_val), mv$(vtable_fcn), + mv$(e.args) + }); + + block.terminator = mv$(new_term); + } + } + ) + } +} + diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 4792d793..cedbb5f5 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -15,6 +15,7 @@ #include <hir_typeck/common.hpp> // monomorphise_type #include "main_bindings.hpp" #include "from_hir.hpp" +#include "operations.hpp" namespace { @@ -1355,7 +1356,6 @@ namespace { void visit(::HIR::ExprNode_CallPath& node) override { - const Span& sp = node.span(); TRACE_FUNCTION_F("_CallPath " << node.m_path); ::std::vector< ::MIR::LValue> values; values.reserve( node.m_args.size() ); @@ -1371,68 +1371,11 @@ namespace { auto next_block = m_builder.new_bb_unlinked(); auto res = m_builder.new_temporary( node.m_res_type ); - // If the call was to a TraitObject function, get it from the vtable. - // TODO: Should this be a later pass? - bool was_virtual = false; - if( node.m_path.m_data.is_UfcsKnown() && node.m_path.m_data.as_UfcsKnown().type->m_data.is_TraitObject() ) - { - const auto& pe = node.m_path.m_data.as_UfcsKnown(); - const auto& te = pe.type->m_data.as_TraitObject(); - if( pe.trait == te.m_trait.m_path ) - { - assert( te.m_trait.m_trait_ptr ); - const auto& trait = *te.m_trait.m_trait_ptr; - - // 1. Get the vtable index for this function - if( trait.m_value_indexes.count(pe.item) == 0 ) - BUG(sp, "Calling method '" << pe.item << "' of " << pe.trait << " which isn't in the vtable"); - unsigned int vtable_idx = trait.m_value_indexes.at( pe.item ); - - // 2. Load from the vtable - auto vtable_rval = ::MIR::RValue::make_DstMeta({ - ::MIR::LValue::make_Deref({ box$(values.front().clone()) }) - }); - auto vtable_ty_spath = pe.trait.m_path; - vtable_ty_spath.m_components.back() += "#vtable"; - const auto& vtable_ref = m_builder.crate().get_struct_by_path(sp, vtable_ty_spath); - // Copy the param set from the trait in the trait object - ::HIR::PathParams vtable_params = te.m_trait.m_path.m_params.clone(); - // - Include associated types on bound - for(const auto& ty_b : te.m_trait.m_type_bounds) { - auto idx = trait.m_type_indexes.at(ty_b.first); - if(vtable_params.m_types.size() <= idx) - vtable_params.m_types.resize(idx+1); - vtable_params.m_types[idx] = ty_b.second.clone(); - } - auto vtable_ty = ::HIR::TypeRef( ::HIR::GenericPath(vtable_ty_spath, mv$(vtable_params)), &vtable_ref ); - - auto vtable = m_builder.lvalue_or_temp(sp, mv$(vtable_ty), mv$(vtable_rval)); - auto vtable_fcn = ::MIR::LValue::make_Field({ box$(vtable), vtable_idx }); - - ::MIR::LValue fcn_val; - m_builder.with_val_type(sp, vtable_fcn, [&](const auto& ty){ - fcn_val = m_builder.new_temporary(ty); - }); - - m_builder.push_stmt_assign( sp, fcn_val.clone(), ::MIR::RValue( mv$(vtable_fcn) ) ); - - was_virtual = true; - m_builder.end_block(::MIR::Terminator::make_CallValue({ - next_block, panic_block, - res.clone(), mv$(fcn_val), - mv$(values) - })); - } - } - - if( ! was_virtual ) - { - m_builder.end_block(::MIR::Terminator::make_CallPath({ - next_block, panic_block, - res.clone(), node.m_path.clone(), - mv$(values) - })); - } + m_builder.end_block(::MIR::Terminator::make_CallPath({ + next_block, panic_block, + res.clone(), node.m_path.clone(), + mv$(values) + })); m_builder.set_cur_block(panic_block); // TODO: Proper panic handling, including scope destruction @@ -1904,6 +1847,9 @@ namespace { root_node.visit( ev ); } + ::HIR::TypeRef ret; + MIR_Cleanup(resolve, ::HIR::ItemPath(), fcn, args, ret); + return ::MIR::FunctionPointer(new ::MIR::Function(mv$(fcn))); } diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp index 59aa3420..e0721549 100644 --- a/src/mir/helpers.cpp +++ b/src/mir/helpers.cpp @@ -11,9 +11,21 @@ #include <hir/type.hpp> #include <mir/mir.hpp> -#define MIR_ASSERT(...) do{}while(0) -#define MIR_BUG(...) do{}while(0) -#define MIR_TODO(_, v...) TODO(sp, v) +void ::MIR::TypeResolve::print_msg(const char* tag, ::std::function<void(::std::ostream& os)> cb) const +{ + auto& os = ::std::cerr; + os << "MIR " << tag << ": " << this->m_path << " BB" << this->bb_idx << "/"; + if( this->stmt_idx == STMT_TERM ) { + os << "TERM"; + } + else { + os << this->stmt_idx; + } + os << ": "; + cb(os); + os << ::std::endl; + throw CheckFailure {}; +} const ::HIR::TypeRef& ::MIR::TypeResolve::get_lvalue_type(::HIR::TypeRef& tmp, const ::MIR::LValue& val) const { diff --git a/src/mir/helpers.hpp b/src/mir/helpers.hpp index 884cafa7..a986a3ae 100644 --- a/src/mir/helpers.hpp +++ b/src/mir/helpers.hpp @@ -22,33 +22,66 @@ namespace MIR { class Function; class LValue; +struct CheckFailure: + public ::std::exception +{ +}; + +#define MIR_BUG(state, ...) ( (state).print_bug( [&](auto& _os){_os << __VA_ARGS__; } ) ) +#define MIR_ASSERT(state, cnd, ...) do { if( !(cnd) ) (state).print_bug( [&](auto& _os){_os << "ASSERT " #cnd " failed - " << __VA_ARGS__; } ); } while(0) +#define MIR_TODO(state, ...) ( (state).print_todo( [&](auto& _os){_os << __VA_ARGS__; } ) ) + class TypeResolve { public: typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > args_t; private: + const unsigned int STMT_TERM = ~0u; + const Span& sp; + const ::StaticTraitResolve& m_resolve; const ::HIR::Crate& m_crate; + ::FmtLambda m_path; const ::HIR::TypeRef& m_ret_type; const args_t& m_args; const ::MIR::Function& m_fcn; - ::StaticTraitResolve m_resolve; const ::HIR::SimplePath* m_lang_Box = nullptr; + + unsigned int bb_idx = 0; + unsigned int stmt_idx = 0; public: - TypeResolve(const Span& sp, const ::HIR::Crate& crate, const ::HIR::TypeRef& ret_type, const args_t& args, const ::MIR::Function& fcn): + TypeResolve(const Span& sp, const ::StaticTraitResolve& resolve, ::FmtLambda path, const ::HIR::TypeRef& ret_type, const args_t& args, const ::MIR::Function& fcn): sp(sp), - m_crate(crate), + m_resolve(resolve), + m_crate(resolve.m_crate), + m_path(path), m_ret_type(ret_type), m_args(args), - m_fcn(fcn), - m_resolve(crate) + m_fcn(fcn) { if( m_crate.m_lang_items.count("owned_box") > 0 ) { m_lang_Box = &m_crate.m_lang_items.at("owned_box"); } } + void set_cur_stmt(unsigned int bb_idx, unsigned int stmt_idx) { + this->bb_idx = bb_idx; + this->stmt_idx = stmt_idx; + } + void set_cur_stmt_term(unsigned int bb_idx) { + this->bb_idx = bb_idx; + this->stmt_idx = STMT_TERM; + } + + void print_bug(::std::function<void(::std::ostream& os)> cb) const { + print_msg("ERROR", cb); + } + void print_todo(::std::function<void(::std::ostream& os)> cb) const { + print_msg("TODO", cb); + } + void print_msg(const char* tag, ::std::function<void(::std::ostream& os)> cb) const; + const ::HIR::TypeRef& get_lvalue_type(::HIR::TypeRef& tmp, const ::MIR::LValue& val) const; private: diff --git a/src/mir/operations.hpp b/src/mir/operations.hpp new file mode 100644 index 00000000..a32531e9 --- /dev/null +++ b/src/mir/operations.hpp @@ -0,0 +1,12 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * mir/operations.hpp + * - Common header for operations performed on MIR functions + */ +#include <hir_typeck/static.hpp> +#include <hir/item_path.hpp> + +extern void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type); +extern void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type); diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 9256054f..bda64d02 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -9,6 +9,7 @@ #include "trans_list.hpp" #include <hir/hir.hpp> #include <mir/mir.hpp> +#include <mir/operations.hpp> #include "codegen.hpp" #include "monomorphise.hpp" @@ -236,9 +237,18 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, cons const auto& fcn = *ent.second->ptr; // TODO: If this is a provided trait method, it needs to be monomorphised too. bool is_method = ( fcn.m_args.size() > 0 && visit_ty_with(fcn.m_args[0].second, [&](const auto& x){return x == ::HIR::TypeRef("Self",0xFFFF);}) ); - if( ent.second->pp.has_types() || is_method ) { + if( ent.second->pp.has_types() || is_method ) + { + ::StaticTraitResolve resolve { crate }; + auto ret_type = ent.second->pp.monomorph(crate, fcn.m_return); + ::HIR::Function::args_t args; + for(const auto& a : fcn.m_args) + args.push_back(::std::make_pair( ::HIR::Pattern{}, ent.second->pp.monomorph(crate, a.second) )); auto mir = Trans_Monomorphise(crate, ent.second->pp, fcn.m_code.m_mir); + MIR_Validate(resolve, ::HIR::ItemPath(), *mir, args, ret_type); + MIR_Cleanup(resolve, ::HIR::ItemPath(), *mir, args, ret_type); // TODO: MIR Optimisation + MIR_Validate(resolve, ::HIR::ItemPath(), *mir, args, ret_type); codegen->emit_function_code(ent.first, fcn, ent.second->pp, mir); } else { diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index d7199b98..ee0719ef 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -273,7 +273,7 @@ namespace { arg_types.push_back(::std::make_pair( ::HIR::Pattern{}, params.monomorph(m_crate, ent.second) )); ::HIR::TypeRef ret_type = params.monomorph(m_crate, item.m_return); - ::MIR::TypeResolve mir_res { sp, m_crate, ret_type, arg_types, *code }; + ::MIR::TypeResolve mir_res { sp, m_resolve, FMT_CB(ss, ss << p;), ret_type, arg_types, *code }; m_mir_res = &mir_res; m_of << "// " << p << "\n"; @@ -294,7 +294,6 @@ namespace { m_of << "\t// " << code->temporaries[i]; m_of << "\n"; } - // TODO: Code. for(unsigned int i = 0; i < code->blocks.size(); i ++) { TRACE_FUNCTION_F(p << " bb" << i); @@ -305,6 +304,7 @@ namespace { { assert( stmt.is_Drop() || stmt.is_Assign() ); if( stmt.is_Drop() ) { + // TODO: Emit destructor calls } else { const auto& e = stmt.as_Assign(); @@ -338,7 +338,6 @@ namespace { m_of << " = "; m_of << (c ? "true" : "false"); ), - // TODO: These need to be arrays, not strings! (strings are NUL terminated) (Bytes, emit_lvalue(e.dst); m_of << ".PTR = "; |