diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 40 | ||||
-rw-r--r-- | src/ast/ast.hpp | 31 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 2 | ||||
-rw-r--r-- | src/expand/derive.cpp | 8 | ||||
-rw-r--r-- | src/expand/mod.cpp | 14 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 8 | ||||
-rw-r--r-- | src/parse/root.cpp | 26 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 54 | ||||
-rw-r--r-- | src/resolve/use.cpp | 2 |
9 files changed, 99 insertions, 86 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 00c4b39b..1da79f33 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -103,18 +103,18 @@ SERIALISE_TYPE(ImplDef::, "AST_ImplDef", { s.item(m_type);
})
-void Impl::add_function(bool is_public, ::std::string name, Function fcn)
+void Impl::add_function(bool is_public, bool is_specialisable, ::std::string name, Function fcn)
{
DEBUG("impl fn " << name);
- m_items.push_back( Named<Item>( mv$(name), Item::make_Function({::std::move(fcn)}), is_public ) );
+ m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Function(mv$(fcn)) ) } );
}
-void Impl::add_type(bool is_public, ::std::string name, TypeRef type)
+void Impl::add_type(bool is_public, bool is_specialisable, ::std::string name, TypeRef type)
{
- m_items.push_back( Named<Item>( mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), is_public ) );
+ m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Type(TypeAlias(GenericParams(), mv$(type))) ) } );
}
-void Impl::add_static(bool is_public, ::std::string name, Static v)
+void Impl::add_static(bool is_public, bool is_specialisable, ::std::string name, Static v)
{
- m_items.push_back( Named<Item>( mv$(name), Item::make_Static({mv$(v)}), is_public ) );
+ m_items.push_back( ImplItem { is_public, is_specialisable, mv$(name), box$( Item::make_Static(mv$(v)) ) } );
}
bool Impl::has_named_item(const ::std::string& name) const
@@ -128,42 +128,14 @@ bool Impl::has_named_item(const ::std::string& name) const return false;
}
-Impl& Impl::get_concrete(const ::std::vector<TypeRef>& param_types)
-{
- if( param_types.size() > 0 )
- {
- for( auto& i : m_concrete_impls )
- {
- if( i.first == param_types )
- {
- return i.second;
- }
- }
-
- m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) );
- return m_concrete_impls.back().second;
- }
- else
- {
- return *this;
- }
-}
-
-Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const
-{
- throw ParseError::Todo("Impl::make_concrete");
-}
-
::std::ostream& operator<<(::std::ostream& os, const Impl& impl)
{
return os << impl.m_def;
}
SERIALISE_TYPE(Impl::, "AST_Impl", {
s << m_def;
- s << m_items;
},{
s.item(m_def);
- s.item(m_items);
})
::rust::option<char> ImplRef::find_named_item(const ::std::string& name) const
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index d57d6693..02e9c5f2 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -407,15 +407,24 @@ public: class Impl:
public Serialisable
{
+public:
+ struct ImplItem {
+ bool is_pub; // Ignored for trait impls
+ bool is_specialisable;
+ ::std::string name;
+
+ ::std::unique_ptr<Item> data;
+ };
+
+private:
ImplDef m_def;
Span m_span;
- NamedList<Item> m_items;
+ ::std::vector< ImplItem > m_items;
//NamedList<TypeRef> m_types;
//NamedList<Function> m_functions;
//NamedList<Static> m_statics;
- ::std::vector< ::std::pair< ::std::vector<TypeRef>, Impl > > m_concrete_impls;
public:
::std::vector<MacroInvocation> m_macro_invocations;
@@ -426,30 +435,24 @@ public: {}
Impl& operator=(Impl&&) = default;
- void add_function(bool is_public, ::std::string name, Function fcn);
- void add_type(bool is_public, ::std::string name, TypeRef type);
- void add_static(bool is_public, ::std::string name, Static v);
+ void add_function(bool is_public, bool is_specialisable, ::std::string name, Function fcn);
+ void add_type(bool is_public, bool is_specialisable, ::std::string name, TypeRef type);
+ void add_static(bool is_public, bool is_specialisable, ::std::string name, Static v);
void add_macro_invocation( MacroInvocation inv ) {
m_macro_invocations.push_back( mv$(inv) );
}
const ImplDef& def() const { return m_def; }
- const NamedList<Item>& items() const { return m_items; }
-
- ImplDef& def() { return m_def; }
- NamedList<Item>& items() { return m_items; }
+ ImplDef& def() { return m_def; }
+ const ::std::vector<ImplItem>& items() const { return m_items; }
+ ::std::vector<ImplItem>& items() { return m_items; }
bool has_named_item(const ::std::string& name) const;
- /// Obtain a concrete implementation based on the provided types (caches)
- Impl& get_concrete(const ::std::vector<TypeRef>& param_types);
-
friend ::std::ostream& operator<<(::std::ostream& os, const Impl& impl);
SERIALISABLE_PROTOTYPES();
private:
- /// Actually create a concrete impl
- Impl make_concrete(const ::std::vector<TypeRef>& types) const;
};
struct UseStmt:
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index abad2938..191366fa 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -682,7 +682,7 @@ void RustPrinter::handle_module(const AST::Module& mod) inc_indent(); for( const auto& it : i.items() ) { - TU_MATCH_DEF(AST::Item, (it.data), (e), + TU_MATCH_DEF(AST::Item, (*it.data), (e), ( throw ::std::runtime_error("Unexpected item type in impl block"); ), diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index e50d881b..5f4a1a10 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -66,7 +66,7 @@ class Deriver_Debug: fcn.set_code( NEWNODE(AST::ExprNode_Block, vec$(mv$(node)), ::std::unique_ptr<AST::Module>()) ); AST::Impl rv( AST::ImplDef( sp, AST::MetaItems(), p, make_spanned(sp, debug_trait), type ) ); - rv.add_function(false, "fmt", mv$(fcn)); + rv.add_function(false, false, "fmt", mv$(fcn)); return mv$(rv); } @@ -169,7 +169,7 @@ class Deriver_PartialEq: } AST::Impl rv( AST::ImplDef( sp, AST::MetaItems(), mv$(params), make_spanned(sp, trait_path), type ) ); - rv.add_function(false, "eq", mv$(fcn)); + rv.add_function(false, false, "eq", mv$(fcn)); return mv$(rv); } public: @@ -345,7 +345,7 @@ class Deriver_Eq: } AST::Impl rv( AST::ImplDef( sp, AST::MetaItems(), mv$(params), make_spanned(sp, trait_path), type ) ); - rv.add_function(false, "assert_receiver_is_total_eq", mv$(fcn)); + rv.add_function(false, false, "assert_receiver_is_total_eq", mv$(fcn)); return mv$(rv); } AST::ExprNodeP assert_is_eq(const AST::Path& method_path, AST::ExprNodeP val) const { @@ -485,7 +485,7 @@ class Deriver_Clone: } AST::Impl rv( AST::ImplDef( sp, AST::MetaItems(), mv$(params), make_spanned(sp, trait_path), type ) ); - rv.add_function(false, "clone", mv$(fcn)); + rv.add_function(false, false, "clone", mv$(fcn)); return mv$(rv); } AST::ExprNodeP clone_val(AST::ExprNodeP val) const { diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 617a2fc9..54987d01 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -768,16 +768,16 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo DEBUG("> Items"); for( auto& i : impl.items() ) { - DEBUG(" - " << i.name << " :: " << i.data.attrs); + DEBUG(" - " << i.name << " :: " << i.data->attrs); // TODO: Make a path from the impl definition? Requires having the impl def resolved to be correct // - Does it? the namespace is essentially the same. There may be issues with wherever the path is used though //::AST::Path path = modpath + i.name; - auto attrs = mv$(i.data.attrs); - Expand_Attrs(attrs, stage_pre(is_early), crate, AST::Path(), mod, i.data); + auto attrs = mv$(i.data->attrs); + Expand_Attrs(attrs, stage_pre(is_early), crate, AST::Path(), mod, *i.data); - TU_MATCH_DEF(AST::Item, (i.data), (e), + TU_MATCH_DEF(AST::Item, (*i.data), (e), ( throw ::std::runtime_error("BUG: Unknown item type in impl block"); ), @@ -798,9 +798,9 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo ) ) - Expand_Attrs(attrs, stage_post(is_early), crate, AST::Path(), mod, i.data); - if( i.data.attrs.m_items.size() == 0 ) - i.data.attrs = mv$(attrs); + Expand_Attrs(attrs, stage_post(is_early), crate, AST::Path(), mod, *i.data); + if( i.data->attrs.m_items.size() == 0 ) + i.data->attrs = mv$(attrs); } Expand_Attrs(impl.def().attrs(), stage_post(is_early), crate, mod, impl.def()); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 540a362c..30b23900 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -975,9 +975,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat for(const auto& item : impl.items()) { - TU_MATCH_DEF(::AST::Item, (item.data), (e), + TU_MATCH_DEF(::AST::Item, (*item.data), (e), ( - ERROR(item.data.span, E0000, "Unexpected item type in trait impl"); + ERROR(item.data->span, E0000, "Unexpected item type in trait impl"); ), // TODO: Associated constants (Type, @@ -1009,9 +1009,9 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat for(const auto& item : impl.items()) { - TU_MATCH_DEF(::AST::Item, (item.data), (e), + TU_MATCH_DEF(::AST::Item, (*item.data), (e), ( - ERROR(item.data.span, E0000, "Unexpected item type in inherent impl"); + ERROR(item.data->span, E0000, "Unexpected item type in inherent impl"); ), (Function, methods.insert( ::std::make_pair(item.name, LowerHIR_Function(e)) ); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 9ae8a628..87d1e9c3 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -996,8 +996,6 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) is_specialisable = true;
GET_TOK(tok, lex);
}
- // TODO: Mark specialisation
- (void)is_specialisable;
if(tok.type() == TOK_RWORD_UNSAFE) {
item_attrs.push_back( AST::MetaItem("#UNSAFE") );
@@ -1011,7 +1009,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- impl.add_type(is_public, name, Parse_Type(lex));
+ impl.add_type(is_public, is_specialisable, name, Parse_Type(lex));
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
break; }
case TOK_RWORD_CONST:
@@ -1028,7 +1026,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) auto i = ::AST::Static(AST::Static::CONST, mv$(ty), mv$(val));
// TODO: Attributes on associated constants
- impl.add_static( is_public, mv$(name), mv$(i) /*, mv$(item_attrs)*/ );
+ impl.add_static( is_public, is_specialisable, mv$(name), mv$(i) /*, mv$(item_attrs)*/ );
break ;
}
else if( tok.type() == TOK_RWORD_UNSAFE )
@@ -1059,29 +1057,15 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl) DEBUG("Function " << name);
// - Self allowed, can't be prototype-form
auto fcn = Parse_FunctionDefWithCode(lex, abi, item_attrs, true);
- impl.add_function(is_public, ::std::move(name), mv$(fcn));
+ impl.add_function(is_public, is_specialisable, mv$(name), mv$(fcn));
break; }
-
- case TOK_IDENT:
- if( tok.str() == "default" ) {
- // TODO: Mark `default` functions as default (i.e. specialisable)
- GET_CHECK_TOK(tok, lex, TOK_RWORD_FN);
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- // - Self allowed, can't be prototype-form
- auto fcn = Parse_FunctionDefWithCode(lex, abi, item_attrs, true);
- impl.add_function(is_public, ::std::move(name), mv$(fcn));
- }
- else {
- throw ParseError::Unexpected(lex, tok);
- }
- break;
default:
throw ParseError::Unexpected(lex, tok);
}
- impl.items().back().data.span = lex.end_span(ps);
+ impl.items().back().data->span = lex.end_span(ps);
+ impl.items().back().data->attrs = mv$(item_attrs); // Empty for functions
}
void Parse_ExternBlock(TokenStream& lex, AST::Module& mod, ::std::string abi, ::AST::MetaItems block_attrs)
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 34255e99..a21c9b10 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -1280,6 +1280,60 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: } } +void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Impl::ImplItem >& items) +{ + TRACE_FUNCTION_F(""); + for(auto& i : items) + { + TU_MATCH(AST::Item, (*i.data), (e), + (None, ), + (Module, BUG(i.data->span, "Resolve_Absolute_ImplItems - Module");), + (Crate , BUG(i.data->span, "Resolve_Absolute_ImplItems - Crate");), + (Enum , BUG(i.data->span, "Resolve_Absolute_ImplItems - Enum");), + (Trait , BUG(i.data->span, "Resolve_Absolute_ImplItems - Trait");), + (Struct, BUG(i.data->span, "Resolve_Absolute_ImplItems - Struct");), + (Type, + DEBUG("Type - " << i.name); + assert( e.params().ty_params().size() == 0 ); + assert( e.params().lft_params().size() == 0 ); + item_context.push( e.params(), GenericSlot::Level::Method, true ); + Resolve_Absolute_Generic(item_context, e.params()); + + Resolve_Absolute_Type( item_context, e.type() ); + + item_context.pop( e.params(), true ); + ), + (Function, + DEBUG("Function - " << i.name); + item_context.push( e.params(), GenericSlot::Level::Method ); + Resolve_Absolute_Generic(item_context, e.params()); + + Resolve_Absolute_Type( item_context, e.rettype() ); + for(auto& arg : e.args()) + Resolve_Absolute_Type( item_context, arg.second ); + + { + auto _h = item_context.enter_rootblock(); + item_context.push_block(); + for(auto& arg : e.args()) { + Resolve_Absolute_Pattern( item_context, false, arg.first ); + } + + Resolve_Absolute_Expr( item_context, e.code() ); + + item_context.pop_block(); + } + + item_context.pop( e.params() ); + ), + (Static, + DEBUG("Static - " << i.name); + TODO(i.data->span, "Resolve_Absolute_ImplItems - Static"); + ) + ) + } +} + void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod) { Resolve_Absolute_Mod( Context { crate, mod }, mod ); } diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 2ebdc058..361cca76 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -162,7 +162,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path { for(auto& i : im.items()) { - TU_MATCH_DEF( AST::Item, (i.data), (e), + TU_MATCH_DEF( AST::Item, (*i.data), (e), ( ), (Function, |