summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-07-25 19:04:36 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-07-25 19:04:36 +0800
commitcece72809d4c70debea23fd832e4830d334f52d6 (patch)
treee7c98c7506f49f2fc5cb311eb8c7f849ece64e72
parentde997426229f7d309f76b939d71f8007120631c4 (diff)
downloadmrust-cece72809d4c70debea23fd832e4830d334f52d6.tar.gz
HIR Typecheck - Refactor of markings to keep more information
-rw-r--r--src/hir/deserialise.cpp48
-rw-r--r--src/hir/hir.hpp46
-rw-r--r--src/hir/serialise.cpp18
-rw-r--r--src/hir_conv/markings.cpp51
-rw-r--r--src/hir_typeck/expr_cs.cpp48
-rw-r--r--src/hir_typeck/helpers.cpp20
-rw-r--r--src/hir_typeck/static.cpp20
-rw-r--r--src/mir/check.cpp10
-rw-r--r--src/mir/cleanup.cpp16
-rw-r--r--src/trans/codegen_c.cpp121
10 files changed, 233 insertions, 165 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index 21fc9cea..2301898d 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -591,19 +591,31 @@ namespace {
::HIR::TraitMarkings m;
uint8_t bitflag_1 = m_in.read_u8();
#define BIT(i,fld) fld = (bitflag_1 & (1 << (i))) != 0;
+ BIT(0, m.has_a_deref)
+ BIT(1, m.is_copy)
+ BIT(2, m.has_drop_impl)
+ #undef BIT
+ // TODO: auto_impls
+ return m;
+ }
+ ::HIR::StructMarkings deserialise_str_markings()
+ {
+ ::HIR::StructMarkings m;
+ uint8_t bitflag_1 = m_in.read_u8();
+ #define BIT(i,fld) fld = (bitflag_1 & (1 << (i))) != 0;
BIT(0, m.can_unsize)
- BIT(1, m.has_a_deref)
- BIT(2, m.is_copy)
- BIT(3, m.has_drop_impl)
#undef BIT
- m.dst_type = static_cast< ::HIR::TraitMarkings::DstType>( m_in.read_tag() );
+ m.dst_type = static_cast< ::HIR::StructMarkings::DstType>( m_in.read_tag() );
+ m.coerce_unsized = static_cast<::HIR::StructMarkings::Coerce>( m_in.read_tag() );
m.coerce_unsized_index = m_in.read_count( );
+ m.coerce_param = m_in.read_count( );
m.unsized_field = m_in.read_count( );
m.unsized_param = m_in.read_count();
// TODO: auto_impls
return m;
}
+
::HIR::Enum deserialise_enum();
::HIR::Enum::Variant deserialise_enumvariant();
@@ -906,32 +918,30 @@ namespace {
auto repr = static_cast< ::HIR::Struct::Repr>( m_in.read_tag() );
DEBUG("params = " << params.fmt_args() << params.fmt_bounds());
+ ::HIR::Struct::Data data;
switch( m_in.read_tag() )
{
case ::HIR::Struct::Data::TAG_Unit:
DEBUG("Unit");
- return ::HIR::Struct {
- mv$(params), repr,
- ::HIR::Struct::Data::make_Unit( {} ),
- deserialise_markings()
- };
+ data = ::HIR::Struct::Data::make_Unit( {} );
+ break;
case ::HIR::Struct::Data::TAG_Tuple:
DEBUG("Tuple");
- return ::HIR::Struct {
- mv$(params), repr,
- ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() ),
- deserialise_markings()
- };
+ data = ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() );
+ break;
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> > >() ),
- deserialise_markings()
- };
+ data = ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() );
+ break;
default:
throw "";
}
+ auto markings = deserialise_markings();
+ auto str_markings = deserialise_str_markings();
+
+ return ::HIR::Struct {
+ mv$(params), repr, mv$(data), mv$(markings), mv$(str_markings)
+ };
}
::HIR::Trait HirDeserialiser::deserialise_trait()
{
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index 304bdd64..517a025e 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -157,9 +157,6 @@ typedef ::std::vector< ::std::pair< ::std::string, VisEnt<::HIR::TypeRef> > >
/// Cache of the state of various language traits on an enum/struct
struct TraitMarkings
{
- /// There is at least one Unsize impl for this type
- bool can_unsize = false;
-
/// Indicates that there is at least one Deref impl
bool has_a_deref = false;
@@ -167,19 +164,6 @@ struct TraitMarkings
/// - If there is an impl, there must be an applicable impl to every instance.
bool has_drop_impl = false;
- // If populated, indicates the field that is the coercable pointer.
- unsigned int coerce_unsized_index = ~0u;
-
- // TODO: This would have to be changed for custom DSTs
- enum class DstType {
- None, // Sized
- Possible, // Has a ?Sized field
- Slice, // [T]
- TraitObject, // (Trait)
- } dst_type;
- unsigned int unsized_field = ~0u;
- unsigned int unsized_param = ~0u;
-
/// `true` if there is a Copy impl
bool is_copy = false;
@@ -194,6 +178,35 @@ struct TraitMarkings
mutable ::std::map< ::HIR::SimplePath, AutoMarking> auto_impls;
};
+// Trait implementations relevant only to structs
+struct StructMarkings
+{
+ /// This type has a <T: ?Sized> parameter that is used directly
+ bool can_unsize = false;
+ /// Index of the parameter that is ?Sized
+ unsigned int unsized_param = ~0u;
+
+ // TODO: This would have to be changed for custom DSTs
+ enum class DstType {
+ None, // Sized
+ Possible, // A ?Sized parameter
+ Slice, // [T]
+ TraitObject, // (Trait)
+ } dst_type = DstType::None;
+ unsigned int unsized_field = ~0u;
+
+ enum class Coerce {
+ None, // No CoerceUnsized impl
+ Passthrough, // Is generic over T: CoerceUnsized
+ Pointer, // Contains a pointer to a ?Sized type
+ } coerce_unsized = Coerce::None;
+
+ // If populated, indicates the field that is the coercable pointer.
+ unsigned int coerce_unsized_index = ~0u;
+ // Index of the parameter that controls the CoerceUnsized (either a T: ?Sized, or a T: CoerceUnsized)
+ unsigned int coerce_param = ~0u;
+};
+
class Enum
{
public:
@@ -247,6 +260,7 @@ public:
Data m_data;
TraitMarkings m_markings;
+ StructMarkings m_struct_markings;
};
class Union
{
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index b379312d..4577fb91 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -873,15 +873,26 @@ namespace {
{
uint8_t bitflag_1 = 0;
#define BIT(i,fld) if(fld) bitflag_1 |= 1 << (i);
+ BIT(0, m.has_a_deref)
+ BIT(1, m.is_copy)
+ BIT(2, m.has_drop_impl)
+ #undef BIT
+ m_out.write_u8(bitflag_1);
+
+ // TODO: auto_impls
+ }
+ void serialise(const ::HIR::StructMarkings& m)
+ {
+ uint8_t bitflag_1 = 0;
+ #define BIT(i,fld) if(fld) bitflag_1 |= 1 << (i);
BIT(0, m.can_unsize)
- BIT(1, m.has_a_deref)
- BIT(2, m.is_copy)
- BIT(3, m.has_drop_impl)
#undef BIT
m_out.write_u8(bitflag_1);
m_out.write_tag( static_cast<unsigned int>(m.dst_type) );
+ m_out.write_tag( static_cast<unsigned int>(m.coerce_unsized) );
m_out.write_count( m.coerce_unsized_index );
+ m_out.write_count( m.coerce_param );
m_out.write_count( m.unsized_field );
m_out.write_count( m.unsized_param );
// TODO: auto_impls
@@ -907,6 +918,7 @@ namespace {
)
serialise(item.m_markings);
+ serialise(item.m_struct_markings);
}
void serialise(const ::HIR::Union& item)
{
diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp
index 4550bef5..fd9dabf8 100644
--- a/src/hir_conv/markings.cpp
+++ b/src/hir_conv/markings.cpp
@@ -38,10 +38,10 @@ public:
{
::HIR::Visitor::visit_struct(ip, str);
- str.m_markings.dst_type = get_struct_dst_type(str, str.m_params, {});
- if( str.m_markings.dst_type != ::HIR::TraitMarkings::DstType::None )
+ str.m_struct_markings.dst_type = get_struct_dst_type(str, str.m_params, {});
+ if( str.m_struct_markings.dst_type != ::HIR::StructMarkings::DstType::None )
{
- str.m_markings.unsized_field = (str.m_data.is_Tuple() ? str.m_data.as_Tuple().size()-1 : str.m_data.as_Named().size()-1);
+ str.m_struct_markings.unsized_field = (str.m_data.is_Tuple() ? str.m_data.as_Tuple().size()-1 : str.m_data.as_Named().size()-1);
}
// Rules:
@@ -50,7 +50,7 @@ public:
// - If the final field isn't the parameter, it must also impl Unsize
// HACK: Just determine what ?Sized parameter is controlling the sized-ness
- if( str.m_markings.dst_type == ::HIR::TraitMarkings::DstType::Possible )
+ if( str.m_struct_markings.dst_type == ::HIR::StructMarkings::DstType::Possible )
{
auto& last_field_ty = (str.m_data.is_Tuple() ? str.m_data.as_Tuple().back().ent : str.m_data.as_Named().back().second.ent);
auto ty = ::HIR::TypeRef("", 0);
@@ -62,13 +62,13 @@ public:
{
if( visit_ty_with(last_field_ty, [&](const auto& t){ return t == ty; }) )
{
- assert(str.m_markings.unsized_param == ~0u);
- str.m_markings.unsized_param = i;
+ assert(str.m_struct_markings.unsized_param == ~0u);
+ str.m_struct_markings.unsized_param = i;
}
}
}
- ASSERT_BUG(Span(), str.m_markings.unsized_param != ~0u, "No unsized param for type " << ip);
- str.m_markings.can_unsize = true;
+ ASSERT_BUG(Span(), str.m_struct_markings.unsized_param != ~0u, "No unsized param for type " << ip);
+ str.m_struct_markings.can_unsize = true;
}
}
@@ -237,7 +237,7 @@ public:
tr.m_all_parent_traits = mv$(e.supertraits);
}
- ::HIR::TraitMarkings::DstType get_field_dst_type(const ::HIR::TypeRef& ty, const ::HIR::GenericParams& inner_def, const ::HIR::GenericParams& params_def, const ::HIR::PathParams* params)
+ ::HIR::StructMarkings::DstType get_field_dst_type(const ::HIR::TypeRef& ty, const ::HIR::GenericParams& inner_def, const ::HIR::GenericParams& params_def, const ::HIR::PathParams* params)
{
TRACE_FUNCTION_F("ty=" << ty);
// If the type is generic, and the pointed-to parameters is ?Sized, record as needing unsize
@@ -245,7 +245,7 @@ public:
{
if( inner_def.m_types.at(te->binding).m_is_sized == true )
{
- return ::HIR::TraitMarkings::DstType::None;
+ return ::HIR::StructMarkings::DstType::None;
}
else if( params )
{
@@ -254,23 +254,23 @@ public:
}
else
{
- return ::HIR::TraitMarkings::DstType::Possible;
+ return ::HIR::StructMarkings::DstType::Possible;
}
}
else if( ty.m_data.is_Slice() )
{
- return ::HIR::TraitMarkings::DstType::Slice;
+ return ::HIR::StructMarkings::DstType::Slice;
}
else if( ty.m_data.is_TraitObject() )
{
- return ::HIR::TraitMarkings::DstType::TraitObject;
+ return ::HIR::StructMarkings::DstType::TraitObject;
}
else if( const auto* te = ty.m_data.opt_Path() )
{
// If the type is a struct, check it (recursively)
if( ! te->path.m_data.is_Generic() ) {
// Associated type, TODO: Check this better.
- return ::HIR::TraitMarkings::DstType::None;
+ return ::HIR::StructMarkings::DstType::None;
}
else if( te->binding.is_Struct() ) {
const auto& params_tpl = te->path.m_data.as_Generic().m_params;
@@ -285,15 +285,15 @@ public:
}
}
else {
- return ::HIR::TraitMarkings::DstType::None;
+ return ::HIR::StructMarkings::DstType::None;
}
}
else
{
- return ::HIR::TraitMarkings::DstType::None;
+ return ::HIR::StructMarkings::DstType::None;
}
}
- ::HIR::TraitMarkings::DstType get_struct_dst_type(const ::HIR::Struct& str, const ::HIR::GenericParams& def, const ::HIR::PathParams* params)
+ ::HIR::StructMarkings::DstType get_struct_dst_type(const ::HIR::Struct& str, const ::HIR::GenericParams& def, const ::HIR::PathParams* params)
{
TU_MATCHA( (str.m_data), (se),
(Unit,
@@ -318,7 +318,7 @@ public:
}
)
)
- return ::HIR::TraitMarkings::DstType::None;
+ return ::HIR::StructMarkings::DstType::None;
}
void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
@@ -351,7 +351,8 @@ public:
markings.has_drop_impl = true;
}
else if( trait_path == m_lang_CoerceUnsized ) {
- if( markings_ptr->coerce_unsized_index != ~0u )
+ auto& struct_markings = const_cast<::HIR::Struct*>(te.binding.as_Struct())->m_struct_markings;
+ if( struct_markings.coerce_unsized_index != ~0u )
ERROR(sp, E0000, "CoerceUnsized can only be implemented once per struct");
DEBUG("Type " << impl.m_type << " can Coerce");
@@ -380,6 +381,7 @@ public:
auto monomorph_cb_l = monomorphise_type_get_cb(sp, nullptr, &dst_te.path.m_data.as_Generic().m_params, nullptr);
auto monomorph_cb_r = monomorphise_type_get_cb(sp, nullptr, &te.path.m_data.as_Generic().m_params, nullptr);
+ const ::HIR::TypeRef* field_ty;
TU_MATCHA( (str->m_data), (se),
(Unit,
),
@@ -400,6 +402,7 @@ public:
if( field != ~0u )
ERROR(sp, E0000, "CoerceUnsized impls can only differ by one field");
field = i;
+ field_ty = &se[i].ent;
}
}
}
@@ -421,6 +424,7 @@ public:
if( field != ~0u )
ERROR(sp, E0000, "CoerceUnsized impls can only differ by one field");
field = i;
+ field_ty = &se[i].second.ent;
}
}
}
@@ -428,7 +432,14 @@ public:
)
if( field == ~0u )
ERROR(sp, E0000, "CoerceUnsized requires a field to differ between source and destination");
- markings.coerce_unsized_index = field;
+ struct_markings.coerce_unsized_index = field;
+ if( const auto* te = field_ty->m_data.opt_Generic() ) {
+ struct_markings.coerce_param = te->binding;
+ struct_markings.coerce_unsized = ::HIR::StructMarkings::Coerce::Passthrough;
+ }
+ else {
+ struct_markings.coerce_unsized = ::HIR::StructMarkings::Coerce::Pointer;
+ }
}
else if( trait_path == m_lang_Deref ) {
DEBUG("Type " << impl.m_type << " can Deref");
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index bd92b17e..84442a1b 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -4413,7 +4413,7 @@ namespace {
struct H {
// Check if a path type has or could have a CoerceUnsized impl
- static bool type_has_coerce_path(const ::HIR::TypeRef& ty) {
+ static bool type_has_coerce_path(const Context& context, const ::HIR::TypeRef& ty, bool inner=false) {
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Path, e,
TU_MATCHA( (e.binding), (pbe),
(Unbound,
@@ -4423,23 +4423,40 @@ namespace {
return true;
),
(Struct,
- return pbe->m_markings.coerce_unsized_index != ~0u;
+ //return pbe->m_struct_markings.coerce_unsized_index != ~0u;
+ switch( pbe->m_struct_markings.coerce_unsized )
+ {
+ case ::HIR::StructMarkings::Coerce::None:
+ return false;
+ case ::HIR::StructMarkings::Coerce::Pointer:
+ // If this contains a pointer (or something that acts like one), then assume it always coerces
+ return true;
+ case ::HIR::StructMarkings::Coerce::Passthrough:
+ // TODO: If this generic over a CoerceUnsized type, then check if that type is CoerceUnsized
+ return type_has_coerce_path( context, context.m_ivars.get_type(e.path.m_data.as_Generic().m_params.m_types.at( pbe->m_struct_markings.coerce_param)), true );
+ }
),
(Union,
- return pbe->m_markings.coerce_unsized_index != ~0u;
),
(Enum,
- return pbe->m_markings.coerce_unsized_index != ~0u;
)
)
)
+ else if( inner ) {
+ if( ty.m_data.is_Pointer() || ty.m_data.is_Borrow() ) {
+ return true;
+ }
+ else if( ty.m_data.is_Infer() ) {
+ return true;
+ }
+ }
return false;
}
};
// CoerceUnsized trait
// - Only valid for generic or path destination types
- if( ty_dst.m_data.is_Generic() || H::type_has_coerce_path(ty_dst) )
+ if( ty_dst.m_data.is_Generic() || H::type_has_coerce_path(context, ty_dst) )
{
// `CoerceUnsized<U> for T` means `T -> U`
@@ -4520,7 +4537,7 @@ namespace {
),
(Path,
// If there is an impl of CoerceUnsized<_> for this, don't equate (just return and wait for a while)
- if( H::type_has_coerce_path(ty_src) ) {
+ if( H::type_has_coerce_path(context, ty_src) ) {
// - Fall through and check the destination.
}
else {
@@ -4599,7 +4616,7 @@ namespace {
return true;
),
(Path,
- if( H::type_has_coerce_path(ty_dst) && ty_src.m_data.is_Infer() ) {
+ if( H::type_has_coerce_path(context, ty_dst) && ty_src.m_data.is_Infer() ) {
// If this type is coercble, and the source is _ (which means that the first check would have silently failed)
// - Keep the rule around until the ivar is known
// NOTE: This assumes that a type can only coerce to a variant of itself (which is usually true)
@@ -5300,7 +5317,6 @@ namespace {
(Path,
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,
@@ -5309,22 +5325,18 @@ namespace {
),
(Struct,
if(pbe_a != pbe_b) return false;
- tm = &pbe_a->m_markings;
+ if( !pbe_a->m_struct_markings.can_unsize )
+ return true;
+ // It _could_ unsize, so let it coexist
+ return false;
),
(Union,
- if(pbe_a != pbe_b) return false;
- tm = &pbe_a->m_markings;
+ return false;
),
(Enum,
- if(pbe_a != pbe_b) return false;
- tm = &pbe_a->m_markings;
+ return false;
)
)
- assert(tm);
- if( !tm->can_unsize )
- return true;
- // It _could_ unsize, so let it coexist
- return false;
),
(Slice,
const auto& ia2 = context.m_ivars.get_type(*e_ia.inner);
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 8791be72..af72efa7 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -2950,15 +2950,15 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa
),
(Struct,
// Possibly not sized
- switch( pb->m_markings.dst_type )
+ switch( pb->m_struct_markings.dst_type )
{
- case ::HIR::TraitMarkings::DstType::None:
+ case ::HIR::StructMarkings::DstType::None:
break;
- case ::HIR::TraitMarkings::DstType::Possible:
+ case ::HIR::StructMarkings::DstType::Possible:
// TODO: Check sized-ness of the unsized param/field
break;
- case ::HIR::TraitMarkings::DstType::Slice:
- case ::HIR::TraitMarkings::DstType::TraitObject:
+ case ::HIR::StructMarkings::DstType::Slice:
+ case ::HIR::StructMarkings::DstType::TraitObject:
return ::HIR::Compare::Unequal;
}
)
@@ -3159,8 +3159,8 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa
// Struct<..., T, ...>: Unsize<Struct<..., U, ...>>
if( dst_ty.m_data.is_Path() && src_ty.m_data.is_Path() )
{
- bool dst_is_unsizable = dst_ty.m_data.as_Path().binding.is_Struct() && dst_ty.m_data.as_Path().binding.as_Struct()->m_markings.can_unsize;
- bool src_is_unsizable = src_ty.m_data.as_Path().binding.is_Struct() && src_ty.m_data.as_Path().binding.as_Struct()->m_markings.can_unsize;
+ bool dst_is_unsizable = dst_ty.m_data.as_Path().binding.is_Struct() && dst_ty.m_data.as_Path().binding.as_Struct()->m_struct_markings.can_unsize;
+ bool src_is_unsizable = src_ty.m_data.as_Path().binding.is_Struct() && src_ty.m_data.as_Path().binding.as_Struct()->m_struct_markings.can_unsize;
if( dst_is_unsizable || src_is_unsizable )
{
DEBUG("Struct unsize? " << dst_ty << " <- " << src_ty);
@@ -3177,15 +3177,15 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa
{
DEBUG("Checking for Unsize " << dst_gp << " <- " << src_gp);
// Structures are equal, add the requirement that the ?Sized parameter also impl Unsize
- const auto& dst_inner = m_ivars.get_type( dst_gp.m_params.m_types.at(str.m_markings.unsized_param) );
- const auto& src_inner = m_ivars.get_type( src_gp.m_params.m_types.at(str.m_markings.unsized_param) );
+ const auto& dst_inner = m_ivars.get_type( dst_gp.m_params.m_types.at(str.m_struct_markings.unsized_param) );
+ const auto& src_inner = m_ivars.get_type( src_gp.m_params.m_types.at(str.m_struct_markings.unsized_param) );
auto cb = [&](auto d){
assert(new_type_callback);
// Re-create structure with s/d
auto dst_gp_new = dst_gp.clone();
- dst_gp_new.m_params.m_types.at(str.m_markings.unsized_param) = mv$(d);
+ dst_gp_new.m_params.m_types.at(str.m_struct_markings.unsized_param) = mv$(d);
(*new_type_callback)( ::HIR::TypeRef::new_path(mv$(dst_gp_new), &str) );
};
if( new_type_callback )
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index 09f2e6c6..e33f29e6 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -1477,14 +1477,14 @@ bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty)
),
(Struct,
// TODO: Destructure?
- switch( pbe->m_markings.dst_type )
+ switch( pbe->m_struct_markings.dst_type )
{
- case ::HIR::TraitMarkings::DstType::None:
+ case ::HIR::StructMarkings::DstType::None:
return true;
- case ::HIR::TraitMarkings::DstType::Possible:
- return type_is_sized( sp, e.path.m_data.as_Generic().m_params.m_types.at(pbe->m_markings.unsized_param) );
- case ::HIR::TraitMarkings::DstType::Slice:
- case ::HIR::TraitMarkings::DstType::TraitObject:
+ case ::HIR::StructMarkings::DstType::Possible:
+ return type_is_sized( sp, e.path.m_data.as_Generic().m_params.m_types.at(pbe->m_struct_markings.unsized_param) );
+ case ::HIR::StructMarkings::DstType::Slice:
+ case ::HIR::StructMarkings::DstType::TraitObject:
return false;
}
),
@@ -1598,8 +1598,8 @@ bool StaticTraitResolve::can_unsize(const Span& sp, const ::HIR::TypeRef& dst_ty
// Struct<..., T, ...>: Unsize<Struct<..., U, ...>>
if( dst_ty.m_data.is_Path() && src_ty.m_data.is_Path() )
{
- bool dst_is_unsizable = dst_ty.m_data.as_Path().binding.is_Struct() && dst_ty.m_data.as_Path().binding.as_Struct()->m_markings.can_unsize;
- bool src_is_unsizable = src_ty.m_data.as_Path().binding.is_Struct() && src_ty.m_data.as_Path().binding.as_Struct()->m_markings.can_unsize;
+ bool dst_is_unsizable = dst_ty.m_data.as_Path().binding.is_Struct() && dst_ty.m_data.as_Path().binding.as_Struct()->m_struct_markings.can_unsize;
+ bool src_is_unsizable = src_ty.m_data.as_Path().binding.is_Struct() && src_ty.m_data.as_Path().binding.as_Struct()->m_struct_markings.can_unsize;
if( dst_is_unsizable || src_is_unsizable )
{
DEBUG("Struct unsize? " << dst_ty << " <- " << src_ty);
@@ -1616,8 +1616,8 @@ bool StaticTraitResolve::can_unsize(const Span& sp, const ::HIR::TypeRef& dst_ty
{
DEBUG("Checking for Unsize " << dst_gp << " <- " << src_gp);
// Structures are equal, add the requirement that the ?Sized parameter also impl Unsize
- const auto& dst_inner = dst_gp.m_params.m_types.at(str.m_markings.unsized_param);
- const auto& src_inner = src_gp.m_params.m_types.at(str.m_markings.unsized_param);
+ const auto& dst_inner = dst_gp.m_params.m_types.at(str.m_struct_markings.unsized_param);
+ const auto& src_inner = src_gp.m_params.m_types.at(str.m_struct_markings.unsized_param);
return this->can_unsize(sp, dst_inner, src_inner);
}
else
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index 7c0cd4d8..d17cb660 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -51,11 +51,11 @@ namespace {
{
if( tep->binding.is_Struct() )
{
- switch( tep->binding.as_Struct()->m_markings.dst_type )
+ switch( tep->binding.as_Struct()->m_struct_markings.dst_type )
{
- case ::HIR::TraitMarkings::DstType::None:
+ case ::HIR::StructMarkings::DstType::None:
return ::HIR::TypeRef();
- case ::HIR::TraitMarkings::DstType::Possible: {
+ case ::HIR::StructMarkings::DstType::Possible: {
const auto& path = tep->path.m_data.as_Generic();
const auto& str = *tep->binding.as_Struct();
auto monomorph = [&](const auto& tpl) {
@@ -69,9 +69,9 @@ namespace {
(Named, return get_metadata_type( state, monomorph(se.back().second.ent) ); )
)
throw ""; }
- case ::HIR::TraitMarkings::DstType::Slice:
+ case ::HIR::StructMarkings::DstType::Slice:
return ::HIR::CoreType::Usize;
- case ::HIR::TraitMarkings::DstType::TraitObject:
+ case ::HIR::StructMarkings::DstType::TraitObject:
return ::HIR::TypeRef::new_unit(); // TODO: Get the actual inner metadata type?
}
}
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index f26f2bdd..84052efc 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -490,7 +490,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
(Tuple,
for(unsigned int i = 0; i < se.size(); i ++ ) {
auto val = (i == se.size() - 1 ? mv$(lv) : lv.clone());
- if( i == str.m_markings.coerce_unsized_index ) {
+ if( i == str.m_struct_markings.coerce_unsized_index ) {
vals.push_back( H::get_unit_ptr(state, mutator, monomorph(se[i].ent), ::MIR::LValue::make_Field({ box$(val), i }) ) );
}
else {
@@ -501,7 +501,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
(Named,
for(unsigned int i = 0; i < se.size(); i ++ ) {
auto val = (i == se.size() - 1 ? mv$(lv) : lv.clone());
- if( i == str.m_markings.coerce_unsized_index ) {
+ if( i == str.m_struct_markings.coerce_unsized_index ) {
vals.push_back( H::get_unit_ptr(state, mutator, monomorph(se[i].second.ent), ::MIR::LValue::make_Field({ box$(val), i }) ) );
}
else {
@@ -567,7 +567,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
MIR_ASSERT(state, de.binding.is_Struct(), "Unsize to non-struct - " << dst_ty);
MIR_ASSERT(state, de.binding.as_Struct() == se.binding.as_Struct(), "Unsize between mismatched types - " << dst_ty << " and " << src_ty);
const auto& str = *de.binding.as_Struct();
- MIR_ASSERT(state, str.m_markings.unsized_field != ~0u, "Unsize on type that doesn't implement have a ?Sized field - " << dst_ty);
+ MIR_ASSERT(state, str.m_struct_markings.unsized_field != ~0u, "Unsize on type that doesn't implement have a ?Sized field - " << dst_ty);
auto monomorph_cb_d = monomorphise_type_get_cb(state.sp, nullptr, &de.path.m_data.as_Generic().m_params, nullptr);
auto monomorph_cb_s = monomorphise_type_get_cb(state.sp, nullptr, &se.path.m_data.as_Generic().m_params, nullptr);
@@ -578,14 +578,14 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
MIR_BUG(state, "Unit-like struct Unsize is impossible - " << src_ty);
),
(Tuple,
- const auto& ty_tpl = se.at( str.m_markings.unsized_field ).ent;
+ const auto& ty_tpl = se.at( str.m_struct_markings.unsized_field ).ent;
auto ty_d = monomorphise_type_with(state.sp, ty_tpl, monomorph_cb_d, false);
auto ty_s = monomorphise_type_with(state.sp, ty_tpl, monomorph_cb_s, false);
return MIR_Cleanup_Unsize_GetMetadata(state, mutator, ty_d, ty_s, ptr_value, out_meta_val,out_meta_ty,out_src_is_dst);
),
(Named,
- const auto& ty_tpl = se.at( str.m_markings.unsized_field ).second.ent;
+ const auto& ty_tpl = se.at( str.m_struct_markings.unsized_field ).second.ent;
auto ty_d = monomorphise_type_with(state.sp, ty_tpl, monomorph_cb_d, false);
auto ty_s = monomorphise_type_with(state.sp, ty_tpl, monomorph_cb_s, false);
@@ -720,7 +720,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
MIR_ASSERT(state, dte.binding.as_Struct() == ste.binding.as_Struct(),
"Note, can't CoerceUnsized mismatched structs - " << src_ty << " to " << dst_ty);
const auto& str = *dte.binding.as_Struct();
- MIR_ASSERT(state, str.m_markings.coerce_unsized_index != ~0u,
+ MIR_ASSERT(state, str.m_struct_markings.coerce_unsized_index != ~0u,
"Struct " << src_ty << " doesn't impl CoerceUnsized");
auto monomorph_cb_d = monomorphise_type_get_cb(state.sp, nullptr, &dte.path.m_data.as_Generic().m_params, nullptr);
@@ -736,7 +736,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
ents.reserve( se.size() );
for(unsigned int i = 0; i < se.size(); i++)
{
- if( i == str.m_markings.coerce_unsized_index )
+ if( i == str.m_struct_markings.coerce_unsized_index )
{
auto ty_d = monomorphise_type_with(state.sp, se[i].ent, monomorph_cb_d, false);
auto ty_s = monomorphise_type_with(state.sp, se[i].ent, monomorph_cb_s, false);
@@ -765,7 +765,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
ents.reserve( se.size() );
for(unsigned int i = 0; i < se.size(); i++)
{
- if( i == str.m_markings.coerce_unsized_index )
+ if( i == str.m_struct_markings.coerce_unsized_index )
{
auto ty_d = monomorphise_type_with(state.sp, se[i].second.ent, monomorph_cb_d, false);
auto ty_s = monomorphise_type_with(state.sp, se[i].second.ent, monomorph_cb_s, false);
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index ca91bef4..4cd3b7f6 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -4302,39 +4302,44 @@ namespace {
}
else if( ty.m_data.is_Path() )
{
- const ::HIR::TraitMarkings* markings;
TU_MATCH_DEF( ::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (tpb),
(
MIR_BUG(*m_mir_res, "Unbound/opaque path in trans - " << ty);
+ throw "";
),
- (Struct, markings = &tpb->m_markings; ),
- (Union, markings = &tpb->m_markings; ),
- (Enum, markings = &tpb->m_markings; )
- )
- switch( markings->dst_type )
- {
- case ::HIR::TraitMarkings::DstType::None:
+ (Struct,
+ switch( tpb->m_struct_markings.dst_type )
+ {
+ case ::HIR::StructMarkings::DstType::None:
+ return ::HIR::TypeRef();
+ case ::HIR::StructMarkings::DstType::Slice:
+ case ::HIR::StructMarkings::DstType::TraitObject:
+ case ::HIR::StructMarkings::DstType::Possible: {
+ // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only)
+ const auto& path = ty.m_data.as_Path().path.m_data.as_Generic();
+ const auto& str = *ty.m_data.as_Path().binding.as_Struct();
+ auto monomorph = [&](const auto& tpl) {
+ // TODO: expand_associated_types
+ auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl);
+ m_resolve.expand_associated_types(sp, rv);
+ return rv;
+ };
+ TU_MATCHA( (str.m_data), (se),
+ (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ),
+ (Tuple, return get_inner_unsized_type( monomorph(se.back().ent) ); ),
+ (Named, return get_inner_unsized_type( monomorph(se.back().second.ent) ); )
+ )
+ throw "";
+ }
+ }
+ ),
+ (Union,
+ return ::HIR::TypeRef();
+ ),
+ (Enum,
return ::HIR::TypeRef();
- case ::HIR::TraitMarkings::DstType::Slice:
- case ::HIR::TraitMarkings::DstType::TraitObject:
- case ::HIR::TraitMarkings::DstType::Possible: {
- // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only)
- const auto& path = ty.m_data.as_Path().path.m_data.as_Generic();
- const auto& str = *ty.m_data.as_Path().binding.as_Struct();
- auto monomorph = [&](const auto& tpl) {
- // TODO: expand_associated_types
- auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl);
- m_resolve.expand_associated_types(sp, rv);
- return rv;
- };
- TU_MATCHA( (str.m_data), (se),
- (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ),
- (Tuple, return get_inner_unsized_type( monomorph(se.back().ent) ); ),
- (Named, return get_inner_unsized_type( monomorph(se.back().second.ent) ); )
)
- throw "";
- }
- }
+ )
throw "";
}
else
@@ -4353,41 +4358,45 @@ namespace {
}
else if( ty.m_data.is_Path() )
{
- const ::HIR::TraitMarkings* markings;
TU_MATCH_DEF( ::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (tpb),
(
MIR_BUG(*m_mir_res, "Unbound/opaque path in trans - " << ty);
),
- (Struct, markings = &tpb->m_markings; ),
- (Union, markings = &tpb->m_markings; ),
- (Enum, markings = &tpb->m_markings; )
- )
- switch( markings->dst_type )
- {
- case ::HIR::TraitMarkings::DstType::None:
+ (Struct,
+ switch( tpb->m_struct_markings.dst_type )
+ {
+ case ::HIR::StructMarkings::DstType::None:
+ return MetadataType::None;
+ case ::HIR::StructMarkings::DstType::Possible: {
+ // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only)
+ const auto& path = ty.m_data.as_Path().path.m_data.as_Generic();
+ const auto& str = *ty.m_data.as_Path().binding.as_Struct();
+ auto monomorph = [&](const auto& tpl) {
+ auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl);
+ m_resolve.expand_associated_types(sp, rv);
+ return rv;
+ };
+ TU_MATCHA( (str.m_data), (se),
+ (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ),
+ (Tuple, return metadata_type( monomorph(se.back().ent) ); ),
+ (Named, return metadata_type( monomorph(se.back().second.ent) ); )
+ )
+ //MIR_TODO(*m_mir_res, "Determine DST type when ::Possible - " << ty);
+ return MetadataType::None;
+ }
+ case ::HIR::StructMarkings::DstType::Slice:
+ return MetadataType::Slice;
+ case ::HIR::StructMarkings::DstType::TraitObject:
+ return MetadataType::TraitObject;
+ }
+ ),
+ (Union,
return MetadataType::None;
- case ::HIR::TraitMarkings::DstType::Possible: {
- // TODO: How to figure out? Lazy way is to check the monomorpised type of the last field (structs only)
- const auto& path = ty.m_data.as_Path().path.m_data.as_Generic();
- const auto& str = *ty.m_data.as_Path().binding.as_Struct();
- auto monomorph = [&](const auto& tpl) {
- auto rv = monomorphise_type(sp, str.m_params, path.m_params, tpl);
- m_resolve.expand_associated_types(sp, rv);
- return rv;
- };
- TU_MATCHA( (str.m_data), (se),
- (Unit, MIR_BUG(*m_mir_res, "Unit-like struct with DstType::Possible"); ),
- (Tuple, return metadata_type( monomorph(se.back().ent) ); ),
- (Named, return metadata_type( monomorph(se.back().second.ent) ); )
- )
- //MIR_TODO(*m_mir_res, "Determine DST type when ::Possible - " << ty);
+ ),
+ (Enum,
return MetadataType::None;
- }
- case ::HIR::TraitMarkings::DstType::Slice:
- return MetadataType::Slice;
- case ::HIR::TraitMarkings::DstType::TraitObject:
- return MetadataType::TraitObject;
- }
+ )
+ )
throw "";
}
else {