summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/ast.hpp3
-rw-r--r--src/hir/dump.cpp33
-rw-r--r--src/hir/from_ast.cpp15
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/hir/visitor.cpp11
-rw-r--r--src/hir/visitor.hpp3
-rw-r--r--src/hir_conv/constant_evaluation.cpp76
-rw-r--r--src/hir_typeck/expr_cs.cpp8
-rw-r--r--src/hir_typeck/helpers.cpp20
-rw-r--r--src/hir_typeck/outer.cpp35
-rw-r--r--src/hir_typeck/static.cpp14
-rw-r--r--src/include/target_version.hpp11
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 == &params_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