diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-07-25 19:04:36 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-07-25 19:04:36 +0800 |
commit | cece72809d4c70debea23fd832e4830d334f52d6 (patch) | |
tree | e7c98c7506f49f2fc5cb311eb8c7f849ece64e72 | |
parent | de997426229f7d309f76b939d71f8007120631c4 (diff) | |
download | mrust-cece72809d4c70debea23fd832e4830d334f52d6.tar.gz |
HIR Typecheck - Refactor of markings to keep more information
-rw-r--r-- | src/hir/deserialise.cpp | 48 | ||||
-rw-r--r-- | src/hir/hir.hpp | 46 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 18 | ||||
-rw-r--r-- | src/hir_conv/markings.cpp | 51 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 48 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 20 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 20 | ||||
-rw-r--r-- | src/mir/check.cpp | 10 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 16 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 121 |
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 { |