summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-25 14:49:55 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-25 14:49:55 +0800
commit6ceb82723d6594d96a1308aa16f9ec863246935d (patch)
tree5eb6541a066d8022b00e85958203294022c99814
parent7b0dfc5a859d8fb2cc940764d0c8106c87b5f05b (diff)
downloadmrust-6ceb82723d6594d96a1308aa16f9ec863246935d.tar.gz
HIR - Shift markings to their own pass, store in crate metadata.
-rw-r--r--Makefile2
-rw-r--r--src/hir/deserialise.cpp35
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/hir/serialise.cpp31
-rw-r--r--src/hir_conv/bind.cpp44
-rw-r--r--src/hir_conv/main_bindings.hpp3
-rw-r--r--src/hir_conv/markings.cpp85
-rw-r--r--src/hir_typeck/expr_cs.cpp36
-rw-r--r--src/main.cpp4
9 files changed, 185 insertions, 57 deletions
diff --git a/Makefile b/Makefile
index 0d9f52d1..06312143 100644
--- a/Makefile
+++ b/Makefile
@@ -81,7 +81,7 @@ OBJ += hir/hir.o hir/generic_params.o
OBJ += hir/crate_ptr.o hir/type_ptr.o hir/expr_ptr.o
OBJ += hir/type.o hir/path.o hir/expr.o hir/pattern.o
OBJ += hir/visitor.o hir/crate_post_load.o
-OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o hir_conv/resolve_ufcs.o hir_conv/bind.o
+OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o hir_conv/resolve_ufcs.o hir_conv/bind.o hir_conv/markings.o
OBJ += hir_typeck/outer.o hir_typeck/common.o hir_typeck/helpers.o hir_typeck/static.o hir_typeck/impl_ref.o
OBJ += hir_typeck/expr_visit.o
OBJ += hir_typeck/expr_cs.o
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index fffff7fa..1880b660 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -510,6 +510,22 @@ namespace {
deserialise_type()
};
}
+ ::HIR::TraitMarkings deserialise_markings()
+ {
+ ::HIR::TraitMarkings m;
+ uint8_t bitflag_1 = m_in.read_u8();
+ #define BIT(i,fld) fld = (bitflag_1 & (1 << (i))) != 0;
+ BIT(0, m.can_coerce)
+ BIT(1, m.can_unsize)
+ BIT(2, m.has_a_deref)
+ BIT(3, m.is_always_unsized)
+ BIT(4, m.is_always_sized)
+ BIT(5, m.is_copy)
+ #undef BIT
+ // TODO: auto_impls
+ return m;
+ }
+
::HIR::Enum deserialise_enum();
::HIR::Enum::Variant deserialise_enumvariant();
@@ -751,14 +767,15 @@ namespace {
throw "";
}
}
-
+
::HIR::Enum HirDeserialiser::deserialise_enum()
{
TRACE_FUNCTION;
return ::HIR::Enum {
deserialise_genericparams(),
static_cast< ::HIR::Enum::Repr>(m_in.read_tag()),
- deserialise_vec< ::std::pair< ::std::string, ::HIR::Enum::Variant> >()
+ deserialise_vec< ::std::pair< ::std::string, ::HIR::Enum::Variant> >(),
+ deserialise_markings()
};
}
::HIR::Enum::Variant HirDeserialiser::deserialise_enumvariant()
@@ -785,10 +802,11 @@ namespace {
TRACE_FUNCTION;
auto params = deserialise_genericparams();
auto repr = static_cast< ::HIR::Union::Repr>( m_in.read_tag() );
+ auto variants = deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >();
+ auto markings = deserialise_markings();
return ::HIR::Union {
- mv$(params), repr,
- deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >()
+ mv$(params), repr, mv$(variants), mv$(markings)
};
}
::HIR::Struct HirDeserialiser::deserialise_struct()
@@ -804,19 +822,22 @@ namespace {
DEBUG("Unit");
return ::HIR::Struct {
mv$(params), repr,
- ::HIR::Struct::Data::make_Unit( {} )
+ ::HIR::Struct::Data::make_Unit( {} ),
+ deserialise_markings()
};
case ::HIR::Struct::Data::TAG_Tuple:
DEBUG("Tuple");
return ::HIR::Struct {
mv$(params), repr,
- ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() )
+ ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() ),
+ deserialise_markings()
};
case ::HIR::Struct::Data::TAG_Named:
DEBUG("Named");
return ::HIR::Struct {
mv$(params), repr,
- ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() )
+ ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() ),
+ deserialise_markings()
};
default:
throw "";
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index d5f04fd3..6843e93d 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -135,6 +135,8 @@ struct TraitMarkings
{
/// There is at least one CoerceUnsized impl for this type
bool can_coerce = false;
+ /// There is at least one CoerceUnsized impl for this type
+ bool can_unsize = false;
/// Indicates that there is at least one Deref impl
bool has_a_deref = false;
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index dd68a792..bf28a53f 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -727,11 +727,14 @@ namespace {
serialise_generics(ta.m_params);
serialise_type(ta.m_type);
}
- void serialise(const ::HIR::Enum& ta)
+ void serialise(const ::HIR::Enum& item)
{
- serialise_generics(ta.m_params);
- m_out.write_tag( static_cast<int>(ta.m_repr) );
- serialise_vec( ta.m_variants );
+ serialise_generics(item.m_params);
+ m_out.write_tag( static_cast<int>(item.m_repr) );
+
+ serialise_vec( item.m_variants );
+
+ serialise(item.m_markings);
}
void serialise(const ::HIR::Enum::Variant& v)
{
@@ -751,6 +754,21 @@ namespace {
)
)
}
+
+ void serialise(const ::HIR::TraitMarkings& m)
+ {
+ uint8_t bitflag_1 = 0;
+ #define BIT(i,fld) if(fld) bitflag_1 |= 1 << (i);
+ BIT(0, m.can_coerce)
+ BIT(1, m.can_unsize)
+ BIT(2, m.has_a_deref)
+ BIT(3, m.is_always_unsized)
+ BIT(4, m.is_always_sized)
+ BIT(5, m.is_copy)
+ #undef BIT
+ m_out.write_u8(bitflag_1);
+ // TODO: auto_impls
+ }
void serialise(const ::HIR::Struct& item)
{
@@ -770,6 +788,8 @@ namespace {
serialise_vec(e);
)
)
+
+ serialise(item.m_markings);
}
void serialise(const ::HIR::Union& item)
{
@@ -777,7 +797,10 @@ namespace {
serialise_generics(item.m_params);
m_out.write_tag( static_cast<int>(item.m_repr) );
+
serialise_vec(item.m_variants);
+
+ serialise(item.m_markings);
}
void serialise(const ::HIR::Trait& item)
{
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index 7a1049e6..d88a9fbb 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -131,14 +131,10 @@ namespace {
public ::HIR::Visitor
{
const ::HIR::Crate& m_crate;
- const ::HIR::SimplePath& m_lang_CoerceUnsized;
- const ::HIR::SimplePath& m_lang_Deref;
public:
Visitor(const ::HIR::Crate& crate):
- m_crate(crate),
- m_lang_CoerceUnsized(m_crate.get_lang_item_path_opt("coerce_unsized")),
- m_lang_Deref(m_crate.get_lang_item_path_opt("coerce_unsized"))
+ m_crate(crate)
{}
void visit_trait_path(::HIR::TraitPath& p) override
@@ -487,44 +483,6 @@ namespace {
(*expr).visit(v);
}
}
-
- void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
- {
- ::HIR::Visitor::visit_trait_impl(trait_path, impl);
-
- TU_IFLET(::HIR::TypeRef::Data, impl.m_type.m_data, Path, te,
- ::HIR::TraitMarkings* markings = nullptr;
- TU_MATCHA( (te.binding), (tpb),
- (Unbound,
- // Wut?
- ),
- (Opaque,
- // Just ignore, it's a wildcard... wait? is that valid?
- ),
- (Struct,
- markings = &const_cast<HIR::Struct*>(tpb)->m_markings;
- ),
- (Union,
- markings = &const_cast<HIR::Union*>(tpb)->m_markings;
- ),
- (Enum,
- markings = &const_cast<HIR::Enum*>(tpb)->m_markings;
- )
- )
-
- if( markings )
- {
- // CoerceUnsized - set flag to avoid needless searches later
- if( trait_path == m_lang_CoerceUnsized ) {
- markings->can_coerce = true;
- }
- // Deref - set flag to avoid needless searches later
- else if( trait_path == m_lang_Deref ) {
- markings->has_a_deref = true;
- }
- }
- )
- }
};
}
diff --git a/src/hir_conv/main_bindings.hpp b/src/hir_conv/main_bindings.hpp
index 732e1722..fe99b859 100644
--- a/src/hir_conv/main_bindings.hpp
+++ b/src/hir_conv/main_bindings.hpp
@@ -6,7 +6,8 @@ namespace HIR {
class Crate;
};
-extern void ConvertHIR_ResolveUFCS(::HIR::Crate& crate);
extern void ConvertHIR_ExpandAliases(::HIR::Crate& crate);
extern void ConvertHIR_Bind(::HIR::Crate& crate);
+extern void ConvertHIR_ResolveUFCS(::HIR::Crate& crate);
+extern void ConvertHIR_Markings(::HIR::Crate& crate);
extern void ConvertHIR_ConstantEvaluate(::HIR::Crate& hir_crate);
diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp
new file mode 100644
index 00000000..577ed63a
--- /dev/null
+++ b/src/hir_conv/markings.cpp
@@ -0,0 +1,85 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * hir_conv/markings.cpp
+ * - Fills the TraitMarkings structure on types
+ */
+#include "main_bindings.hpp"
+#include <hir/visitor.hpp>
+#include <hir/expr.hpp>
+#include <algorithm> // std::find_if
+
+#include <hir_typeck/static.hpp>
+
+namespace {
+
+class Visitor:
+ public ::HIR::Visitor
+{
+ const ::HIR::Crate& m_crate;
+ const ::HIR::SimplePath& m_lang_Unsize;
+ const ::HIR::SimplePath& m_lang_CoerceUnsized;
+ const ::HIR::SimplePath& m_lang_Deref;
+public:
+ Visitor(const ::HIR::Crate& crate):
+ m_crate(crate),
+ m_lang_Unsize( crate.get_lang_item_path_opt("unsize") ),
+ m_lang_CoerceUnsized( crate.get_lang_item_path_opt("coerce_unsized") ),
+ m_lang_Deref( crate.get_lang_item_path_opt("deref") )
+ {
+ }
+
+ void visit_struct(::HIR::ItemPath ip, ::HIR::Struct& str) override
+ {
+ ::HIR::Visitor::visit_struct(ip, str);
+ }
+
+ void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
+ {
+ static Span sp;
+
+ ::HIR::Visitor::visit_trait_impl(trait_path, impl);
+
+ if( impl.m_type.m_data.is_Path() )
+ {
+ const auto& te = impl.m_type.m_data.as_Path();
+ const ::HIR::TraitMarkings* markings_ptr = nullptr;
+ TU_MATCHA( (te.binding), (tpb),
+ (Unbound, BUG(sp, "Unbound type path in trait impl - " << impl.m_type); ),
+ (Opaque, ),
+ (Struct, markings_ptr = &tpb->m_markings; ),
+ (Union , markings_ptr = &tpb->m_markings; ),
+ (Enum , markings_ptr = &tpb->m_markings; )
+ )
+ if( markings_ptr )
+ {
+ ::HIR::TraitMarkings& markings = *const_cast<::HIR::TraitMarkings*>(markings_ptr);
+ if( trait_path == m_lang_Unsize ) {
+ DEBUG("Type " << impl.m_type << " can Unsize");
+ markings.can_unsize = true;
+ }
+ else if( trait_path == m_lang_CoerceUnsized ) {
+ DEBUG("Type " << impl.m_type << " can Coerce");
+ markings.can_coerce = true;
+ }
+ else if( trait_path == m_lang_Deref ) {
+ DEBUG("Type " << impl.m_type << " can Deref");
+ markings.has_a_deref = true;
+ }
+ // TODO: Marker traits (with conditions)
+ else {
+ }
+ }
+ }
+ }
+};
+
+} // namespace
+
+void ConvertHIR_Markings(::HIR::Crate& crate)
+{
+ Visitor exp { crate };
+ exp.visit_crate( crate );
+}
+
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 962bf42c..73524d87 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -5110,8 +5110,9 @@ namespace {
}
// Types are equal from the view of being coercion targets
- // - Inequality here means that the targets could coexist (e.g. &[u8; N] and &[u8])
+ // - Inequality here means that the targets could coexist in the list (e.g. &[u8; N] and &[u8])
// - Equality means that they HAVE to be equal (even if they're not currently due to ivars)
+ // - E.g. &mut HashMap<_1> and &mut HashMap<T> would unify
static bool equal_to(const Context& context, const ::HIR::TypeRef& ia, const ::HIR::TypeRef& ib) {
const auto& a = context.m_ivars.get_type(ia);
const auto& b = context.m_ivars.get_type(ib);
@@ -5135,6 +5136,39 @@ namespace {
(Infer,
return false;
),
+ (Path,
+ #if 0
+ if( e_ia.binding.tag() != e_ib.binding.tag() )
+ return false;
+ const ::HIR::TraitMarkings* tm = nullptr;
+ TU_MATCHA( (e_ia.binding, e_ib.binding), (pbe_a, pbe_b),
+ (Unbound, return false; ),
+ (Opaque,
+ // TODO: Check bounds?
+ return false;
+ ),
+ (Struct,
+ if(pbe_a != pbe_b) return false;
+ tm = &pbe_a->m_markings;
+ ),
+ (Union,
+ if(pbe_a != pbe_b) return false;
+ tm = &pbe_a->m_markings;
+ ),
+ (Enum,
+ if(pbe_a != pbe_b) return false;
+ tm = &pbe_a->m_markings;
+ )
+ )
+ assert(tm);
+ if( !tm->can_unsize )
+ return true;
+ // It _could_ unsize, so let it coexist
+ return false;
+ #else
+ return context.m_ivars.types_equal(ia, ib);
+ #endif
+ ),
(Slice,
const auto& ia2 = context.m_ivars.get_type(*e_ia.inner);
const auto& ib2 = context.m_ivars.get_type(*e_ib.inner);
diff --git a/src/main.cpp b/src/main.cpp
index eb177268..45e5bfa8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -45,6 +45,7 @@ void init_debug_list()
g_debug_disable_map.insert( "Resolve Type Aliases" );
g_debug_disable_map.insert( "Resolve Bind" );
g_debug_disable_map.insert( "Resolve UFCS paths" );
+ g_debug_disable_map.insert( "Resolve HIR Markings" );
g_debug_disable_map.insert( "Constant Evaluate" );
g_debug_disable_map.insert( "Typecheck Outer");
@@ -309,6 +310,9 @@ int main(int argc, char *argv[])
CompilePhaseV("Resolve UFCS paths", [&]() {
ConvertHIR_ResolveUFCS(*hir_crate);
});
+ CompilePhaseV("Resolve HIR Markings", [&]() {
+ ConvertHIR_Markings(*hir_crate);
+ });
CompilePhaseV("Constant Evaluate", [&]() {
ConvertHIR_ConstantEvaluate(*hir_crate);
});