diff options
-rw-r--r-- | src/ast/ast.hpp | 3 | ||||
-rw-r--r-- | src/hir/dump.cpp | 33 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 15 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 11 | ||||
-rw-r--r-- | src/hir/visitor.hpp | 3 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 76 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 8 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 20 | ||||
-rw-r--r-- | src/hir_typeck/outer.cpp | 35 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 14 | ||||
-rw-r--r-- | src/include/target_version.hpp | 11 |
12 files changed, 196 insertions, 35 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 19f0c66b..f78d559f 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -8,8 +8,7 @@ #ifndef AST_HPP_INCLUDED #define AST_HPP_INCLUDED -#define TARGETVER_1_19 true -#define TARGETVER_1_29 true +#include <target_version.hpp> #include <string> #include <vector> diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp index 874a80a7..e607925e 100644 --- a/src/hir/dump.cpp +++ b/src/hir/dump.cpp @@ -89,13 +89,46 @@ namespace { void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override { m_os << indent() << "trait " << p.get_name() << item.m_params.fmt_args() << "\n"; + if( ! item.m_parent_traits.empty() ) + { + m_os << indent() << " " << ": "; + bool is_first = true; + for(auto& bound : item.m_parent_traits) + { + if( !is_first ) + m_os << indent() << " " << "+ "; + m_os << bound << "\n"; + is_first = false; + } + } if( ! item.m_params.m_bounds.empty() ) { m_os << indent() << " " << item.m_params.fmt_bounds() << "\n"; } m_os << indent() << "{\n"; inc_indent(); + + for(auto& i : item.m_types) + { + m_os << indent() << "type " << i.first; + if( ! i.second.m_trait_bounds.empty() ) + { + m_os << ": "; + bool is_first = true; + for(auto& bound : i.second.m_trait_bounds) + { + if( !is_first ) + m_os << " + "; + m_os << bound; + is_first = false; + } + } + //this->visit_type(i.second.m_default); + m_os << ";\n"; + } + ::HIR::Visitor::visit_trait(p, item); + dec_indent(); m_os << indent() << "}\n"; } diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 5dbf9c03..9c8f34f6 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1258,6 +1258,21 @@ namespace { receiver = ::HIR::Function::Receiver::Box; } } + // TODO: for other types, support arbitary structs/paths. + // - The path must include Self as a (the only?) type param. + if( receiver == ::HIR::Function::Receiver::Free ) + { + if( pe.m_params.m_types.size() == 0 ) { + ERROR(sp, E0000, "Unsupported receiver type - " << arg_self_ty); + } + if( pe.m_params.m_types.size() != 1 ) { + TODO(sp, "Receiver types with more than one param - " << arg_self_ty); + } + if( pe.m_params.m_types[0] != self_type ) { + ERROR(sp, E0000, "Unsupported receiver type - " << arg_self_ty); + } + receiver = ::HIR::Function::Receiver::Custom; + } ) ) else { diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 20b9ad58..daa27d10 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -8,6 +8,7 @@ * Contains the expanded and desugared AST */ #pragma once +#include <target_version.hpp> #include <cassert> #include <unordered_map> @@ -122,6 +123,7 @@ public: //PointerMut, //PointerConst, Box, + Custom, }; typedef ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef> > args_t; diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 2e03990a..87b790ae 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -168,10 +168,9 @@ void ::HIR::Visitor::visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) this->visit_trait_path(par); } for(auto& i : item.m_types) { + auto item_path = ::HIR::ItemPath(trait_ip, i.first.c_str()); DEBUG("type " << i.first); - for(auto& bound : i.second.m_trait_bounds) - this->visit_trait_path(bound); - this->visit_type(i.second.m_default); + this->visit_associatedtype(item_path, i.second); } for(auto& i : item.m_values) { auto item_path = ::HIR::ItemPath(trait_ip, i.first.c_str()); @@ -234,6 +233,12 @@ void ::HIR::Visitor::visit_union(::HIR::ItemPath p, ::HIR::Union& item) for(auto& var : item.m_variants) this->visit_type(var.second.ent); } +void ::HIR::Visitor::visit_associatedtype(ItemPath p, ::HIR::AssociatedType& item) +{ + for(auto& bound : item.m_trait_bounds) + this->visit_trait_path(bound); + this->visit_type(item.m_default); +} void ::HIR::Visitor::visit_function(::HIR::ItemPath p, ::HIR::Function& item) { this->visit_params(item.m_params); diff --git a/src/hir/visitor.hpp b/src/hir/visitor.hpp index dbf759a4..d432b29d 100644 --- a/src/hir/visitor.hpp +++ b/src/hir/visitor.hpp @@ -33,8 +33,9 @@ public: virtual void visit_type_alias(ItemPath p, ::HIR::TypeAlias& item); virtual void visit_trait(ItemPath p, ::HIR::Trait& item); virtual void visit_struct(ItemPath p, ::HIR::Struct& item); - virtual void visit_union(ItemPath p, ::HIR::Union& item); virtual void visit_enum(ItemPath p, ::HIR::Enum& item); + virtual void visit_union(ItemPath p, ::HIR::Union& item); + virtual void visit_associatedtype(ItemPath p, ::HIR::AssociatedType& item); // - Value Items virtual void visit_function(ItemPath p, ::HIR::Function& item); virtual void visit_static(ItemPath p, ::HIR::Static& item); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 5a41e954..a2847e04 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -48,7 +48,7 @@ namespace { } }; - ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={}); + ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args={}); ::HIR::Literal clone_literal(const ::HIR::Literal& v) { @@ -245,7 +245,26 @@ namespace { } } - ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant_intrinsic(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::std::string& name, const ::HIR::PathParams& params, ::std::vector< ::HIR::Literal> args) + { + TRACE_FUNCTION_F("\"" << name << "\"" << params << " " << args); + if( name == "size_of" ) { + ASSERT_BUG(sp, params.m_types.size() == 1, "size_of intrinsic takes one type param (consteval)"); + const auto& ty = params.m_types[0]; + + size_t size; + if( !Target_GetSizeOf(sp, StaticTraitResolve { crate }, ty, size) ) + { + TODO(sp, "Handle error from Target_GetSizeOf(" << ty << ") in evaluate_constant_intrinsic"); + } + return ::HIR::Literal::make_Integer(size); + } + else { + TODO(sp, "name=" << name << params << " args=" << args); + } + } + + ::HIR::Literal evaluate_constant_hir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprNode& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp_type, ::std::vector< ::HIR::Literal> args) { // TODO: Force this function/tree through the entire pipeline so we can MIR it? // - Requires a HUGE change to the way the compiler operates. @@ -260,6 +279,7 @@ namespace { ::HIR::TypeRef m_exp_type; ::HIR::TypeRef m_rv_type; ::HIR::Literal m_rv; + t_cb_generic m_monomorph_cb; Visitor(const ::HIR::Crate& crate, NewvalState newval_state, ::HIR::TypeRef exp_ty): m_crate(crate), @@ -613,7 +633,7 @@ namespace { } void visit(::HIR::ExprNode_CallPath& node) override { - + const auto& sp = node.span(); TRACE_FUNCTION_FR("_CallPath - " << node.m_path, m_rv); auto& fcn = get_function(node.span(), m_crate, node.m_path); @@ -651,10 +671,27 @@ namespace { exp_ret_type = fcn.m_return.clone(); - // Call by invoking evaluate_constant on the function + if( fcn.m_abi == "rust-intrinsic" ) + { + auto pp = monomorphise_path_params_with(node.span(), node.m_path.m_data.as_Generic().m_params, m_monomorph_cb, true); + m_rv = evaluate_constant_intrinsic(node.span(), m_crate, m_newval_state, fcn.m_linkage.name, pp, mv$(args)); + } + else { - TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " }"); - m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, mv$(exp_ret_type), mv$(args)); + // Call by invoking evaluate_constant on the function + t_cb_generic cb; + ::HIR::PathParams pp; + if( const auto* g = node.m_path.m_data.opt_Generic() ) + { + pp = monomorphise_path_params_with(node.span(), g->m_params, m_monomorph_cb, true); + cb = monomorphise_type_get_cb(sp, nullptr, nullptr, &pp); + } + else + { + cb = monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr); + } + TRACE_FUNCTION_F("Call const fn " << node.m_path << " args={ " << args << " } - pp=" << pp); + m_rv = evaluate_constant(node.span(), m_crate, m_newval_state, fcn.m_code, cb, mv$(exp_ret_type), mv$(args)); } } void visit(::HIR::ExprNode_CallValue& node) override { @@ -1009,6 +1046,7 @@ namespace { }; Visitor v { crate, newval_state, mv$(exp_type) }; + v.m_monomorph_cb = monomorph_cb; for(auto& arg : args) v.m_values.push_back( mv$(arg) ); const_cast<::HIR::ExprNode&>(expr).visit(v); @@ -1021,7 +1059,7 @@ namespace { return mv$(v.m_rv); } - ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant_mir(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::MIR::Function& fcn, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) { // TODO: Full-blown miri TRACE_FUNCTION_F("exp=" << exp << ", args=" << args); @@ -1452,7 +1490,8 @@ namespace { // Call by invoking evaluate_constant on the function { TRACE_FUNCTION_F("Call const fn " << fcnp << " args={ " << call_args << " }"); - dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, fcn.m_return.clone(), mv$(call_args)); + // TODO: Correct monomorph_cb + dst = evaluate_constant(sp, crate, newval_state, fcn.m_code, monomorph_cb, fcn.m_return.clone(), mv$(call_args)); } cur_block = e.ret_block; @@ -1461,13 +1500,13 @@ namespace { } } - ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) + ::HIR::Literal evaluate_constant(const Span& sp, const ::HIR::Crate& crate, NewvalState newval_state, const ::HIR::ExprPtr& expr, t_cb_generic monomorph_cb, ::HIR::TypeRef exp, ::std::vector< ::HIR::Literal> args) { if( expr.m_mir ) { - return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, mv$(exp), mv$(args)); + return evaluate_constant_mir(sp, crate, mv$(newval_state), *expr.m_mir, monomorph_cb, mv$(exp), mv$(args)); } else if( expr ) { - return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, mv$(exp), mv$(args)); + return evaluate_constant_hir(sp, crate, mv$(newval_state), *expr, monomorph_cb, mv$(exp), mv$(args)); } else { BUG(sp, "Attempting to evaluate constant expression with no associated code"); @@ -1585,13 +1624,14 @@ namespace { ::HIR::Visitor::visit_type(ty); TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e, + TRACE_FUNCTION_FR(ty, ty); if( e.size_val == ~0u ) { assert(e.size); assert(*e.size); const auto& expr_ptr = *e.size; auto nvs = NewvalState { m_new_values, *m_mod_path, FMT("ty_" << &ty << "$") }; - auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, ::HIR::CoreType::Usize); + auto val = evaluate_constant(expr_ptr->span(), m_crate, nvs, expr_ptr, monomorphise_type_get_cb(expr_ptr->span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize); if( !val.is_Integer() ) ERROR(expr_ptr->span(), E0000, "Array size isn't an integer"); e.size_val = static_cast<size_t>(val.as_Integer()); @@ -1615,14 +1655,16 @@ namespace { // return ; auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$") }; - item.m_value_res = evaluate_constant(item.m_value->span(), m_crate, nvs, item.m_value, item.m_type.clone(), {}); + const auto& sp = item.m_value->span(); + item.m_value_res = evaluate_constant(sp, m_crate, nvs, item.m_value, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), item.m_type.clone(), {}); - check_lit_type(item.m_value->span(), item.m_type, item.m_value_res); + check_lit_type(sp, item.m_type, item.m_value_res); DEBUG("constant: " << item.m_type << " = " << item.m_value_res); } } void visit_enum(::HIR::ItemPath p, ::HIR::Enum& item) override { + static Span sp; if( auto* e = item.m_data.opt_Value() ) { uint64_t i = 0; @@ -1630,7 +1672,9 @@ namespace { { if( var.expr ) { - auto val = evaluate_constant(var.expr->span(), m_crate, NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") }, var.expr, {}); + auto nvs = NewvalState { m_new_values, *m_mod_path, FMT(p.get_name() << "$" << var.name << "$") }; + const auto& sp = var.expr->span(); + auto val = evaluate_constant(sp, m_crate, nvs, var.expr, monomorphise_type_get_cb(sp, nullptr, nullptr, nullptr), {}, {}); DEBUG("enum variant: " << p << "::" << var.name << " = " << val); i = val.as_Integer(); } @@ -1664,7 +1708,7 @@ namespace { void visit(::HIR::ExprNode_ArraySized& node) override { assert( node.m_size ); NewvalState nvs { m_exp.m_new_values, *m_exp.m_mod_path, FMT("array_" << &node << "$") }; - auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, ::HIR::CoreType::Usize, {}); + auto val = evaluate_constant_hir(node.span(), m_exp.m_crate, mv$(nvs), *node.m_size, monomorphise_type_get_cb(node.span(), nullptr, nullptr, nullptr), ::HIR::CoreType::Usize, {}); if( !val.is_Integer() ) ERROR(node.span(), E0000, "Array size isn't an integer"); node.m_size_val = static_cast<size_t>(val.as_Integer()); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 4f698c15..07f86d44 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -890,10 +890,10 @@ namespace { { case ::HIR::ExprNode_BinOp::Op::CmpEqu: item_name = "eq"; break; case ::HIR::ExprNode_BinOp::Op::CmpNEqu: item_name = "eq"; break; - case ::HIR::ExprNode_BinOp::Op::CmpLt: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpLtE: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpGt: item_name = "ord"; break; - case ::HIR::ExprNode_BinOp::Op::CmpGtE: item_name = "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpLt: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpLtE: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpGt: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; + case ::HIR::ExprNode_BinOp::Op::CmpGtE: item_name = TARGETVER_1_29 ? "partial_ord" : "ord"; break; default: break; } assert(item_name); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 22291123..8f1f0685 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1050,8 +1050,10 @@ bool TraitResolution::iterate_bounds( ::std::function<bool(const ::HIR::GenericB bool TraitResolution::iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data::Data_UfcsKnown& pe, ::std::function<bool(const ::HIR::TraitPath&)> cb) const { ::HIR::GenericPath trait_path; + DEBUG("Checking ATY bounds on " << pe.trait << " :: " << pe.item); if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item, trait_path) ) BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait); + DEBUG("trait_path=" << trait_path); const auto& trait_ref = m_crate.get_trait_by_path(sp, trait_path.m_path); const auto& aty_def = trait_ref.m_types.find(pe.item)->second; @@ -1361,12 +1363,19 @@ bool TraitResolution::find_trait_impls(const Span& sp, ASSERT_BUG(sp, e.path.m_data.is_UfcsKnown(), "Opaque bound type wasn't UfcsKnown - " << type); const auto& pe = e.path.m_data.as_UfcsKnown(); + // TODO: Should Self here be `type` or `*pe.type` + // - Depends... if implicit it should be `type` (as it relates to the associated type), but if explicit it's referring to the trait auto monomorph_cb = monomorphise_type_get_cb(sp, &*pe.type, &pe.trait.m_params, nullptr, nullptr); auto rv = this->iterate_aty_bounds(sp, pe, [&](const auto& bound) { + DEBUG("Bound on ATY: " << bound); const auto& b_params = bound.m_path.m_params; ::HIR::PathParams params_mono_o; const auto& b_params_mono = (monomorphise_pathparams_needed(b_params) ? params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false) : b_params); + // TODO: Monormophise and EAT associated types + ::std::map< ::std::string, ::HIR::TypeRef> b_atys; + for(const auto& aty : bound.m_type_bounds) + b_atys.insert(::std::make_pair( aty.first, monomorphise_type_with(sp, aty.second, monomorph_cb) )); if( bound.m_path.m_path == trait ) { @@ -1375,13 +1384,15 @@ bool TraitResolution::find_trait_impls(const Span& sp, { if( &b_params_mono == ¶ms_mono_o ) { - if( callback( ImplRef(type.clone(), mv$(params_mono_o), {}), cmp ) ) + // TODO: assoc bounds + if( callback( ImplRef(type.clone(), mv$(params_mono_o), mv$(b_atys)), cmp ) ) return true; params_mono_o = monomorphise_path_params_with(sp, b_params, monomorph_cb, false); } else { - if( callback( ImplRef(&type, &bound.m_path.m_params, &null_assoc), cmp ) ) + //if( callback( ImplRef(&type, &bound.m_path.m_params, &null_assoc), cmp ) ) + if( callback( ImplRef(&type, &bound.m_path.m_params, &b_atys), cmp ) ) return true; } } @@ -2219,12 +2230,14 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple // TODO: A bound can imply something via its associated types. How deep can this go? // E.g. `T: IntoIterator<Item=&u8>` implies `<T as IntoIterator>::IntoIter : Iterator<Item=&u8>` return this->iterate_bounds([&](const auto& b)->bool { + DEBUG(b); if( b.is_TraitBound() ) { const auto& e = b.as_TraitBound(); const auto& b_params = e.trait.m_path.m_params; auto cmp = e.type .compare_with_placeholders(sp, type, m_ivars.callback_resolve_infer()); + DEBUG("cmp = " << cmp); if( cmp == ::HIR::Compare::Unequal ) return false; @@ -3643,6 +3656,9 @@ const ::HIR::TypeRef* TraitResolution::check_method_receiver(const Span& sp, ::H return &this->m_ivars.get_type(*ty.m_data.as_Borrow().inner); } break; + case ::HIR::Function::Receiver::Custom: + // TODO: Handle custom-receiver functions + return nullptr; case ::HIR::Function::Receiver::Box: if(const auto* ity = this->type_is_owned_box(sp, ty)) { diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index dddb7731..b38511d1 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -201,13 +201,16 @@ namespace { { while( param_vals.m_types.size() < param_def.m_types.size() ) { unsigned int i = param_vals.m_types.size(); - if( param_def.m_types[i].m_default.m_data.is_Infer() ) { + const auto& ty_def = param_def.m_types[i]; + if( ty_def.m_default.m_data.is_Infer() ) { ERROR(sp, E0000, "Unspecified parameter with no default"); } // Replace and expand - param_vals.m_types.push_back( param_def.m_types[i].m_default.clone() ); + param_vals.m_types.push_back( ty_def.m_default.clone() ); auto& ty = param_vals.m_types.back(); + // TODO: Monomorphise? + // Replace `Self` here with the real Self update_self_type(sp, ty); } @@ -220,7 +223,7 @@ namespace { if( param_vals.m_types[i] == ::HIR::TypeRef() ) { //if( param_def.m_types[i].m_default == ::HIR::TypeRef() ) // ERROR(sp, E0000, "Unspecified parameter with no default"); - // TODO: Monomorph? + // TODO: Monomorphise? param_vals.m_types[i] = param_def.m_types[i].m_default.clone(); update_self_type(sp, param_vals.m_types[i]); } @@ -429,6 +432,16 @@ namespace { } return trait_path_g; } + ::HIR::GenericPath get_current_trait_gp() const + { + assert(m_current_trait_path); + assert(m_current_trait); + auto trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); + for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { + trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); + } + return trait_path; + } void visit_path_UfcsUnknown(const Span& sp, ::HIR::Path& p, ::HIR::Visitor::PathContext pc) { TRACE_FUNCTION_FR("UfcsUnknown - p=" << p, p); @@ -449,10 +462,7 @@ namespace { // If processing a trait, and the type is 'Self', search for the type/method on the trait // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues? if( te.name == "Self" && m_current_trait ) { - auto trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); - for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { - trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); - } + auto trait_path = this->get_current_trait_gp(); if( this->locate_in_trait_and_set(sp, pc, trait_path, *m_current_trait, p.m_data) ) { // Success! return ; @@ -616,6 +626,17 @@ namespace { auto _ = m_resolve.set_item_generics(item.m_params); ::HIR::Visitor::visit_enum(p, item); } + void visit_associatedtype(::HIR::ItemPath p, ::HIR::AssociatedType& item) + { + // Push `Self = <Self as CurTrait>::Type` for processing defaults in the bounds. + auto path_aty = ::HIR::Path( ::HIR::TypeRef("Self", 0xFFFF), this->get_current_trait_gp(), p.get_name() ); + auto ty_aty = ::HIR::TypeRef::new_path( mv$(path_aty), ::HIR::TypeRef::TypePathBinding::make_Opaque({}) ); + m_self_types.push_back(&ty_aty); + + ::HIR::Visitor::visit_associatedtype(p, item); + + m_self_types.pop_back(); + } void visit_type_impl(::HIR::TypeImpl& impl) override { diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 8000f5af..cfa94dbb 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -118,6 +118,16 @@ bool StaticTraitResolve::find_impl( } } + if(const auto* e = type.m_data.opt_Generic() ) + { + if( (e->binding >> 8) == 2 ) + { + // TODO: If the type is a magic placeholder, assume it impls the specified trait. + // TODO: Restructure so this knows that the placehlder impls the impl-provided bounds. + return found_cb( ImplRef(&type, trait_params, &null_assoc), false ); + } + } + // --- MAGIC IMPLS --- // TODO: There should be quite a few more here, but laziness TU_IFLET(::HIR::TypeRef::Data, type.m_data, Function, e, @@ -556,6 +566,7 @@ bool StaticTraitResolve::find_impl__check_crate_raw( if( placeholders.size() == 0 ) placeholders.resize(impl_params.size()); placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i); + DEBUG("Placeholder " << placeholders[i] << " for " << impl_params_def.m_types[i].m_name); } } // Callback that matches placeholders to concrete types @@ -571,6 +582,9 @@ bool StaticTraitResolve::find_impl__check_crate_raw( ph = ty.clone(); return ::HIR::Compare::Equal; } + else if( ph == ty ) { + return ::HIR::Compare::Equal; + } else { TODO(sp, "[find_impl__check_crate_raw:cb_match] Compare placeholder " << i << " " << ph << " == " << ty); } diff --git a/src/include/target_version.hpp b/src/include/target_version.hpp new file mode 100644 index 00000000..dddf69e4 --- /dev/null +++ b/src/include/target_version.hpp @@ -0,0 +1,11 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * include/target_version.hpp + * - mrustc target lanuage version definitions + */ +#pragma once + +#define TARGETVER_1_19 true +#define TARGETVER_1_29 true |