diff options
-rw-r--r-- | src/hir/from_ast.cpp | 55 | ||||
-rw-r--r-- | src/hir/generic_params.cpp | 25 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 10 | ||||
-rw-r--r-- | src/parse/root.cpp | 6 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 17 |
5 files changed, 88 insertions, 25 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 6c873e1e..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); 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_typeck/expr.cpp b/src/hir_typeck/expr.cpp index f548582a..24f1519c 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -1491,6 +1491,16 @@ 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 ); + const auto& ty_bounds = assoc_ty.m_params.m_bounds; + // NOTE: The bounds here have 'Self' = the type + DEBUG("TODO: Search bounds assoc type bounds - type " << e.item << assoc_ty.m_params.fmt_bounds()); + } else { // 2. Search for inherent methods for(const auto& impl : m_crate.m_type_impls) 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); |