diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 32 | ||||
-rw-r--r-- | src/ast/ast.hpp | 39 | ||||
-rw-r--r-- | src/expand/derive.cpp | 4 | ||||
-rw-r--r-- | src/hir/expr.hpp | 1 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 18 | ||||
-rw-r--r-- | src/hir/hir.hpp | 11 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 50 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 2 | ||||
-rw-r--r-- | src/parse/root.cpp | 3 |
10 files changed, 109 insertions, 54 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index b9394702..29ddf07f 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -302,6 +302,38 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves }
+Function::Function(Span sp, GenericParams params, TypeRef ret_type, Arglist args):
+ m_span(sp),
+ m_params( move(params) ),
+ m_rettype( move(ret_type) ),
+ m_args( move(args) )
+{
+ if( m_args.size() > 0 && m_args.front().first.binding().m_name == "self" ) {
+ const auto& ty = m_args.front().second;
+ TU_MATCH_DEF( ::TypeData, (ty.m_data), (e),
+ (
+ // Whups!
+ ERROR(sp, E0000, "Invalid receiver type - " << ty);
+ ),
+ (Borrow,
+ if(e.is_mut) {
+ m_receiver = Receiver::BorrowUnique;
+ }
+ else {
+ m_receiver = Receiver::BorrowShared;
+ }
+ ),
+ // NOTE: This only applies for `self/&self/&mut self` syntax, NOT the `self: Self` syntax
+ (Generic,
+ if( e.index != 0xFFFF ) {
+ ERROR(sp, E0000, "Invalid receiver type - " << ty);
+ }
+ m_receiver = Receiver::Value;
+ )
+ )
+ }
+}
+
void Trait::add_type(::std::string name, TypeRef type) {
m_items.push_back( Named<Item>(mv$(name), Item::make_Type({TypeAlias(GenericParams(), mv$(type))}), true) );
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 93b68604..b5fd07ea 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -147,38 +147,49 @@ class Function {
public:
typedef ::std::vector< ::std::pair<AST::Pattern,TypeRef> > Arglist;
+
+ enum class Receiver {
+ Free,
+ Value,
+ BorrowOwned,
+ BorrowUnique,
+ BorrowShared,
+ //RawMut,
+ //RawConst,
+ //Box,
+ };
private:
- ::std::string m_lifetime;
+ Span m_span;
+ //::std::string m_lifetime;
+ Receiver m_receiver;
GenericParams m_params;
Expr m_code;
TypeRef m_rettype;
Arglist m_args;
public:
- Function()
+ Function():
+ m_receiver(Receiver::Free)
{}
Function(const Function&) = delete;
- Function(Function&&) noexcept = default;
+ Function& operator=(const Function&) = delete;
+ Function(Function&&) = default;
Function& operator=(Function&&) = default;
- Function(GenericParams params, TypeRef ret_type, Arglist args):
- m_params( move(params) ),
- m_rettype( move(ret_type) ),
- m_args( move(args) )
- {
- }
+ Function(Span sp, GenericParams params, TypeRef ret_type, Arglist args);
void set_code(Expr code) { m_code = ::std::move(code); }
- void set_self_lifetime(::std::string s) { m_lifetime = s; }
const GenericParams& params() const { return m_params; }
+ GenericParams& params() { return m_params; }
const Expr& code() const { return m_code; }
+ Expr& code() { return m_code; }
const TypeRef& rettype() const { return m_rettype; }
+ TypeRef& rettype() { return m_rettype; }
const Arglist& args() const { return m_args; }
+ Arglist& args() { return m_args; }
+
+ Receiver receiver() const { return m_receiver; }
- GenericParams& params() { return m_params; }
- Expr& code() { return m_code; }
- TypeRef& rettype() { return m_rettype; }
- Arglist& args() { return m_args; }
};
class Trait
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 310ad104..09fd4bbc 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -234,6 +234,7 @@ class Deriver_Debug: DEBUG("node = " << *node); AST::Function fcn( + sp, AST::GenericParams(), ret_type, vec$( @@ -409,6 +410,7 @@ class Deriver_PartialEq: const AST::Path trait_path("", { AST::PathNode("cmp", {}), AST::PathNode("PartialEq", {}) }); AST::Function fcn( + sp, AST::GenericParams(), TypeRef(sp, CORETYPE_BOOL), vec$( @@ -591,6 +593,7 @@ class Deriver_Eq: const AST::Path trait_path = this->get_trait_path(); AST::Function fcn( + sp, AST::GenericParams(), TypeRef(TypeRef::TagUnit(), sp), vec$( @@ -727,6 +730,7 @@ class Deriver_Clone: const AST::Path trait_path = this->get_trait_path(); AST::Function fcn( + sp, AST::GenericParams(), TypeRef("Self", 0xFFFF), vec$( diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 4b385c99..3a7839a8 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -416,6 +416,7 @@ struct ExprCallCache ::std::vector< ::HIR::TypeRef> m_arg_types; const ::HIR::GenericParams* m_fcn_params; const ::HIR::GenericParams* m_top_params; + const ::HIR::Function* m_fcn; ::HIR::PathParams m_ty_impl_params; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 4fe9759c..6a43b790 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -891,13 +891,31 @@ namespace { } ::HIR::Function LowerHIR_Function(::HIR::ItemPath p, const ::AST::Function& f) { + static Span sp; + DEBUG(p); ::std::vector< ::std::pair< ::HIR::Pattern, ::HIR::TypeRef > > args; for(const auto& arg : f.args()) args.push_back( ::std::make_pair( LowerHIR_Pattern(arg.first), LowerHIR_Type(arg.second) ) ); + auto receiver = ::HIR::Function::Receiver::Free; + + switch( f.receiver() ) + { + #define _(N) case ::AST::Function::Receiver::N: receiver = ::HIR::Function::Receiver::N; break; + _(Free) + _(Value) + _(BorrowOwned) + _(BorrowUnique) + _(BorrowShared) + //case ::AST::Function::Receiver::Box: + // break; + #undef _ + } + // TODO: ABI and unsafety/constness return ::HIR::Function { + receiver, "rust", false, false, LowerHIR_GenericParams(f.params(), nullptr), // TODO: If this is a method, then it can add the Self: Sized bound mv$(args), diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 2eaf508d..d2a3631b 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -76,6 +76,17 @@ struct Constant class Function { public: + enum class Receiver { + Free, + Value, + BorrowOwned, + BorrowUnique, + BorrowShared, + //PointerMut, + //PointerConst, + }; + + Receiver m_receiver; ::std::string m_abi; bool m_unsafe; bool m_const; diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index 03b5e8f2..a6246a2c 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -166,6 +166,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call_once"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + ::HIR::Function::Receiver::Value, "rust", false, false, {}, make_vec2( @@ -197,6 +198,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call_mut"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + ::HIR::Function::Receiver::BorrowUnique, "rust", false, false, {}, make_vec2( @@ -229,6 +231,7 @@ namespace { mv$(params), mv$(trait_params), mv$(closure_type), make_map1( ::std::string("call"), ::HIR::TraitImpl::ImplEnt< ::HIR::Function> { false, ::HIR::Function { + ::HIR::Function::Receiver::BorrowShared, "rust", false, false, {}, make_vec2( diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index b0ff5b9d..53bab500 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -297,6 +297,7 @@ namespace { ) assert( fcn_ptr ); + cache.m_fcn = fcn_ptr; const auto& fcn = *fcn_ptr; // --- Monomorphise the argument/return types (into current context) @@ -1870,55 +1871,26 @@ namespace { // Autoref { - // TODO: Get the receiver type without Self having been expanded. - // - Or some other indication of how Self is being taken - const auto& receiver_type = node.m_cache.m_arg_types.front(); - enum class Receiver { - Unknown, - Value, - Shared, - Unique, - Owned, - //Box, - } receiver_class = Receiver::Unknown; - if( this->context.m_ivars.types_equal(receiver_type, node.m_value->m_res_type) ) { - receiver_class = Receiver::Value; - } - else TU_IFLET(::HIR::TypeRef::Data, receiver_type.m_data, Borrow, e, - if( this->context.m_ivars.types_equal(*e.inner, node.m_value->m_res_type) ) { - switch(e.type) - { - case ::HIR::BorrowType::Shared: receiver_class = Receiver::Shared; break; - case ::HIR::BorrowType::Unique: receiver_class = Receiver::Unique; break; - case ::HIR::BorrowType::Owned : receiver_class = Receiver::Owned ; break; - } - } - else { - receiver_class = Receiver::Unknown; - } - ) - else { - receiver_class = Receiver::Unknown; - } + auto receiver_class = node.m_cache.m_fcn->m_receiver; auto& node_ptr = node.m_value; auto span = node_ptr->span(); switch(receiver_class) { - case Receiver::Unknown: - BUG(sp, "Unknown receiver type - " << receiver_type << ", Self = " << node.m_value->m_res_type); - case Receiver::Value: + case ::HIR::Function::Receiver::Free: + BUG(sp, "Method call resolved to a free function - " << node.m_method_path); + case ::HIR::Function::Receiver::Value: // by value - nothing needs to be added break; - case Receiver::Shared: - case Receiver::Unique: - case Receiver::Owned: { + case ::HIR::Function::Receiver::BorrowShared: + case ::HIR::Function::Receiver::BorrowUnique: + case ::HIR::Function::Receiver::BorrowOwned: { ::HIR::BorrowType bt; switch(receiver_class) { - case Receiver::Shared: bt = ::HIR::BorrowType::Shared; break; - case Receiver::Unique: bt = ::HIR::BorrowType::Unique; break; - case Receiver::Owned: TODO(sp, "Construct &move uni-op"); + case ::HIR::Function::Receiver::BorrowShared: bt = ::HIR::BorrowType::Shared; break; + case ::HIR::Function::Receiver::BorrowUnique: bt = ::HIR::BorrowType::Unique; break; + case ::HIR::Function::Receiver::BorrowOwned: bt = ::HIR::BorrowType::Owned; break; default: throw ""; } // - Add correct borrow operation diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index d04d108a..24c83296 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -2106,6 +2106,7 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait if( !this->trait_contains_method(sp, e.trait.m_path, *e.trait.m_trait_ptr, method_name, final_trait_path) ) continue ; DEBUG("- Found trait " << final_trait_path); + // TODO: Check that the receiver isn't by-value if `allow_move` is false // Found the method, return the UFCS path for it fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({ @@ -2130,6 +2131,7 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait if( it->second.is_Function() ) { const auto& v = it->second.as_Function(); if( v.m_args.size() > 0 && v.m_args[0].first.m_binding.m_name == "self" ) { + // TODO: Check that the receiver isn't by-value if `allow_move` is false fcn_path = ::HIR::Path( ::HIR::Path::Data::Data_UfcsKnown({ box$( ty.clone() ), e.m_trait.m_path.clone(), diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 1ee1a13d..dfc8a1d9 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -233,6 +233,7 @@ void Parse_WhereClause(TokenStream& lex, AST::GenericParams& params) AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaItems& attrs, bool allow_self, bool can_be_prototype)
{
TRACE_FUNCTION;
+ ProtoSpan ps = lex.start_span();
Token tok;
@@ -387,7 +388,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt PUTBACK(tok, lex);
}
- return AST::Function(::std::move(params), ::std::move(ret_type), ::std::move(args));
+ return AST::Function(lex.end_span(ps), mv$(params), mv$(ret_type), mv$(args));
}
AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems& attrs, bool allow_self)
|