summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/from_ast.cpp10
-rw-r--r--src/hir/type.cpp25
-rw-r--r--src/hir/type.hpp3
-rw-r--r--src/hir/visitor.cpp3
-rw-r--r--src/hir_conv/bind.cpp4
-rw-r--r--src/hir_typeck/expr.cpp12
-rw-r--r--src/hir_typeck/expr_context.cpp27
-rw-r--r--src/parse/root.cpp2
-rw-r--r--src/resolve/absolute.cpp4
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() );