diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/crate.hpp | 2 | ||||
-rw-r--r-- | src/expand/lang_item.cpp | 22 | ||||
-rw-r--r-- | src/hir/expr.hpp | 3 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 61 | ||||
-rw-r--r-- | src/hir/generic_params.cpp | 25 | ||||
-rw-r--r-- | src/hir/hir.cpp | 31 | ||||
-rw-r--r-- | src/hir/hir.hpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 141 | ||||
-rw-r--r-- | src/parse/root.cpp | 6 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 17 |
10 files changed, 240 insertions, 71 deletions
diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index 79a5d57f..24106bfa 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -19,7 +19,7 @@ public: ::AST::MetaItems m_attrs; - AST::Path m_lang_item_PhantomFn; + ::std::map< ::std::string, ::AST::Path> m_lang_items; public: Module m_root_module; ::std::map< ::std::string, ExternCrate> m_extern_crates; diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp index c34642db..6d90370a 100644 --- a/src/expand/lang_item.cpp +++ b/src/expand/lang_item.cpp @@ -11,17 +11,18 @@ #include "../ast/crate.hpp" -void handle_lang_item(AST::Crate& crate, const AST::Path& path, const ::std::string& name, AST::eItemType type) +void handle_lang_item(const Span& sp, AST::Crate& crate, const AST::Path& path, const ::std::string& name, AST::eItemType type) { if(name == "phantom_fn") { - crate.m_lang_item_PhantomFn = AST::Path(path); - crate.m_lang_item_PhantomFn.nodes().back().args().m_types = { TypeRef("A"), TypeRef("B") }; + // - Just save path } else if( name == "send" ) { // Don't care, Send is fully library in mrustc + // - Needed for `static` } else if( name == "sync" ) { // Don't care, Sync is fully library in mrustc + // - Needed for `static` } else if( name == "sized" ) { DEBUG("Bind 'sized' to " << path); @@ -90,10 +91,13 @@ void handle_lang_item(AST::Crate& crate, const AST::Path& path, const ::std::str else if( name == "str_eq" ) { } else { - throw CompileError::Generic(FMT("Unknown lang item '" << name << "'")); + ERROR(sp, E0000, "Unknown language item '" << name << "'"); } - + auto rv = crate.m_lang_items.insert( ::std::make_pair( name, ::AST::Path(path) ) ); + if( !rv.second ) { + ERROR(sp, E0000, "Duplicate definition of language item '" << name << "'"); + } } class Decorator_LangItem: @@ -108,13 +112,13 @@ public: TODO(sp, "Unknown item type with #[lang=\""<<attr<<"\"] attached at " << path); ), (Function, - handle_lang_item(crate, path, attr.string(), AST::ITEM_FN); + handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_FN); ), (Struct, - handle_lang_item(crate, path, attr.string(), AST::ITEM_STRUCT); + handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_STRUCT); ), (Trait, - handle_lang_item(crate, path, attr.string(), AST::ITEM_TRAIT); + handle_lang_item(sp, crate, path, attr.string(), AST::ITEM_TRAIT); ) ) } @@ -137,6 +141,8 @@ public: else { ERROR(sp, E0000, "Unknown lang item '" << name << "' on impl"); } + + // TODO: Somehow annotate these impls to allow them to provide inherents? } }; diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 4862651d..d50191f4 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -487,6 +487,8 @@ struct ExprNode_StructLiteral: ::HIR::ExprNodeP m_base_value; t_values m_values; + ::std::vector< ::HIR::TypeRef> m_value_types; + ExprNode_StructLiteral(Span sp, ::HIR::GenericPath path, ::HIR::ExprNodeP base_value, t_values values): ExprNode( mv$(sp) ), m_path( mv$(path) ), @@ -494,6 +496,7 @@ struct ExprNode_StructLiteral: m_values( mv$(values) ) { // TODO: set m_res_type based on path? + // - Defer, because it requires binding ivars between m_path and m_res_type } NODE_METHODS(); diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 3f297e89..1693684f 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -12,8 +12,10 @@ ::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Path& path, bool allow_final_generic = false); ::HIR::PathParams LowerHIR_PathParams(const Span& sp, const ::AST::PathParams& src_params); +const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"}); + // -------------------------------------------------------------------- -::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp) +::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp, bool* self_is_sized) { ::HIR::GenericParams rv; @@ -80,23 +82,41 @@ rv.m_bounds.push_back(::HIR::GenericBound::make_TypeEquality({ mv$(left_type), LowerHIR_Type(assoc.second) })); } + // TODO: Check for `Sized` + auto trait_path = LowerHIR_GenericPath(bound.span, e.trait); rv.m_bounds.push_back(::HIR::GenericBound::make_TraitBound({ mv$(type), ::HIR::TraitPath { mv$(trait_path), e.hrls } })); ), (MaybeTrait, if( ! e.type.m_data.is_Generic() ) BUG(bound.span, "MaybeTrait on non-param"); - const auto& param_name = e.type.m_data.as_Generic().name; - unsigned param_idx = ::std::find_if( rv.m_types.begin(), rv.m_types.end(), [&](const auto& x) { return x.m_name == param_name; } ) - rv.m_types.begin(); - if( param_idx >= rv.m_types.size() ) { - BUG(bound.span, "MaybeTrait on parameter not in parameter list"); + const auto& ge = e.type.m_data.as_Generic(); + const auto& param_name = ge.name; + unsigned param_idx; + if( ge.index == 0xFFFF ) { + if( !self_is_sized ) { + BUG(bound.span, "MaybeTrait on parameter on Self when not allowed"); + } + param_idx = 0xFFFF; + } + else { + param_idx = ::std::find_if( rv.m_types.begin(), rv.m_types.end(), [&](const auto& x) { return x.m_name == param_name; } ) - rv.m_types.begin(); + if( param_idx >= rv.m_types.size() ) { + BUG(bound.span, "MaybeTrait on parameter not in parameter list (#" << ge.index << " " << param_name << ")"); + } } // Compare with list of known default traits (just Sized atm) and set a marker - const auto path_Sized = ::HIR::SimplePath("", {"marker", "Sized"}); auto trait = LowerHIR_GenericPath(bound.span, e.trait); if( trait.m_path == path_Sized ) { - rv.m_types[param_idx].m_is_sized = false; + if( param_idx == 0xFFFF ) { + assert( self_is_sized ); + *self_is_sized = false; + } + else { + assert( param_idx < rv.m_types.size() ); + rv.m_types[param_idx].m_is_sized = false; + } } else { ERROR(bound.span, E0000, "MaybeTrait on unknown trait " << trait.m_path); @@ -627,7 +647,7 @@ ::HIR::TypeAlias LowerHIR_TypeAlias(const ::AST::TypeAlias& ta) { return ::HIR::TypeAlias { - LowerHIR_GenericParams(ta.params()), + LowerHIR_GenericParams(ta.params(), nullptr), LowerHIR_Type(ta.type()) }; } @@ -659,7 +679,7 @@ ) return ::HIR::Struct { - LowerHIR_GenericParams(ent.params()), + LowerHIR_GenericParams(ent.params(), nullptr), // TODO: Get repr from attributes ::HIR::Struct::Repr::Rust, mv$(data) @@ -697,7 +717,7 @@ } return ::HIR::Enum { - LowerHIR_GenericParams(f.params()), + LowerHIR_GenericParams(f.params(), nullptr), // TODO: Get repr from attributes ::HIR::Enum::Repr::Rust, mv$(variants) @@ -716,8 +736,9 @@ lifetime = "static"; } } + bool trait_reqires_sized = false; ::HIR::Trait rv { - LowerHIR_GenericParams(f.params()), + LowerHIR_GenericParams(f.params(), &trait_reqires_sized), mv$(lifetime), mv$(supertraits) }; @@ -739,9 +760,11 @@ BUG(item.data.span, "Encountered unexpected item type in trait"); ), (Type, + bool is_sized = true; + auto gps = LowerHIR_GenericParams(i.params(), &is_sized); rv.m_types.insert( ::std::make_pair(item.name, ::HIR::AssociatedType { - LowerHIR_GenericParams(i.params()), - LowerHIR_Type(i.type()) + mv$(gps), + LowerHIR_Type(i.type()) }) ); ), (Function, @@ -776,7 +799,7 @@ // TODO: ABI and unsafety/constness return ::HIR::Function { "rust", false, false, - LowerHIR_GenericParams(f.params()), + LowerHIR_GenericParams(f.params(), nullptr), // TODO: If this is a method, then it can add the Self: Sized bound mv$(args), LowerHIR_Type( f.rettype() ), LowerHIR_Expr( f.code() ) @@ -886,7 +909,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat // for( const auto& impl : ast_mod.impls() ) { - auto params = LowerHIR_GenericParams(impl.def().params()); + auto params = LowerHIR_GenericParams(impl.def().params(), nullptr); auto type = LowerHIR_Type(impl.def().type()); if( impl.def().trait().ent.is_valid() ) @@ -967,7 +990,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat } for( const auto& impl : ast_mod.neg_impls() ) { - auto params = LowerHIR_GenericParams(impl.params()); + auto params = LowerHIR_GenericParams(impl.params(), nullptr); auto type = LowerHIR_Type(impl.type()); auto trait = LowerHIR_GenericPath(impl.trait().sp, impl.trait().ent); auto trait_name = mv$(trait.m_path); @@ -1028,6 +1051,12 @@ public: LowerHIR_Module_Impls(crate.m_root_module, rv); + auto sp = Span(); + for( const auto& lang_item_path : crate.m_lang_items ) + { + rv.m_lang_items.insert( ::std::make_pair(lang_item_path.first, LowerHIR_SimplePath(sp, lang_item_path.second)) ); + } + // Set all pointers in the HIR to the correct (now fixed) locations IndexVisitor(rv).visit_crate( rv ); diff --git a/src/hir/generic_params.cpp b/src/hir/generic_params.cpp index b2b72148..40608cea 100644 --- a/src/hir/generic_params.cpp +++ b/src/hir/generic_params.cpp @@ -25,6 +25,31 @@ namespace HIR { } ::std::ostream& operator<<(::std::ostream& os, const ::HIR::GenericParams::PrintBounds& x) { + if( x.gp.m_bounds.size() > 0 ) + { + os << " where "; + bool comma_needed = false; + for(const auto& b : x.gp.m_bounds) + { + if(comma_needed) + os << ", "; + TU_MATCH(::HIR::GenericBound, (b), (e), + (Lifetime, + os << "'" << e.test << ": '" << e.valid_for; + ), + (TypeLifetime, + os << e.type << ": '" << e.valid_for; + ), + (TraitBound, + os << e.type << ": " << e.trait.m_path; + ), + (TypeEquality, + os << e.type << " = " << e.other_type; + ) + ) + comma_needed = true; + } + } return os; } } diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 1dce63f8..d9f85a53 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -153,33 +153,12 @@ bool ::HIR::MarkerImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_res const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path(const Span& sp, const char* name) const { - if( ::std::strcmp(name, "index") == 0 ) { - static ::HIR::SimplePath lang_index { "", {"ops", "Index"} }; - return lang_index; - } - else if( ::std::strcmp(name, "unsize") == 0 ) { - static ::HIR::SimplePath lang_unsize { "", {"marker", "Unsize"} }; - return lang_unsize; - } - else if( ::std::strcmp(name, "add") == 0 ) { - static ::HIR::SimplePath lang_path { "", {"ops", "Add"} }; - return lang_path; - } - else if( ::std::strcmp(name, "ord") == 0 ) { - static ::HIR::SimplePath lang_path { "", {"cmp", "PartialOrd"} }; - return lang_path; - } - else if( ::std::strcmp(name, "eq") == 0 ) { - static ::HIR::SimplePath lang_path { "", {"cmp", "PartialEq"} }; - return lang_path; - } - else if( ::std::strcmp(name, "fn_once") == 0 ) { - static ::HIR::SimplePath lang_path { "", {"ops", "FnOnce"} }; - return lang_path; - } - else { - ERROR(sp, E0000, "Unknown language item '" << name << "' encountered"); + // TODO: have map stored in crate populated by (or from) the #[lang] attribute handler + auto it = this->m_lang_items.find( name ); + if( it == this->m_lang_items.end() ) { + ERROR(sp, E0000, "Undefined language item '" << name << "' required"); } + return it->second; } const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index 3447aaa0..a938579a 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -263,6 +263,9 @@ public: /// Macros exported by this crate ::std::unordered_map< ::std::string, ::MacroRules > m_exported_macros; + /// Language items avaliable through this crate (includes ones from loaded externs) + ::std::unordered_map< ::std::string, ::HIR::SimplePath> m_lang_items; + const ::HIR::SimplePath& get_lang_item_path(const Span& sp, const char* name) const; const ::HIR::TypeItem& get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const; diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 9e7b4b5a..c952de4f 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -1491,6 +1491,33 @@ namespace { TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Generic, e, // No match, keep trying. ) + else if( ty.m_data.is_Path() && ty.m_data.as_Path().path.m_data.is_UfcsKnown() ) + { + const auto& e = ty.m_data.as_Path().path.m_data.as_UfcsKnown(); + // UFCS known - Assuming that it's reached the maximum resolvable level (i.e. a type within is generic), search for trait bounds on the type + const auto& trait = this->m_crate.get_trait_by_path(sp, e.trait.m_path); + const auto& assoc_ty = trait.m_types.at( e.item ); + // NOTE: The bounds here have 'Self' = the type + for(const auto& bound : assoc_ty.m_params.m_bounds ) + { + TU_IFLET(::HIR::GenericBound, bound, TraitBound, be, + assert(be.trait.m_trait_ptr); + ::HIR::GenericPath final_trait_path; + if( !this->trait_contains_method(sp, be.trait.m_path, *be.trait.m_trait_ptr, method_name, final_trait_path) ) + continue ; + DEBUG("- Found trait " << final_trait_path); + + // Found the method, return the UFCS path for it + fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({ + box$( ty.clone() ), + mv$(final_trait_path), + method_name, + {} + }) ); + return deref_count; + ) + } + } else { // 2. Search for inherent methods for(const auto& impl : m_crate.m_type_impls) @@ -1872,22 +1899,23 @@ namespace { node.m_res_type = this->context.get_var_type(node.span(), node.m_slot).clone(); } - void visit(::HIR::ExprNode_CallPath& node) override - { - TU_MATCH(::HIR::Path::Data, (node.m_path.m_data), (e), + void visit_generic_path(const Span& sp, ::HIR::GenericPath& gp) { + for(auto& ty : gp.m_params.m_types) + this->context.add_ivars(ty); + } + void visit_path(const Span& sp, ::HIR::Path& path) { + TU_MATCH(::HIR::Path::Data, (path.m_data), (e), (Generic, - for(auto& ty : e.m_params.m_types) - this->context.add_ivars(ty); + this->visit_generic_path(sp, e); ), (UfcsKnown, this->context.add_ivars(*e.type); - for(auto& ty : e.trait.m_params.m_types) - this->context.add_ivars(ty); + this->visit_generic_path(sp, e.trait); for(auto& ty : e.params.m_types) this->context.add_ivars(ty); ), (UfcsUnknown, - TODO(node.span(), "Hit a UfcsUnknown (" << node.m_path << ") - Is this an error?"); + TODO(sp, "Hit a UfcsUnknown (" << path << ") - Is this an error?"); ), (UfcsInherent, this->context.add_ivars(*e.type); @@ -1895,6 +1923,21 @@ namespace { this->context.add_ivars(ty); ) ) + } + void visit(::HIR::ExprNode_PathValue& node) override { + this->visit_path(node.span(), node.m_path); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_CallPath& node) override { + this->visit_path(node.span(), node.m_path); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_StructLiteral& node) override { + this->visit_generic_path(node.span(), node.m_path); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_TupleVariant& node) override { + this->visit_generic_path(node.span(), node.m_path); ::HIR::ExprVisitorDef::visit(node); } }; @@ -1912,7 +1955,6 @@ namespace { { } - // TODO: Add a new method called for all ExprNodeP, which will save the pointer someho void visit_node_ptr(::std::unique_ptr< ::HIR::ExprNode>& node_ptr) { m_node_ptr_ptr = &node_ptr; ::HIR::ExprVisitorDef::visit_node_ptr(node_ptr); @@ -1970,6 +2012,7 @@ namespace { void visit(::HIR::ExprNode_Assign& node) override { TRACE_FUNCTION_F("... = ..."); + // Plain assignment can't be overloaded, requires equal types if( node.m_op == ::HIR::ExprNode_Assign::Op::None ) { this->context.apply_equality(node.span(), node.m_slot->m_res_type, node.m_value->m_res_type, @@ -1977,7 +2020,39 @@ namespace { ); } else { - // TODO: Look for overload + const auto& ty_left = this->context.get_type(node.m_slot->m_res_type ); + const auto& ty_right = this->context.get_type(node.m_value->m_res_type); + + bool isprim_l = ty_left .m_data.is_Primitive() || (ty_left .m_data.is_Infer() && ty_left .m_data.as_Infer().ty_class != ::HIR::InferClass::None); + bool isprim_r = ty_right.m_data.is_Primitive() || (ty_right.m_data.is_Infer() && ty_right.m_data.as_Infer().ty_class != ::HIR::InferClass::None); + // SHORTCUT - If both sides are primitives (either confirmed or literals) + if( isprim_l && isprim_r ) { + // - The only option is for them both to be the same type (because primitives can't have multiple overloads) + // TODO: Check that this operation is valid to peform. (e.g. not doing f32_val <<= f32_val) + // TODO: Aren't the bitwise shift operators valid with any integer type count? + this->context.apply_equality(node.span(), node.m_slot->m_res_type, node.m_value->m_res_type); + } + else { + const char *lang_item = nullptr; + switch( node.m_op ) + { + case ::HIR::ExprNode_Assign::Op::None: throw ""; + case ::HIR::ExprNode_Assign::Op::Add: lang_item = "add_assign"; break; + case ::HIR::ExprNode_Assign::Op::Sub: lang_item = "sub_assign"; break; + case ::HIR::ExprNode_Assign::Op::Mul: lang_item = "mul_assign"; break; + case ::HIR::ExprNode_Assign::Op::Div: lang_item = "div_assign"; break; + case ::HIR::ExprNode_Assign::Op::Mod: lang_item = "rem_assign"; break; + case ::HIR::ExprNode_Assign::Op::And: lang_item = "bitand_assign"; break; + case ::HIR::ExprNode_Assign::Op::Or : lang_item = "bitor_assign" ; break; + case ::HIR::ExprNode_Assign::Op::Xor: lang_item = "bitxor_assign"; break; + case ::HIR::ExprNode_Assign::Op::Shr: lang_item = "shl_assign"; break; + case ::HIR::ExprNode_Assign::Op::Shl: lang_item = "shr_assign"; break; + } + assert(lang_item); + const auto& trait_path = this->context.m_crate.get_lang_item_path(node.span(), lang_item); + // TODO: Look for implementation of ops trait + TODO(node.span(), "Search for implementation of " << trait_path << "<" << ty_right << "> for " << ty_left); + } } ::HIR::ExprVisitorDef::visit(node); } @@ -1997,7 +2072,7 @@ namespace { return ; } - // TODO: Inferrence rules when untyped integer literals are in play + // NOTE: Inferrence rules when untyped integer literals are in play // - `impl Add<Foo> for u32` is valid, and makes `1 + Foo` work // - But `[][0] + Foo` doesn't // - Adding `impl Add<Foo> for u64` leads to "`Add<Foo>` is not implemented for `i32`" @@ -2738,6 +2813,50 @@ namespace { // - Struct literal: Semi-known types void visit(::HIR::ExprNode_StructLiteral& node) override { + const Span& sp = node.span(); + // TODO: what if this is an enum struct variant constructor? + + auto& val_types = node.m_value_types; + + if( val_types.size() == 0 ) + { + const auto& str = this->context.m_crate.get_struct_by_path(node.span(), node.m_path.m_path); + this->fix_param_count(node.span(), node.m_path.clone(), str.m_params, node.m_path.m_params); + + this->context.apply_equality(node.span(), node.m_res_type, ::HIR::TypeRef(node.m_path.clone())); + + if( !str.m_data.is_Named() ) + ERROR(sp, E0000, "Struct literal constructor for non-struct-like struct"); + const auto& flds_def = str.m_data.as_Named(); + + for(auto& field : node.m_values) + { + auto fld_def_it = ::std::find_if( flds_def.begin(), flds_def.end(), [&](const auto& x){ return x.first == field.first; } ); + if( fld_def_it == flds_def.end() ) { + ERROR(sp, E0000, "Struct " << node.m_path << " doesn't have a field " << field.first); + } + const ::HIR::TypeRef& field_type = fld_def_it->second.ent; + + if( monomorphise_type_needed(field_type) ) { + val_types.push_back( monomorphise_type(sp, str.m_params, node.m_path.m_params, field_type) ); + } + else { + // SAFE: Can't have _ as monomorphise_type_needed checks for that + val_types.push_back( field_type.clone() ); + } + } + } + + for( unsigned int i = 0; i < node.m_values.size(); i ++ ) + { + auto& field = node.m_values[i]; + this->context.apply_equality(sp, val_types[i], field.second->m_res_type, &field.second); + } + + if( node.m_base_value ) { + this->context.apply_equality(node.span(), node.m_res_type, node.m_base_value->m_res_type); + } + ::HIR::ExprVisitorDef::visit(node); } // - Tuple literal: diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 5bd32225..a64105c7 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -629,14 +629,13 @@ AST::Trait Parse_TraitDef(TokenStream& lex, AST::Module& mod, const AST::MetaIte break; }
// Associated type
case TOK_RWORD_TYPE: {
+ auto atype_params = ::AST::GenericParams { };
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
if( GET_TOK(tok, lex) == TOK_COLON )
{
// Bounded associated type
- TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef("Self", 0xFFFF), AST::Path(), {AST::PathNode(name)}) );
- //TypeRef a_type = TypeRef(TypeRef::TagAssoc(), TypeRef("Self", 0xFFFF), TypeRef(), name);
- Parse_TypeBound(lex, params, a_type);
+ Parse_TypeBound(lex, atype_params, TypeRef("Self", 0xFFFF));
GET_TOK(tok, lex);
}
if( tok.type() == TOK_RWORD_WHERE ) {
@@ -651,6 +650,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, AST::Module& mod, const AST::MetaIte CHECK_TOK(tok, TOK_SEMICOLON);
trait.add_type( ::std::move(name), ::std::move(default_type) );
+ trait.items().back().data.as_Type().params() = mv$(atype_params);
break; }
// Functions (possibly unsafe)
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 4c1eb927..f224d5f9 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -75,7 +75,7 @@ struct Context auto& data = e.as_Generic(); if( has_self ) { - assert( level == GenericSlot::Level::Top ); + //assert( level == GenericSlot::Level::Top ); data.types.push_back( Named<GenericSlot> { "Self", GenericSlot { level, 0xFFFF } } ); m_name_context.push_back( Ent::make_ConcreteSelf(nullptr) ); } @@ -91,10 +91,15 @@ struct Context m_name_context.push_back(mv$(e)); } - void pop(const ::AST::GenericParams& ) { + void pop(const ::AST::GenericParams& , bool has_self=false) { if( !m_name_context.back().is_Generic() ) BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); m_name_context.pop_back(); + if(has_self) { + if( !m_name_context.back().is_ConcreteSelf() ) + BUG(Span(), "resolve/absolute.cpp - Context::pop(GenericParams) - Mismatched pop"); + m_name_context.pop_back(); + } } void push(const ::AST::Module& mod) { m_name_context.push_back( Ent::make_Module({ &mod }) ); @@ -1194,12 +1199,12 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST: 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 ); + 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() ); + item_context.pop( e.params(), true ); ), (Function, DEBUG("Function - " << i.name); @@ -1295,7 +1300,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) Resolve_Absolute_ImplItems(item_context, e.items()); - item_context.pop( e.params() ); + item_context.pop( e.params(), true ); ), (Type, DEBUG("Type - " << i.name); @@ -1304,7 +1309,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) Resolve_Absolute_Type( item_context, e.type() ); - item_context.pop( e.params() ); + item_context.pop( e.params(), true ); ), (Struct, DEBUG("Struct - " << i.name); |