diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/types.hpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 120 |
2 files changed, 98 insertions, 24 deletions
diff --git a/src/ast/types.hpp b/src/ast/types.hpp index af07ba2d..0b0f205e 100644 --- a/src/ast/types.hpp +++ b/src/ast/types.hpp @@ -41,10 +41,12 @@ namespace AST { class LifetimeRef { + public: static const uint16_t BINDING_STATIC = 0xFFFF; static const uint16_t BINDING_UNBOUND = 0xFFFE; static const uint16_t BINDING_INFER = 0xFFFD; + private: Ident m_name; uint16_t m_binding; diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index d4147e92..3652fb3a 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -65,6 +65,9 @@ namespace }), (Generic, struct { // Map of names to slots + GenericSlot::Level level; + ::AST::GenericParams* params_def; // TODO: What if it's HRBs?, they have a different type + //::AST::HigherRankedBounds* hrbs_def; ::std::vector< Named< GenericSlot > > types; ::std::vector< Named< GenericSlot > > constants; ::std::vector< NamedI< GenericSlot > > lifetimes; @@ -91,7 +94,7 @@ namespace {} void push(const ::AST::HigherRankedBounds& params) { - auto e = Ent::make_Generic({}); + auto e = Ent::make_Generic({ GenericSlot::Level::Hrb, nullptr /*, ¶ms*/ }); auto& data = e.as_Generic(); for(size_t i = 0; i < params.m_lifetimes.size(); i ++) @@ -101,8 +104,8 @@ namespace m_name_context.push_back(mv$(e)); } - void push(const ::AST::GenericParams& params, GenericSlot::Level level, bool has_self=false) { - auto e = Ent::make_Generic({}); + void push(/*const */::AST::GenericParams& params, GenericSlot::Level level, bool has_self=false) { + auto e = Ent::make_Generic({ level, ¶ms }); auto& data = e.as_Generic(); if( has_self ) { @@ -283,6 +286,7 @@ namespace Type, Constant, PatternValue, + //PatternAny, Variable, }; static const char* lookup_mode_msg(LookupMode mode) { @@ -341,7 +345,38 @@ namespace return true; } } + // HACK: For `Enum::Var { .. }` patterns matching value variants + { + auto v = mod.m_value_items.find(name); + if( v != mod.m_value_items.end() ) { + const auto& b = v->second.path.m_bindings.value; + if( b.is_EnumVar() ) { + DEBUG("- TY: Enum variant " << v->second.path); + path = ::AST::Path( v->second.path ); + return true; + } + } + } break; + //case LookupMode::PatternAny: + // { + // auto v = mod.m_type_items.find(name); + // if( v != mod.m_type_items.end() ) { + // DEBUG("- TY: Type " << v->second.path); + // path = ::AST::Path( v->second.path ); + // return true; + // } + // auto v2 = mod.m_value_items.find(name); + // if( v2 != mod.m_value_items.end() ) { + // const auto& b = v2->second.path.m_bindings.value; + // if( b.is_EnumVar() ) { + // DEBUG("- TY: Enum variant " << v2->second.path); + // path = ::AST::Path( v2->second.path ); + // return true; + // } + // } + // } + // break; case LookupMode::PatternValue: { auto v = mod.m_value_items.find(name); @@ -548,6 +583,11 @@ void Resolve_Absolute_Function(Context& item_context, ::AST::Function& fcn); void Resolve_Absolute_PathParams(/*const*/ Context& context, const Span& sp, ::AST::PathParams& args) { + // TODO: Lifetime params + for(auto& arg : args.m_lifetimes) + { + Resolve_Absolute_Lifetime(context, sp, arg); + } for(auto& arg : args.m_types) { Resolve_Absolute_Type(context, arg); @@ -1489,6 +1529,17 @@ void Resolve_Absolute_Lifetime(Context& context, const Span& sp, AST::LifetimeRe return ; } + if( lft.name() == "_" ) + { + if( TARGETVER_1_19 ) + { + ERROR(sp, E0000, "'_ is not a valid lifetime name in 1.19 mode"); + } + // Note: '_ is just an explicit elided lifetime + lft.set_binding(AST::LifetimeRef::BINDING_INFER); + return ; + } + for(auto it = context.m_name_context.rbegin(); it != context.m_name_context.rend(); ++ it) { if( const auto* e = it->opt_Generic() ) @@ -1508,25 +1559,33 @@ void Resolve_Absolute_Lifetime(Context& context, const Span& sp, AST::LifetimeRe if( TARGETVER_1_29 ) { // If parsing a function header, add a new lifetime param to the function - // - Does the same apply to impl headers? + // - Does the same apply to impl headers? Yes it does. if( context.m_ibl_target_generics ) { ASSERT_BUG(sp, !context.m_name_context.empty(), "Name context stack is empty"); - ASSERT_BUG(sp, context.m_name_context.back().is_Generic(), "Name context stack end not Generic, instead " << context.m_name_context.back().tag_str()); - auto& context_gen = context.m_name_context.back().as_Generic(); - auto& def_gen = *context.m_ibl_target_generics; - // 1. Assert that the last item of `context.m_name_context` is Generic, and matches `m_ibl_target_generics` - ASSERT_BUG(sp, context_gen.lifetimes.size() == def_gen.lft_params().size(), ""); - ASSERT_BUG(sp, context_gen.types.size() == def_gen.ty_params().size(), ""); - //ASSERT_BUG(sp, context_gen.constants.size() == def_gen.val_params().size(), ""); - // 2. Add the new lifetime to both `m_ibl_target_generics` and the last entry in m_name_context - size_t idx = def_gen.lft_params().size(); - def_gen.add_lft_param(AST::LifetimeParam(sp, {}, lft.name())); - // TODO: Is this always a method-level set? - auto level = GenericSlot::Level::Method; - context_gen.lifetimes.push_back( NamedI<GenericSlot> { lft.name(), GenericSlot { level, static_cast<unsigned short>(idx) } } ); - lft.set_binding( idx | (static_cast<int>(level) << 8) ); - return ; + auto it = context.m_name_context.rbegin(); + ASSERT_BUG(sp, it->is_Generic(), "Name context stack end not Generic, instead " << it->tag_str()); + while( it->as_Generic().level == GenericSlot::Level::Hrb ) { + it ++; + ASSERT_BUG(sp, it != context.m_name_context.rend(), ""); + ASSERT_BUG(sp, it->is_Generic(), "Name context stack end not Generic, instead " << it->tag_str()); + } + if( it->as_Generic().level != GenericSlot::Level::Hrb ) + { + auto& context_gen = it->as_Generic(); + auto& def_gen = *context.m_ibl_target_generics; + auto level = context_gen.level; + // 1. Assert that the last item of `context.m_name_context` is Generic, and matches `m_ibl_target_generics` + ASSERT_BUG(sp, context_gen.lifetimes.size() == def_gen.lft_params().size(), ""); + ASSERT_BUG(sp, context_gen.types.size() == def_gen.ty_params().size(), ""); + //ASSERT_BUG(sp, context_gen.constants.size() == def_gen.val_params().size(), ""); + // 2. Add the new lifetime to both `m_ibl_target_generics` and the last entry in m_name_context + size_t idx = def_gen.lft_params().size(); + def_gen.add_lft_param(AST::LifetimeParam(sp, {}, lft.name())); + context_gen.lifetimes.push_back( NamedI<GenericSlot> { lft.name(), GenericSlot { level, static_cast<unsigned short>(idx) } } ); + lft.set_binding( idx | (static_cast<int>(level) << 8) ); + return ; + } } } ERROR(sp, E0000, "Couldn't find lifetime " << lft); @@ -1903,6 +1962,10 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa Resolve_Absolute_Pattern(context, allow_refutable, sp); ), (Struct, + // TODO: `Struct { .. }` patterns can match anything + //if( e.sub_patterns.empty() && !e.is_exhaustive ) { + // auto rv = this->lookup_opt(name, src_context, mode); + //} Resolve_Absolute_Path(context, pat.span(), Context::LookupMode::Type, e.path); for(auto& sp : e.sub_patterns) Resolve_Absolute_Pattern(context, allow_refutable, sp.second); @@ -2165,14 +2228,17 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) ), (Impl, auto& def = e.def(); - DEBUG("impl " << def.trait().ent << " for " << def.type()); if( !def.type().is_valid() ) { - DEBUG("---- MARKER IMPL for " << def.trait().ent); + TRACE_FUNCTION_F("impl " << def.trait().ent << " for .."); item_context.push(def.params(), GenericSlot::Level::Top); - Resolve_Absolute_Generic(item_context, def.params()); + + item_context.m_ibl_target_generics = &def.params(); assert( def.trait().ent.is_valid() ); Resolve_Absolute_Path(item_context, def.trait().sp, Context::LookupMode::Type, def.trait().ent); + item_context.m_ibl_target_generics = nullptr; + + Resolve_Absolute_Generic(item_context, def.params()); if( e.items().size() != 0 ) { ERROR(i.data.span, E0000, "impl Trait for .. with methods"); @@ -2184,13 +2250,16 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) } else { + TRACE_FUNCTION_F("impl " << def.trait().ent << " for " << def.type()); item_context.push_self( def.type() ); item_context.push(def.params(), GenericSlot::Level::Top); + item_context.m_ibl_target_generics = &def.params(); Resolve_Absolute_Type(item_context, def.type()); if( def.trait().ent.is_valid() ) { Resolve_Absolute_Path(item_context, def.trait().sp, Context::LookupMode::Type, def.trait().ent); } + item_context.m_ibl_target_generics = nullptr; Resolve_Absolute_Generic(item_context, def.params()); @@ -2202,15 +2271,18 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) ), (NegImpl, auto& impl_def = e; - DEBUG("impl ! " << impl_def.trait().ent << " for " << impl_def.type()); + TRACE_FUNCTION_F("impl ! " << impl_def.trait().ent << " for " << impl_def.type()); item_context.push_self( impl_def.type() ); item_context.push(impl_def.params(), GenericSlot::Level::Top); - Resolve_Absolute_Generic(item_context, impl_def.params()); + item_context.m_ibl_target_generics = &impl_def.params(); Resolve_Absolute_Type(item_context, impl_def.type()); if( !impl_def.trait().ent.is_valid() ) BUG(i.data.span, "Encountered negative impl with no trait"); Resolve_Absolute_Path(item_context, impl_def.trait().sp, Context::LookupMode::Type, impl_def.trait().ent); + item_context.m_ibl_target_generics = nullptr; + + Resolve_Absolute_Generic(item_context, impl_def.params()); // No items |