diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/from_ast.cpp | 10 | ||||
-rw-r--r-- | src/hir/type.cpp | 25 | ||||
-rw-r--r-- | src/hir/type.hpp | 3 | ||||
-rw-r--r-- | src/hir/visitor.cpp | 3 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 4 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 12 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 27 | ||||
-rw-r--r-- | src/parse/root.cpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 4 |
9 files changed, 60 insertions, 30 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 1693684f..4b52cd22 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -620,7 +620,15 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"}); ::HIR::TypeRef::Data::Data_TraitObject v; for(const auto& t : e.traits) { - v.m_traits.push_back( LowerHIR_GenericPath(ty.span(), t) ); + if( t.binding().as_Trait().trait_->is_marker() ) { + v.m_markers.push_back( LowerHIR_GenericPath(ty.span(), t) ); + } + else { + if( v.m_trait.m_path.m_components.size() > 0 ) { + ERROR(ty.span(), E0000, "Multiple data traits in trait object - " << ty); + } + v.m_trait = LowerHIR_GenericPath(ty.span(), t); + } } return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_TraitObject( mv$(v) ) ); ), diff --git a/src/hir/type.cpp b/src/hir/type.cpp index c396ad2b..f78c45ad 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -77,7 +77,9 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const ), (TraitObject, os << "("; - os << e.m_traits; + os << e.m_trait; + for(const auto& tr : e.m_markers) + os << "+" << tr; if( e.m_lifetime.name != "" ) os << "+ '" << e.m_lifetime.name; os << ")"; @@ -191,10 +193,12 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const return te.name == xe.name && te.binding == xe.binding; ), (TraitObject, - if( te.m_traits.size() != xe.m_traits.size() ) + if( te.m_trait != xe.m_trait ) return false; - for(unsigned int i = 0; i < te.m_traits.size(); i ++ ) { - if( te.m_traits[i] != xe.m_traits[i] ) + if( te.m_markers.size() != xe.m_markers.size() ) + return false; + for(unsigned int i = 0; i < te.m_markers.size(); i ++ ) { + if( te.m_markers[i] != xe.m_markers[i] ) return false; } return te.m_lifetime == xe.m_lifetime; @@ -427,13 +431,12 @@ namespace { return ::HIR::TypeRef( Data::make_Generic(e) ); ), (TraitObject, - ::std::vector< ::HIR::GenericPath> traits; - for(const auto& trait : e.m_traits) - traits.push_back( trait.clone() ); - return ::HIR::TypeRef( Data::make_TraitObject({ - mv$(traits), - e.m_lifetime - }) ); + Data::Data_TraitObject rv; + rv.m_trait = e.m_trait.clone(); + for(const auto& trait : e.m_markers) + rv.m_markers.push_back( trait.clone() ); + rv.m_lifetime = e.m_lifetime; + return ::HIR::TypeRef( Data::make_TraitObject( mv$(rv) ) ); ), (Array, if( e.size_val == ~0u ) { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 42d1323e..4f7e97a5 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -100,7 +100,8 @@ public: unsigned int binding; }), (TraitObject, struct { - ::std::vector< ::HIR::GenericPath > m_traits; + ::HIR::GenericPath m_trait; // TODO: Use TraitPath? + ::std::vector< ::HIR::GenericPath > m_markers; ::HIR::LifetimeRef m_lifetime; }), (Array, struct { diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 2d879d7f..a2432971 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -273,7 +273,8 @@ void ::HIR::Visitor::visit_type(::HIR::TypeRef& ty) (Generic, ), (TraitObject, - for(auto& trait : e.m_traits) { + this->visit_generic_path(e.m_trait, ::HIR::Visitor::PathContext::TYPE); + for(auto& trait : e.m_markers) { this->visit_generic_path(trait, ::HIR::Visitor::PathContext::TYPE); } ), diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 6608f230..6581911c 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -214,9 +214,7 @@ namespace { e.binding = ::HIR::TypeRef::TypePathBinding::make_Enum(&e3); ), (Trait, - ::std::vector< ::HIR::GenericPath> traits; - traits.push_back( mv$(e2) ); - ty.m_data = ::HIR::TypeRef::Data::make_TraitObject({ mv$(traits), {} }); + ty.m_data = ::HIR::TypeRef::Data::make_TraitObject({ mv$(e2), {}, {} }); ) ) ) diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index fac27f03..ee29d1c0 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -56,9 +56,10 @@ namespace typeck { return true; ), (TraitObject, - for(const auto& trait : e.m_traits) - if( monomorphise_pathparams_needed(trait.m_params) ) return false; - return true; + if( monomorphise_pathparams_needed(e.m_trait.m_params) ) return true; + for(const auto& trait : e.m_markers) + if( monomorphise_pathparams_needed(trait.m_params) ) return true; + return false; ), (Array, TODO(Span(), "Array - " << tpl); @@ -144,9 +145,10 @@ namespace typeck { ), (TraitObject, ::HIR::TypeRef::Data::Data_TraitObject rv; - for(const auto& trait : e.m_traits) + rv.m_trait = monomorphise_genericpath_with(sp, e.m_trait, callback, allow_infer); + for(const auto& trait : e.m_markers) { - rv.m_traits.push_back( monomorphise_genericpath_with(sp, trait, callback, allow_infer) ); + rv.m_markers.push_back( monomorphise_genericpath_with(sp, trait, callback, allow_infer) ); } rv.m_lifetime = e.m_lifetime; return ::HIR::TypeRef( mv$(rv) ); diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp index df1300a7..93a0748d 100644 --- a/src/hir_typeck/expr_context.cpp +++ b/src/hir_typeck/expr_context.cpp @@ -789,21 +789,25 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR } ), (TraitObject, - if( l_e.m_traits.size() != r_e.m_traits.size() ) { - // TODO: Possibly allow inferrence reducing the set? + if( l_e.m_trait.m_path != r_e.m_trait.m_path ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t); + } + equality_typeparams(l_e.m_trait.m_params, r_e.m_trait.m_params); + // TODO: Possibly allow inferrence reducing the set? + if( l_e.m_markers.size() != r_e.m_markers.size() ) { ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - trait counts differ"); } - // NOTE: Lifetime is ignored // TODO: Is this list sorted in any way? (if it's not sorted, this could fail when source does Send+Any instead of Any+Send) - for(unsigned int i = 0; i < l_e.m_traits.size(); i ++ ) + for(unsigned int i = 0; i < l_e.m_markers.size(); i ++ ) { - auto& l_p = l_e.m_traits[i]; - auto& r_p = r_e.m_traits[i]; + auto& l_p = l_e.m_markers[i]; + auto& r_p = r_e.m_markers[i]; if( l_p.m_path != r_p.m_path ) { ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t); } equality_typeparams(l_p.m_params, r_p.m_params); } + // NOTE: Lifetime is ignored ), (Array, this->apply_equality(sp, *l_e.inner, cb_left, *r_e.inner, cb_right, nullptr); @@ -851,6 +855,17 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR return ; } // - If left is a trait object, right can unsize + if( left_inner_res.m_data.is_TraitObject() ) { + if( right_inner_res.m_data.is_TraitObject() ) { + // TODO: Can Debug+Send be coerced to Debug? + if( left_inner_res != right_inner_res ) + ERROR(sp, E0000, "Can't coerce between trait objects - " << left_inner_res << " and " << right_inner_res); + // - Equal, nothing to do + return ; + } + + TODO(sp, "Unsize into trait object - " << l_t << " <- " << r_t); + } // - If left is a slice, right can unsize/deref if( left_inner_res.m_data.is_Slice() && !right_inner_res.m_data.is_Slice() ) { diff --git a/src/parse/root.cpp b/src/parse/root.cpp index a64105c7..1e57227e 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -906,7 +906,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i if( GET_TOK(tok, lex) == TOK_DOUBLE_DOT )
{
// Default impl
- impl_type = TypeRef();
+ impl_type = TypeRef(TypeRef::TagInvalid(), lex.getPosition());
}
else
{
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 4bb3c51d..84a6b191 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1370,8 +1370,10 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) for(auto& impl : mod.impls()) { auto& def = impl.def(); - if( ! def.type().is_valid() ) + DEBUG("impl " << def.trait().ent << " for " << def.type()); + if( !def.type().is_valid() ) { + DEBUG("---- MARKER IMPL for " << def.trait().ent); item_context.push(def.params(), GenericSlot::Level::Top); Resolve_Absolute_Generic(item_context, def.params()); assert( def.trait().ent.is_valid() ); |