summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/from_ast.cpp55
-rw-r--r--src/hir/generic_params.cpp25
-rw-r--r--src/hir_typeck/expr.cpp10
-rw-r--r--src/parse/root.cpp6
-rw-r--r--src/resolve/absolute.cpp17
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);