summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-03 13:03:10 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-03 13:03:10 +0800
commitc621ce63d46c6902d26ffe246295da9303143a39 (patch)
tree4614ebbf3b85905b0acfd1e64d08a06a73f0cc4b
parentc6b54cafb06560d298b550a3711de642710f72e1 (diff)
downloadmrust-c621ce63d46c6902d26ffe246295da9303143a39.tar.gz
HIR/Trans - Bind items in external MIR, use StaticTraitResolve in trans
-rw-r--r--src/hir_conv/bind.cpp133
-rw-r--r--src/hir_typeck/static.cpp89
-rw-r--r--src/hir_typeck/static.hpp11
-rw-r--r--src/mir/mir_ptr.hpp4
-rw-r--r--src/trans/enumerate.cpp88
-rw-r--r--src/trans/trans_list.hpp10
6 files changed, 292 insertions, 43 deletions
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index d88a9fbb..a83b70d3 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -9,6 +9,7 @@
#include "main_bindings.hpp"
#include <hir/visitor.hpp>
#include <hir/expr.hpp>
+#include <mir/mir.hpp>
#include <algorithm> // std::find_if
#include <hir_typeck/static.hpp>
@@ -482,6 +483,138 @@ namespace {
ExprVisitor v { *this };
(*expr).visit(v);
}
+ else if( expr.m_mir )
+ {
+ struct H {
+ static void visit_lvalue(Visitor& upper_visitor, ::MIR::LValue& lv)
+ {
+ TU_MATCHA( (lv), (e),
+ (Variable,
+ ),
+ (Temporary,
+ ),
+ (Argument,
+ ),
+ (Return,
+ ),
+ (Static,
+ upper_visitor.visit_path(e, ::HIR::Visitor::PathContext::VALUE);
+ ),
+ (Field,
+ H::visit_lvalue(upper_visitor, *e.val);
+ ),
+ (Deref,
+ H::visit_lvalue(upper_visitor, *e.val);
+ ),
+ (Index,
+ H::visit_lvalue(upper_visitor, *e.val);
+ H::visit_lvalue(upper_visitor, *e.idx);
+ ),
+ (Downcast,
+ H::visit_lvalue(upper_visitor, *e.val);
+ )
+ )
+ }
+ };
+ for(auto& block : expr.m_mir->blocks)
+ {
+ for(auto& stmt : block.statements)
+ {
+ TU_IFLET(::MIR::Statement, stmt, Assign, se,
+ H::visit_lvalue(*this, se.dst);
+ TU_MATCHA( (se.src), (e),
+ (Use,
+ H::visit_lvalue(*this, e);
+ ),
+ (Constant,
+ TU_MATCHA( (e), (ce),
+ (Int, ),
+ (Uint,),
+ (Float, ),
+ (Bool, ),
+ (Bytes, ),
+ (StaticString, ), // String
+ (Const,
+ // TODO: Should this trigger anything?
+ ),
+ (ItemAddr,
+ this->visit_path(ce, ::HIR::Visitor::PathContext::VALUE);
+ )
+ )
+ ),
+ (SizedArray,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (Borrow,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (Cast,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (BinOp,
+ H::visit_lvalue(*this, e.val_l);
+ H::visit_lvalue(*this, e.val_r);
+ ),
+ (UniOp,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (DstMeta,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (DstPtr,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (MakeDst,
+ H::visit_lvalue(*this, e.meta_val);
+ H::visit_lvalue(*this, e.ptr_val);
+ ),
+ (Tuple,
+ for(auto& val : e.vals)
+ H::visit_lvalue(*this, val);
+ ),
+ (Array,
+ for(auto& val : e.vals)
+ H::visit_lvalue(*this, val);
+ ),
+ (Variant,
+ H::visit_lvalue(*this, e.val);
+ ),
+ (Struct,
+ for(auto& val : e.vals)
+ H::visit_lvalue(*this, val);
+ )
+ )
+ )
+ else TU_IFLET(::MIR::Statement, stmt, Drop, se,
+ H::visit_lvalue(*this, se.slot);
+ )
+ else {
+ }
+ }
+ TU_MATCHA( (block.terminator), (te),
+ (Incomplete, ),
+ (Return, ),
+ (Diverge, ),
+ (Goto, ),
+ (Panic, ),
+ (If,
+ H::visit_lvalue(*this, te.cond);
+ ),
+ (Switch,
+ H::visit_lvalue(*this, te.val);
+ ),
+ (Call,
+ H::visit_lvalue(*this, te.ret_val);
+ H::visit_lvalue(*this, te.fcn_val);
+ for(auto& arg : te.args)
+ H::visit_lvalue(*this, arg);
+ )
+ )
+ }
+ }
+ else
+ {
+ }
}
};
}
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index 5d7f2512..243690ce 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -101,6 +101,11 @@ bool StaticTraitResolve::find_impl(
return found_cb( ImplRef(&type, &null_params, &null_assoc), false );
}
}
+ else if( trait_path == m_lang_Sized ) {
+ if( this->type_is_sized(sp, type) ) {
+ return found_cb( ImplRef(&type, &null_params, &null_assoc), false );
+ }
+ }
}
// --- MAGIC IMPLS ---
@@ -806,7 +811,12 @@ void StaticTraitResolve::expand_associated_types_inner(const Span& sp, ::HIR::Ty
this->expand_associated_types_inner(sp, arg);
),
(UfcsInherent,
- TODO(sp, "Path - UfcsInherent - " << e.path);
+ this->expand_associated_types_inner(sp, *e2.type);
+ for(auto& arg : e2.params.m_types)
+ this->expand_associated_types_inner(sp, arg);
+ // TODO: impl params too?
+ for(auto& arg : e2.impl_params.m_types)
+ this->expand_associated_types_inner(sp, arg);
),
(UfcsKnown,
// - Only try resolving if the binding isn't known
@@ -1295,3 +1305,80 @@ bool StaticTraitResolve::type_is_copy(const Span& sp, const ::HIR::TypeRef& ty)
)
throw "";
}
+
+bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const
+{
+ TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e),
+ (Generic,
+ if( e.binding == 0xFFFF ) {
+ // TODO: Self: Sized?
+ return true;
+ }
+ else if( (e.binding >> 8) == 0 ) {
+ auto idx = e.binding & 0xFF;
+ assert( m_impl_generics );
+ assert( idx < m_impl_generics->m_types.size() );
+ return m_impl_generics->m_types[idx].m_is_sized;
+ }
+ else if( (e.binding >> 8) == 1 ) {
+ auto idx = e.binding & 0xFF;
+ assert( m_item_generics );
+ assert( idx < m_item_generics->m_types.size() );
+ return m_item_generics->m_types[idx].m_is_sized;
+ }
+ else {
+ BUG(sp, "");
+ }
+ ),
+ (Path,
+ auto pp = ::HIR::PathParams();
+ // TODO: Destructure?
+ return true;
+ //return this->find_impl(sp, m_lang_Sized, &pp, ty, [&](auto , bool){ return true; }, true);
+ ),
+ (Diverge,
+ // The ! type is kinda Copy ...
+ return true;
+ ),
+ (Closure,
+ return true;
+ ),
+ (Infer,
+ // Shouldn't be hit
+ return false;
+ ),
+ (Borrow,
+ return true;
+ ),
+ (Pointer,
+ return true;
+ ),
+ (Function,
+ return true;
+ ),
+ (Primitive,
+ // All primitives (except the unsized `str`) are Sized
+ return e != ::HIR::CoreType::Str;
+ ),
+ (Array,
+ return true;
+ ),
+ (Slice,
+ return false;
+ ),
+ (TraitObject,
+ return false;
+ ),
+ (ErasedType,
+ // NOTE: All erased types are implicitly Sized
+ return true;
+ ),
+ (Tuple,
+ for(const auto& ty : e)
+ if( !type_is_sized(sp, ty) )
+ return false;
+ return true;
+ )
+ )
+ throw "";
+}
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 80b9ed56..b2b259fd 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -23,6 +23,7 @@ public:
::std::map< ::HIR::TypeRef, ::HIR::TypeRef> m_type_equalities;
private:
::HIR::SimplePath m_lang_Copy;
+ ::HIR::SimplePath m_lang_Sized;
::HIR::SimplePath m_lang_Fn;
::HIR::SimplePath m_lang_FnMut;
::HIR::SimplePath m_lang_FnOnce;
@@ -33,10 +34,11 @@ public:
m_impl_generics(nullptr),
m_item_generics(nullptr)
{
- m_lang_Copy = m_crate.get_lang_item_path(Span(), "copy");
- m_lang_Fn = m_crate.get_lang_item_path(Span(), "fn");
- m_lang_FnMut = m_crate.get_lang_item_path(Span(), "fn_mut");
- m_lang_FnOnce = m_crate.get_lang_item_path(Span(), "fn_once");
+ m_lang_Copy = m_crate.get_lang_item_path_opt("copy");
+ m_lang_Sized = m_crate.get_lang_item_path_opt("sized");
+ m_lang_Fn = m_crate.get_lang_item_path_opt("fn");
+ m_lang_FnMut = m_crate.get_lang_item_path_opt("fn_mut");
+ m_lang_FnOnce = m_crate.get_lang_item_path_opt("fn_once");
prep_indexes();
}
@@ -163,5 +165,6 @@ public:
// Common bounds
// -------------
bool type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const;
+ bool type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const;
};
diff --git a/src/mir/mir_ptr.hpp b/src/mir/mir_ptr.hpp
index 180fd6c3..583b155b 100644
--- a/src/mir/mir_ptr.hpp
+++ b/src/mir/mir_ptr.hpp
@@ -32,9 +32,9 @@ public:
void reset();
- ::MIR::Function& operator->() { return *ptr; }
+ ::MIR::Function* operator->() { return ptr; }
::MIR::Function& operator*() { return *ptr; }
- const ::MIR::Function& operator->() const { return *ptr; }
+ const ::MIR::Function* operator->() const { return ptr; }
const ::MIR::Function& operator*() const { return *ptr; }
operator bool() const { return ptr != nullptr; }
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 24c87897..97e510de 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -11,7 +11,8 @@
#include "trans_list.hpp"
#include <hir/hir.hpp>
#include <mir/mir.hpp>
-#include <hir_typeck/common.hpp>
+#include <hir_typeck/common.hpp> // monomorph
+#include <hir_typeck/static.hpp> // StaticTraitResolve
void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Function& function, TransList_Function& fcn_out, Trans_Params pp={});
@@ -20,9 +21,11 @@ void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const :
/// Enumerate trans items starting from `::main` (binary crate)
TransList Trans_Enumerate_Main(const ::HIR::Crate& crate)
{
+ static Span sp;
+
TransList rv;
auto main_path = ::HIR::SimplePath("", {"main"});
- const auto& fcn = crate.get_function_by_path(Span(), main_path);
+ const auto& fcn = crate.get_function_by_path(sp, main_path);
auto* ptr = rv.add_function(main_path);
assert(ptr);
@@ -136,6 +139,9 @@ namespace {
}
EntPtr get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path, ::HIR::PathParams& impl_pp)
{
+ TRACE_FUNCTION_F(path);
+ StaticTraitResolve resolve { crate };
+
TU_MATCH(::HIR::Path::Data, (path.m_data), (e),
(Generic,
return get_ent_simplepath(sp, crate, e.m_path);
@@ -182,31 +188,13 @@ namespace {
::std::vector<const ::HIR::TypeRef*> best_impl_params;
const ::HIR::TraitImpl* best_impl = nullptr;
- crate.find_trait_impls(e.trait.m_path, *e.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) {
- DEBUG("Found impl" << impl.m_params.fmt_args() << " " << e.trait.m_path << impl.m_trait_args << " for " << impl.m_type);
+ resolve.find_impl(sp, e.trait.m_path, e.trait.m_params, *e.type, [&](auto impl_ref, auto is_fuzz) {
+ DEBUG("Found " << impl_ref);
+ //ASSERT_BUG(sp, !is_fuzz, "Fuzzy match not allowed here");
+ ASSERT_BUG(sp, impl_ref.m_data.is_TraitImpl(), "Trans impl search found an invalid impl type");
+ const auto& impl = *impl_ref.m_data.as_TraitImpl().impl;
ASSERT_BUG(sp, impl.m_trait_args.m_types.size() == e.trait.m_params.m_types.size(), "Trait parameter count mismatch " << impl.m_trait_args << " vs " << e.trait.m_params);
- ::std::vector<const ::HIR::TypeRef*> impl_params;
-
- auto cb_ident = [](const auto& t)->const auto& { return t; };
- auto cb = [&impl_params,&sp,cb_ident](auto idx, const auto& ty) {
- assert( idx < impl_params.size() );
- if( ! impl_params[idx] ) {
- impl_params[idx] = &ty;
- return ::HIR::Compare::Equal;
- }
- else {
- return impl_params[idx]->compare_with_placeholders(sp, ty, cb_ident);
- }
- };
- impl_params.resize(impl.m_params.m_types.size());
- auto match = impl.m_type.match_test_generics_fuzz(sp, *e.type, cb_ident, cb);
- match &= impl.m_trait_args.match_test_generics_fuzz(sp, e.trait.m_params, cb_ident, cb);
- if( match != ::HIR::Compare::Equal ) {
- DEBUG("- Match failed (" << match << ") " << *e.type << " \n + " << e.trait.m_params);
- return false;
- }
-
if( best_impl == nullptr || impl.more_specific_than(*best_impl) ) {
best_impl = &impl;
bool is_spec = false;
@@ -229,7 +217,7 @@ namespace {
is_spec = fit->second.is_specialisable;
)
)
- best_impl_params = mv$( impl_params );
+ best_impl_params = mv$( impl_ref.m_data.as_TraitImpl().params );
return !is_spec;
}
return false;
@@ -239,7 +227,7 @@ namespace {
const auto& impl = *best_impl;
for(const auto* ty_ptr : best_impl_params) {
- assert( ty_ptr );
+ ASSERT_BUG(sp, ty_ptr, "Parameter unset");
impl_pp.m_types.push_back( ty_ptr->clone() );
}
@@ -272,18 +260,22 @@ namespace {
void Trans_Enumerate_FillFrom_Path(TransList& out, const ::HIR::Crate& crate, const ::HIR::Path& path, const Trans_Params& pp)
{
+ TRACE_FUNCTION_F(path);
Span sp;
- auto path_mono = pp.monomorph(path);
- Trans_Params sub_pp;
+ auto path_mono = pp.monomorph(crate, path);
+ Trans_Params sub_pp(sp);
TU_MATCHA( (path_mono.m_data), (pe),
(Generic,
- sub_pp = Trans_Params { sp, pe.m_params.clone() };
+ sub_pp.pp_method = pe.m_params.clone();
),
(UfcsKnown,
- sub_pp = Trans_Params { sp, pe.params.clone(), {}, pe.type->clone() };
+ sub_pp.pp_method = pe.params.clone();
+ sub_pp.self_type = pe.type->clone();
),
(UfcsInherent,
- sub_pp = Trans_Params { sp, pe.params.clone(), pe.impl_params.clone(), pe.type->clone() };
+ sub_pp.pp_method = pe.params.clone();
+ sub_pp.pp_impl = pe.impl_params.clone();
+ sub_pp.self_type = pe.type->clone();
),
(UfcsUnknown,
BUG(sp, "UfcsUnknown - " << path);
@@ -479,8 +471,36 @@ t_cb_generic Trans_Params::get_cb() const
{
return monomorphise_type_get_cb(sp, &self_type, &pp_impl, &pp_method);
}
-::HIR::Path Trans_Params::monomorph(const ::HIR::Path& p) const
+::HIR::Path Trans_Params::monomorph(const ::HIR::Crate& crate, const ::HIR::Path& p) const
{
- return monomorphise_path_with(sp, p, this->get_cb(), false);
+ TRACE_FUNCTION_F(p);
+ auto rv = monomorphise_path_with(sp, p, this->get_cb(), false);
+
+ ::StaticTraitResolve resolve { crate };
+ TU_MATCH(::HIR::Path::Data, (rv.m_data), (e2),
+ (Generic,
+ for(auto& arg : e2.m_params.m_types)
+ resolve.expand_associated_types(sp, arg);
+ ),
+ (UfcsInherent,
+ resolve.expand_associated_types(sp, *e2.type);
+ for(auto& arg : e2.params.m_types)
+ resolve.expand_associated_types(sp, arg);
+ // TODO: impl params too?
+ for(auto& arg : e2.impl_params.m_types)
+ resolve.expand_associated_types(sp, arg);
+ ),
+ (UfcsKnown,
+ resolve.expand_associated_types(sp, *e2.type);
+ for(auto& arg : e2.trait.m_params.m_types)
+ resolve.expand_associated_types(sp, arg);
+ for(auto& arg : e2.params.m_types)
+ resolve.expand_associated_types(sp, arg);
+ ),
+ (UfcsUnknown,
+ BUG(sp, "Encountered UfcsUnknown");
+ )
+ )
+ return rv;
}
diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp
index 278d8795..78ebd264 100644
--- a/src/trans/trans_list.hpp
+++ b/src/trans/trans_list.hpp
@@ -12,6 +12,7 @@
#include <hir_typeck/common.hpp>
namespace HIR {
+class Crate;
class Function;
class Static;
}
@@ -23,9 +24,14 @@ struct Trans_Params
::HIR::PathParams pp_impl;
::HIR::TypeRef self_type;
+ Trans_Params() {}
+ Trans_Params(const Span& sp):
+ sp(sp)
+ {}
+
t_cb_generic get_cb() const;
- ::HIR::TypeRef monomorph(const ::HIR::TypeRef& p) const;
- ::HIR::Path monomorph(const ::HIR::Path& p) const;
+ ::HIR::TypeRef monomorph(const ::HIR::Crate& crate, const ::HIR::TypeRef& p) const;
+ ::HIR::Path monomorph(const ::HIR::Crate& crate, const ::HIR::Path& p) const;
};
struct TransList_Function