summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-11-23 12:01:40 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-11-23 12:01:40 +0800
commit87df981564afc3debfe5b11842f375bfae5900ff (patch)
tree803047f1d90bf6b01ac6445bdb9c7e592d81466f
parentfb2b1202e916e2e3f406d03005237b1d2447269f (diff)
downloadmrust-87df981564afc3debfe5b11842f375bfae5900ff.tar.gz
HIR - Restructure resolve to replace `Self` type later in processing
-rw-r--r--src/hir/dump.cpp2
-rw-r--r--src/hir/expr.cpp4
-rw-r--r--src/hir/expr.hpp8
-rw-r--r--src/hir/from_ast.cpp11
-rw-r--r--src/hir/from_ast_expr.cpp3
-rw-r--r--src/hir_conv/bind.cpp8
-rw-r--r--src/hir_conv/expand_type.cpp16
-rw-r--r--src/hir_conv/resolve_ufcs.cpp51
-rw-r--r--src/hir_conv/resolve_ufcs_outer.cpp127
-rw-r--r--src/hir_expand/annotate_value_usage.cpp3
-rw-r--r--src/hir_typeck/expr_check.cpp5
-rw-r--r--src/hir_typeck/expr_cs.cpp19
-rw-r--r--src/hir_typeck/helpers.cpp32
-rw-r--r--src/hir_typeck/static.cpp6
-rw-r--r--src/mir/from_hir.cpp3
-rw-r--r--src/resolve/absolute.cpp12
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,