diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/dump.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.cpp | 4 | ||||
-rw-r--r-- | src/hir/expr.hpp | 8 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 11 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 3 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 8 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 16 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 51 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs_outer.cpp | 127 | ||||
-rw-r--r-- | src/hir_expand/annotate_value_usage.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr_check.cpp | 5 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 19 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 32 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 6 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 3 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 12 |
16 files changed, 239 insertions, 71 deletions
diff --git a/src/hir/dump.cpp b/src/hir/dump.cpp index 3b981e26..b29873d4 100644 --- a/src/hir/dump.cpp +++ b/src/hir/dump.cpp @@ -643,7 +643,7 @@ namespace { } void visit(::HIR::ExprNode_StructLiteral& node) override { - m_os << node.m_path << " {\n"; + m_os << node.m_type << " {\n"; inc_indent(); for(/*const*/ auto& val : node.m_values) { m_os << indent() << val.first << ": "; diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 0512e557..62017b45 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -159,11 +159,13 @@ DEF_VISIT(ExprNode_PathValue, node, ) DEF_VISIT(ExprNode_Variable, , ) DEF_VISIT(ExprNode_StructLiteral, node, - visit_path(::HIR::Visitor::PathContext::VALUE, node.m_path); + visit_type(node.m_type); if( node.m_base_value ) visit_node_ptr(node.m_base_value); for(auto& val : node.m_values) visit_node_ptr(val.second); + + visit_generic_path(::HIR::Visitor::PathContext::TYPE, node.m_real_path); ) DEF_VISIT(ExprNode_UnionLiteral, node, visit_generic_path(::HIR::Visitor::PathContext::TYPE, node.m_path); diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 753170fd..5d89fb1a 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -701,17 +701,19 @@ struct ExprNode_StructLiteral: { typedef ::std::vector< ::std::pair< RcString, ExprNodeP > > t_values; - ::HIR::Path m_path; + ::HIR::TypeRef m_type; bool m_is_struct; ::HIR::ExprNodeP m_base_value; t_values m_values; + /// Actual path extracted from the TypeRef (populated after inner UFCS expansion) + ::HIR::GenericPath m_real_path; /// Monomorphised types of each field. ::std::vector< ::HIR::TypeRef> m_value_types; - ExprNode_StructLiteral(Span sp, ::HIR::Path path, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): + ExprNode_StructLiteral(Span sp, ::HIR::TypeRef ty, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): ExprNode( mv$(sp) ), - m_path( mv$(path) ), + m_type( mv$(ty) ), m_is_struct( is_struct ), m_base_value( mv$(base_value) ), m_values( mv$(values) ) diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index e3cba9e9..e1ee8138 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1264,9 +1264,10 @@ namespace { return rv; } -::HIR::Function LowerHIR_Function(::HIR::ItemPath p, const ::AST::AttributeList& attrs, const ::AST::Function& f, const ::HIR::TypeRef& self_type) +::HIR::Function LowerHIR_Function(::HIR::ItemPath p, const ::AST::AttributeList& attrs, const ::AST::Function& f, const ::HIR::TypeRef& real_self_type) { static Span sp; + static HIR::TypeRef explicit_self_type = HIR::TypeRef("Self", 0xFFFF); TRACE_FUNCTION_F(p); @@ -1279,11 +1280,11 @@ namespace { if( args.size() > 0 && args.front().first.m_binding.m_name == "self" ) { const auto& arg_self_ty = args.front().second; - if( arg_self_ty == self_type ) { + if( arg_self_ty == explicit_self_type || arg_self_ty == real_self_type ) { receiver = ::HIR::Function::Receiver::Value; } else TU_IFLET(::HIR::TypeRef::Data, arg_self_ty.m_data, Borrow, e, - if( *e.inner == self_type ) + if( *e.inner == explicit_self_type || *e.inner == real_self_type ) { switch(e.type) { @@ -1299,7 +1300,7 @@ namespace { auto p = g_crate_ptr->get_lang_item_path_opt("owned_box"); if( pe.m_path == p ) { - if( pe.m_params.m_types.size() == 1 && pe.m_params.m_types[0] == self_type ) + if( pe.m_params.m_types.size() == 1 && (pe.m_params.m_types[0] == explicit_self_type || pe.m_params.m_types[0] == real_self_type) ) { receiver = ::HIR::Function::Receiver::Box; } @@ -1314,7 +1315,7 @@ namespace { if( pe.m_params.m_types.size() != 1 ) { TODO(sp, "Receiver types with more than one param - " << arg_self_ty); } - if( pe.m_params.m_types[0] != self_type ) { + if( !(pe.m_params.m_types[0] == explicit_self_type || pe.m_params.m_types[0] == real_self_type) ) { ERROR(sp, E0000, "Unsupported receiver type - " << arg_self_ty); } receiver = ::HIR::Function::Receiver::Custom; diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index baca8d75..cd819471 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -535,9 +535,8 @@ struct LowerHIR_ExprNode_Visitor: ::HIR::ExprNode_StructLiteral::t_values values; for(const auto& val : v.m_values) values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); - // TODO: What if `v.m_path` is an associated type (that's known to be a struct) m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), - LowerHIR_Path(v.span(), v.m_path), + LowerHIR_Type( ::TypeRef(v.span(), v.m_path) ), ! v.m_path.m_bindings.type.is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index b494cc58..579df975 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -441,6 +441,10 @@ namespace { } void visit_type(::HIR::TypeRef& ty) override { + visit_type_inner(ty); + } + void visit_type_inner(::HIR::TypeRef& ty, bool do_bind=true) + { //TRACE_FUNCTION_F(ty); static Span sp; @@ -448,6 +452,8 @@ namespace { { TU_MATCH_HDRA( (e->path.m_data), {) TU_ARMA(Generic, pe) { + if(!do_bind) + break; const auto& item = *reinterpret_cast< const ::HIR::TypeItem*>( get_type_pointer(sp, m_crate, pe.m_path, Target::TypeItem) ); TU_MATCH_DEF( ::HIR::TypeItem, (item), (e3), ( @@ -665,7 +671,7 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { - upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); + upper_visitor.visit_type_inner(node.m_type, false); ::HIR::ExprVisitorDef::visit(node); } void visit(::HIR::ExprNode_ArraySized& node) override diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index 3b720198..b6ba48c7 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -263,12 +263,18 @@ public: { if( node.m_is_struct ) { - auto new_type = ConvertHIR_ExpandAliases_GetExpansion(upper_visitor.m_crate, node.m_path, /*in_expr=*/true); - if( new_type != ::HIR::TypeRef() ) + if(node.m_type.m_data.is_Path() ) { - auto new_path = mv$(new_type.m_data.as_Path().path); - DEBUG("Replacing " << node.m_path << " with " << new_path); - node.m_path = mv$(new_path); + auto new_type = ConvertHIR_ExpandAliases_GetExpansion(upper_visitor.m_crate, node.m_type.m_data.as_Path().path, /*in_expr=*/true); + if( new_type != ::HIR::TypeRef() ) + { + DEBUG("Replacing " << node.m_type << " with " << new_type); + node.m_type = mv$(new_type); + } + } + else if( node.m_type == ::HIR::TypeRef("Self", GENERIC_Self) ) + { + node.m_type = upper_visitor.m_impl_type->clone(); } } diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp index 90b3868d..470e26fb 100644 --- a/src/hir_conv/resolve_ufcs.cpp +++ b/src/hir_conv/resolve_ufcs.cpp @@ -27,15 +27,14 @@ namespace { StaticTraitResolve m_resolve; const ::HIR::TypeRef* m_current_type = nullptr; - const ::HIR::Trait* m_current_trait; + const ::HIR::Trait* m_current_trait = nullptr; const ::HIR::ItemPath* m_current_trait_path; bool m_in_expr = false; public: Visitor(const ::HIR::Crate& crate): m_crate(crate), - m_resolve(crate), - m_current_trait(nullptr) + m_resolve(crate) {} struct ModTraitsGuard { @@ -78,7 +77,7 @@ namespace { // NOTE: Disabled, becuase generics in type aliases are never checked #if 0 auto _ = m_resolve.set_item_generics(item.m_params); - ::HIR::Visitor::visit_function(p, item); + ::HIR::Visitor::visit_type_alias(p, item); #endif } void visit_trait(::HIR::ItemPath p, ::HIR::Trait& trait) override { @@ -189,7 +188,7 @@ namespace { } void visit(::HIR::ExprNode_StructLiteral& node) override { - upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); + upper_visitor.visit_type(node.m_type); ::HIR::ExprVisitorDef::visit(node); } @@ -522,6 +521,8 @@ namespace { ::HIR::Visitor::visit_type(ty); + // TODO: If this an associated type, check for default trait params + unsigned counter = 0; while( m_resolve.expand_associated_types_single(sp, ty) ) { @@ -548,12 +549,43 @@ namespace { } } - TU_IFLET(::HIR::Path::Data, p.m_data, UfcsUnknown, e, + // TODO: Would like to remove this, but it's required still (for expressions) + if(auto* pe = p.m_data.opt_UfcsUnknown()) + { + auto& e = *pe; TRACE_FUNCTION_FR("UfcsUnknown - p=" << p, p); this->visit_type( *e.type ); this->visit_path_params( e.params ); + // Self resolves from the current trait before looking for bounds + if( *e.type == ::HIR::TypeRef("Self", 0xFFFF) ) + { + ::HIR::GenericPath trait_path; + if( m_current_trait_path->trait_path() ) + { + trait_path = ::HIR::GenericPath( *m_current_trait_path->trait_path() ); + trait_path.m_params = m_current_trait_path->trait_args()->clone(); + } + else + { + trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); + for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { + trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); + } + } + if( locate_in_trait_and_set(pc, trait_path, *m_current_trait, p.m_data) ) { + // Success! + if( m_in_expr ) { + for(auto& t : p.m_data.as_UfcsKnown().trait.m_params.m_types) + t = ::HIR::TypeRef(); + } + DEBUG("Found in Self, p = " << p); + return ; + } + DEBUG("- Item " << e.item << " not found in Self - ty=" << *e.type); + } + // Search for matching impls in current generic blocks if( m_resolve.m_item_generics != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_resolve.m_item_generics, p.m_data) ) { DEBUG("Found in item params, p = " << p); @@ -571,9 +603,8 @@ namespace { } assert(p.m_data.is_UfcsUnknown()); - // If processing a trait, and the type is 'Self', search for the type/method on the trait - // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues? - if( *e.type == ::HIR::TypeRef("Self", 0xFFFF) || (m_current_type && *e.type == *m_current_type) ) + // If the type is the impl type, look for items AFTER generic lookup + if( m_current_type && *e.type == *m_current_type ) { ::HIR::GenericPath trait_path; if( m_current_trait_path->trait_path() ) @@ -608,7 +639,7 @@ namespace { // Couldn't find it ERROR(sp, E0000, "Failed to find impl with '" << e.item << "' for " << *e.type << " (in " << p << ")"); - ) + } else { ::HIR::Visitor::visit_path(p, pc); } diff --git a/src/hir_conv/resolve_ufcs_outer.cpp b/src/hir_conv/resolve_ufcs_outer.cpp index 4e90f4f2..4baf86a2 100644 --- a/src/hir_conv/resolve_ufcs_outer.cpp +++ b/src/hir_conv/resolve_ufcs_outer.cpp @@ -52,7 +52,7 @@ namespace { // NOTE: Disabled, becuase generics in type aliases are never checked #if 0 auto _ = m_resolve.set_item_generics(item.m_params); - ::HIR::Visitor::visit_function(p, item); + ::HIR::Visitor::visit_type_alias(p, item); #endif } void visit_trait(::HIR::ItemPath p, ::HIR::Trait& trait) override { @@ -104,7 +104,100 @@ namespace { void visit_expr(::HIR::ExprPtr& expr) override { - // No inner visiting for expressions +#if 0 + struct ExprVisitor: + public ::HIR::ExprVisitorDef + { + Visitor& upper_visitor; + + ExprVisitor(Visitor& uv): + upper_visitor(uv) + {} + + void visit(::HIR::ExprNode_Let& node) override + { + upper_visitor.visit_pattern(node.m_pattern); + upper_visitor.visit_type(node.m_type); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_Cast& node) override + { + upper_visitor.visit_type(node.m_res_type); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_CallPath& node) override + { + upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::VALUE); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_CallMethod& node) override + { + upper_visitor.visit_path_params(node.m_params); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_ArraySized& node) override + { + upper_visitor.visit_expr(node.m_size); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_PathValue& node) override + { + upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::VALUE); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_StructLiteral& node) override + { + upper_visitor.visit_type(node.m_type); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_Match& node) override + { + for(auto& arm : node.m_arms) + { + for(auto& pat : arm.m_patterns) + upper_visitor.visit_pattern(pat); + } + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_Closure& node) override + { + upper_visitor.visit_type(node.m_return); + for(auto& arg : node.m_args) { + upper_visitor.visit_pattern(arg.first); + upper_visitor.visit_type(arg.second); + } + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_Block& node) override + { + if( node.m_traits.size() == 0 && node.m_local_mod.m_components.size() > 0 ) { + const auto& mod = upper_visitor.m_crate.get_mod_by_path(node.span(), node.m_local_mod); + for( const auto& trait_path : mod.m_traits ) { + node.m_traits.push_back( ::std::make_pair( &trait_path, &upper_visitor.m_crate.get_trait_by_path(node.span(), trait_path) ) ); + } + } + for( const auto& trait_ref : node.m_traits ) + upper_visitor.m_traits.push_back( trait_ref ); + ::HIR::ExprVisitorDef::visit(node); + for(unsigned int i = 0; i < node.m_traits.size(); i ++ ) + upper_visitor.m_traits.pop_back(); + } + }; + + if( expr.get() != nullptr ) + { + m_in_expr = true; + ExprVisitor v { *this }; + (*expr).visit(v); + m_in_expr = false; + } +#endif } bool locate_trait_item_in_bounds(::HIR::Visitor::PathContext pc, const ::HIR::TypeRef& tr, const ::HIR::GenericParams& params, ::HIR::Path::Data& pd) { @@ -276,6 +369,31 @@ namespace { this->visit_type( *e.type ); this->visit_path_params( e.params ); + // If processing a trait, and the type is 'Self', search for the type/method on the trait + // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues? + // NOTE: `Self` can already be replaced by the self type (AST resolve does this) + if( *e.type == ::HIR::TypeRef("Self", 0xFFFF) ) + { + ::HIR::GenericPath trait_path; + if( m_current_trait_path->trait_path() ) + { + trait_path = ::HIR::GenericPath( *m_current_trait_path->trait_path() ); + trait_path.m_params = m_current_trait_path->trait_args()->clone(); + } + else + { + trait_path = ::HIR::GenericPath( m_current_trait_path->get_simple_path() ); + for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) { + trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) ); + } + } + if( locate_in_trait_and_set(pc, trait_path, *m_current_trait, p.m_data) ) { + DEBUG("Found in Self, p = " << p); + return ; + } + DEBUG("- Item " << e.item << " not found in Self - ty=" << *e.type); + } + // Search for matching impls in current generic blocks if( m_params_method != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_params_method, p.m_data) ) { DEBUG("Found in item params, p = " << p); @@ -286,10 +404,7 @@ namespace { return ; } - // If processing a trait, and the type is 'Self', search for the type/method on the trait - // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues? - // NOTE: `Self` can already be replaced by the self type (AST resolve does this) - if( *e.type == ::HIR::TypeRef("Self", 0xFFFF) || (m_current_type && *e.type == *m_current_type) ) + if( m_current_type && *e.type == *m_current_type ) { ::HIR::GenericPath trait_path; if( m_current_trait_path->trait_path() ) diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 5ce270bc..ef4f257c 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -383,8 +383,7 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { const auto& sp = node.span(); - ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); - auto& ty_path = node.m_path.m_data.as_Generic(); + const auto& ty_path = node.m_real_path; if( node.m_base_value ) { bool is_moved = false; const auto& tpb = node.m_base_value->m_res_type.m_data.as_Path().binding; diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index bdd5e4a7..239de1cf 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -538,13 +538,12 @@ namespace { } void visit(::HIR::ExprNode_StructLiteral& node) override { - TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); + TRACE_FUNCTION_F(&node << " " << node.m_real_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); const auto& sp = node.span(); if( node.m_base_value) { check_types_equal( node.m_base_value->span(), node.m_res_type, node.m_base_value->m_res_type ); } - ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); - auto& ty_path = node.m_path.m_data.as_Generic(); + const auto& ty_path = node.m_real_path; // - Create ivars in path, and set result type const auto& ty = node.m_res_type; diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index e726f64a..0eb20568 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1250,9 +1250,9 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { const auto& sp = node.span(); - TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); + TRACE_FUNCTION_F(&node << " " << node.m_type << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); - this->add_ivars_path(node.span(), node.m_path); + this->context.add_ivars(node.m_type); for( auto& val : node.m_values ) { this->context.add_ivars( val.second->m_res_type ); @@ -1261,14 +1261,11 @@ namespace { this->context.add_ivars( node.m_base_value->m_res_type ); } - // TODO: The path can be a Ufcs (any type) - if( !node.m_path.m_data.is_Generic() ) - { - auto t = this->context.m_resolve.expand_associated_types(sp, ::HIR::TypeRef::new_path( mv$(node.m_path), {} )); - node.m_path = mv$(t.m_data.as_Path().path); - } - ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); - auto& ty_path = node.m_path.m_data.as_Generic(); + auto t = this->context.m_resolve.expand_associated_types(sp, mv$(node.m_type)); + node.m_type = HIR::TypeRef(); + ASSERT_BUG(sp, TU_TEST1(t.m_data, Path, .path.m_data.is_Generic()), "Struct literal with non-Generic path - " << t); + node.m_real_path = mv$(t.m_data.as_Path().path.m_data.as_Generic()); + auto& ty_path = node.m_real_path; // - Create ivars in path, and set result type const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, ty_path); @@ -3289,7 +3286,7 @@ namespace { this->check_type_resolved_genericpath(node.span(), node.m_path); } void visit(::HIR::ExprNode_StructLiteral& node) override { - this->check_type_resolved_path(node.span(), node.m_path); + this->check_type_resolved_genericpath(node.span(), node.m_real_path); for(auto& ty : node.m_value_types) { if( ty != ::HIR::TypeRef() ) { this->check_type_resolved_top(node.span(), ty); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 7f20ef28..5268e483 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -990,7 +990,7 @@ void TraitResolution::prep_indexes() const auto& trait_params = be.trait.m_path.m_params; auto cb_mono = [&](const auto& ty)->const ::HIR::TypeRef& { const auto& ge = ty.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { + if( ge.binding == GENERIC_Self ) { return be.type; } else if( ge.binding < 256 ) { @@ -1130,7 +1130,7 @@ bool TraitResolution::iterate_aty_bounds(const Span& sp, const ::HIR::Path::Data if( ! be.type.m_data.as_Path().binding.is_Opaque() ) continue ; const auto& be_type_pe = be.type.m_data.as_Path().path.m_data.as_UfcsKnown(); - if( *be_type_pe.type != ::HIR::TypeRef("Self", 0xFFFF) ) + if( *be_type_pe.type != ::HIR::TypeRef("Self", GENERIC_Self) ) continue ; if( be_type_pe.trait.m_path != pe.trait.m_path ) continue ; @@ -2105,7 +2105,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, // Resolve where Self=pe_inner.type (i.e. for the trait this inner UFCS is on) auto cb_placeholders_trait = [&](const auto& ty)->const ::HIR::TypeRef&{ TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Generic, e, - if( e.binding == 0xFFFF ) + if( e.binding == GENERIC_Self ) return *pe_inner.type; else if( e.binding >> 8 == 0 ) { ASSERT_BUG(sp, e.binding < pe_inner.trait.m_params.m_types.size(), ""); @@ -2281,7 +2281,7 @@ bool TraitResolution::find_named_trait_in_trait(const Span& sp, const auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { + if( ge.binding == GENERIC_Self ) { return target_type; } else { @@ -2413,7 +2413,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple { auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { + if( ge.binding == GENERIC_Self ) { return *assoc_info->type; } else { @@ -2648,7 +2648,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ::HIR::TypeRef tmp; auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { + if( ge.binding == GENERIC_Self ) { BUG(sp, "Self type in struct/enum generics"); } else if( ge.binding >> 8 == 0 ) { @@ -3927,7 +3927,7 @@ const ::HIR::TypeRef* TraitResolution::check_method_receiver(const Span& sp, con { const ::HIR::TypeRef* detected_self_ty = nullptr; auto cb_getself = [&](auto idx, const auto& /*name*/, const auto& ty)->::HIR::Compare{ - if( idx == 0xFFFF ) + if( idx == GENERIC_Self ) { detected_self_ty = &ty; } @@ -4070,7 +4070,7 @@ bool TraitResolution::find_method(const Span& sp, const auto& trait = this->m_crate.get_trait_by_path(sp, e.m_trait.m_path.m_path); ::HIR::GenericPath final_trait_path; - if( const auto* fcn_ptr = this->trait_contains_method(sp, e.m_trait.m_path, trait, ::HIR::TypeRef("Self", 0xFFFF), method_name, final_trait_path) ) + if( const auto* fcn_ptr = this->trait_contains_method(sp, e.m_trait.m_path, trait, ::HIR::TypeRef("Self", GENERIC_Self), method_name, final_trait_path) ) { DEBUG("- Found trait " << final_trait_path); // - If the receiver is valid, then it's correct (no need to check the type again) @@ -4099,7 +4099,7 @@ bool TraitResolution::find_method(const Span& sp, const auto& trait = this->m_crate.get_trait_by_path(sp, trait_path.m_path.m_path); ::HIR::GenericPath final_trait_path; - if( const auto* fcn_ptr = this->trait_contains_method(sp, trait_path.m_path, trait, ::HIR::TypeRef("Self", 0xFFFF), method_name, final_trait_path) ) + if( const auto* fcn_ptr = this->trait_contains_method(sp, trait_path.m_path, trait, ::HIR::TypeRef("Self", GENERIC_Self), method_name, final_trait_path) ) { DEBUG("- Found trait " << final_trait_path); @@ -4128,7 +4128,7 @@ bool TraitResolution::find_method(const Span& sp, // `/*I:#*/` := `e.trait.m_params` auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { + if( ge.binding == GENERIC_Self ) { return *e.type; } else if( ge.binding >> 8 == 0 ) { @@ -4152,7 +4152,7 @@ bool TraitResolution::find_method(const Span& sp, ASSERT_BUG(sp, bound.m_trait_ptr, "Pointer to trait " << bound.m_path << " not set in " << e.trait.m_path); ::HIR::GenericPath final_trait_path; - if( const auto* fcn_ptr = this->trait_contains_method(sp, bound.m_path, *bound.m_trait_ptr, ::HIR::TypeRef("Self", 0xFFFF), method_name, final_trait_path) ) + if( const auto* fcn_ptr = this->trait_contains_method(sp, bound.m_path, *bound.m_trait_ptr, ::HIR::TypeRef("Self", GENERIC_Self), method_name, final_trait_path) ) { DEBUG("- Found trait " << final_trait_path); @@ -4181,7 +4181,7 @@ bool TraitResolution::find_method(const Span& sp, if( ! be.type.m_data.as_Path().binding.is_Opaque() ) continue ; const auto& be_type_pe = be.type.m_data.as_Path().path.m_data.as_UfcsKnown(); - if( *be_type_pe.type != ::HIR::TypeRef("Self", 0xFFFF) ) + if( *be_type_pe.type != ::HIR::TypeRef("Self", GENERIC_Self) ) continue ; if( be_type_pe.trait.m_path != e.trait.m_path ) continue ; @@ -4191,7 +4191,7 @@ bool TraitResolution::find_method(const Span& sp, // Found such a bound, now to test if it is useful ::HIR::GenericPath final_trait_path; - if( const auto* fcn_ptr = this->trait_contains_method(sp, be.trait.m_path, *be.trait.m_trait_ptr, ::HIR::TypeRef("Self", 0xFFFF), method_name, final_trait_path) ) + if( const auto* fcn_ptr = this->trait_contains_method(sp, be.trait.m_path, *be.trait.m_trait_ptr, ::HIR::TypeRef("Self", GENERIC_Self), method_name, final_trait_path) ) { DEBUG("- Found trait " << final_trait_path); @@ -4264,7 +4264,7 @@ bool TraitResolution::find_method(const Span& sp, ::HIR::GenericPath final_trait_path; const ::HIR::Function* fcn_ptr; - if( !(fcn_ptr = this->trait_contains_method(sp, *trait_ref.first, *trait_ref.second, ::HIR::TypeRef("Self", 0xFFFF), method_name, final_trait_path)) ) + if( !(fcn_ptr = this->trait_contains_method(sp, *trait_ref.first, *trait_ref.second, ::HIR::TypeRef("Self", GENERIC_Self), method_name, final_trait_path)) ) continue ; DEBUG("- Found trait " << final_trait_path); @@ -4372,7 +4372,7 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const const auto& params = e.path.m_data.as_Generic().m_params; auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) + if( ge.binding == GENERIC_Self ) TODO(sp, "Monomorphise struct field types (Self) - " << gt); else if( ge.binding < 256 ) { assert(ge.binding < params.m_types.size()); @@ -4420,7 +4420,7 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const const auto& params = e.path.m_data.as_Generic().m_params; auto monomorph = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) + if( ge.binding == GENERIC_Self ) TODO(sp, "Monomorphise union field types (Self) - " << gt); else if( ge.binding < 256 ) { assert(ge.binding < params.m_types.size()); diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 62dbbaba..8c176790 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -476,7 +476,7 @@ bool StaticTraitResolve::find_impl__check_bound( { struct H { static bool compare_pp(const Span& sp, const ::HIR::PathParams& left, const ::HIR::PathParams& right) { - ASSERT_BUG( sp, left.m_types.size() == right.m_types.size(), "Parameter count mismatch" ); + ASSERT_BUG( sp, left.m_types.size() == right.m_types.size(), "Parameter count mismatch between " << left << " and " << right ); for(unsigned int i = 0; i < left.m_types.size(); i ++) { // TODO: Permits fuzzy comparison to handle placeholder params, should instead do a match/test/assign if( left.m_types[i].compare_with_placeholders(sp, right.m_types[i], [](const auto&t)->const ::HIR::TypeRef&{return t;}) == ::HIR::Compare::Unequal ) { @@ -1291,6 +1291,10 @@ bool StaticTraitResolve::expand_associated_types__UfcsKnown(const Span& sp, ::HI } else { DEBUG("Converted UfcsKnown - " << e.path << " = " << nt); + if( input == nt ) { + replacement_happened = false; + return true; + } input = mv$(nt); replacement_happened = true; } diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index b373e6e0..dac11b43 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -2394,8 +2394,7 @@ namespace { { TRACE_FUNCTION_F("_StructLiteral"); - ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); - const auto& ty_path = node.m_path.m_data.as_Generic(); + const auto& ty_path = node.m_real_path; TU_MATCH_HDRA( (node.m_res_type.m_data.as_Path().binding), {) TU_ARMA(Unbound, _e) { diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 86bc47c7..6cc7c615 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -192,7 +192,7 @@ namespace ( ), (ConcreteSelf, - if( e ) { + if( false && e ) { return e->clone(); } else { @@ -460,7 +460,15 @@ namespace (ConcreteSelf, DEBUG("- ConcreteSelf"); if( ( mode == LookupMode::Type || mode == LookupMode::Namespace ) && name == "Self" ) { - return ::AST::Path( ::AST::Path::TagUfcs(), e->clone(), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); + // TODO: Want to return the type if handling a struct literal + if( false ) { + return ::AST::Path( ::AST::Path::TagUfcs(), e->clone(), ::AST::Path(), ::std::vector< ::AST::PathNode>() ); + } + else { + ::AST::Path rv(name); + rv.bind_variable(0xFFFF); + return rv; + } } ), (VarBlock, |