diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expand/lang_item.cpp | 27 | ||||
-rw-r--r-- | src/expand/mod.cpp | 2 | ||||
-rw-r--r-- | src/hir/hir.hpp | 1 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 22 | ||||
-rw-r--r-- | src/parse/types.cpp | 36 |
5 files changed, 87 insertions, 1 deletions
diff --git a/src/expand/lang_item.cpp b/src/expand/lang_item.cpp index 62527ac9..0bdd37e5 100644 --- a/src/expand/lang_item.cpp +++ b/src/expand/lang_item.cpp @@ -88,6 +88,7 @@ void handle_lang_item(const Span& sp, AST::Crate& crate, const AST::Path& path, else if( name == "unsafe_cell" ) { } else if( TARGETVER_1_29 && name == "alloc_layout") { } else if( TARGETVER_1_29 && name == "panic_info" ) {} // Struct + else if( TARGETVER_1_29 && name == "manually_drop" ) {} // Struct // Generators else if( TARGETVER_1_29 && name == "generator" ) {} // - Trait @@ -114,6 +115,32 @@ void handle_lang_item(const Span& sp, AST::Crate& crate, const AST::Path& path, else if( name == "start" ) { } else if( name == "eh_personality" ) { } + // libcompiler_builtins + // - i128/u128 helpers (not used by mrustc) + else if( name == "i128_add" ) { } + else if( name == "i128_addo" ) { } + else if( name == "u128_add" ) { } + else if( name == "u128_addo" ) { } + else if( name == "i128_sub" ) { } + else if( name == "i128_subo" ) { } + else if( name == "u128_sub" ) { } + else if( name == "u128_subo" ) { } + else if( name == "i128_mul" ) { } + else if( name == "i128_mulo" ) { } + else if( name == "u128_mul" ) { } + else if( name == "u128_mulo" ) { } + else if( name == "i128_div" ) { } + else if( name == "i128_rem" ) { } + else if( name == "u128_div" ) { } + else if( name == "u128_rem" ) { } + else if( name == "i128_shl" ) { } + else if( name == "i128_shlo" ) { } + else if( name == "u128_shl" ) { } + else if( name == "u128_shlo" ) { } + else if( name == "i128_shr" ) { } + else if( name == "i128_shro" ) { } + else if( name == "u128_shr" ) { } + else if( name == "u128_shro" ) { } else { ERROR(sp, E0000, "Unknown language item '" << name << "'"); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index a0cc3f7b..66a7308a 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -772,6 +772,7 @@ struct CExpandExpr: case ::AST::ExprNode_BinOp::RANGE_INC: { // NOTE: Not language items auto core_crate = (crate.m_load_std == ::AST::Crate::LOAD_NONE ? "" : "core"); + auto path_None = ::AST::Path(core_crate, { ::AST::PathNode("option"), ::AST::PathNode("Option"), ::AST::PathNode("None") }); auto path_RangeInclusive_NonEmpty = ::AST::Path(core_crate, { ::AST::PathNode("ops"), ::AST::PathNode("RangeInclusive") }); auto path_RangeToInclusive = ::AST::Path(core_crate, { ::AST::PathNode("ops"), ::AST::PathNode("RangeToInclusive") }); @@ -780,6 +781,7 @@ struct CExpandExpr: ::AST::ExprNode_StructLiteral::t_values values; values.push_back({ {}, "start", mv$(node.m_left) }); values.push_back({ {}, "end" , mv$(node.m_right) }); + values.push_back({ {}, "is_empty", ::AST::ExprNodeP(new ::AST::ExprNode_NamedValue(mv$(path_None))) }); replacement.reset( new ::AST::ExprNode_StructLiteral(mv$(path_RangeInclusive_NonEmpty), nullptr, mv$(values)) ); } else diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index daa27d10..d693c61d 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -50,6 +50,7 @@ struct VisEnt /// NOTE: Intentionally minimal, just covers the values (not the types) TAGGED_UNION(Literal, Invalid, (Invalid, struct {}), + (Defer, struct {}), // List = Array, Tuple, struct literal (List, ::std::vector<Literal>), // TODO: Have a variant for repetition lists // Variant = Enum variant diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index a2847e04..34830f79 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -15,6 +15,8 @@ #include <mir/helpers.hpp> #include <trans/target.hpp> +#define CHECK_DEFER(var) do { if( var.is_Defer() ) { m_rv = ::HIR::Literal::make_Defer({}); return ; } } while(0) + namespace { typedef ::std::vector< ::std::pair< ::std::string, ::HIR::Static> > t_new_values; @@ -332,10 +334,12 @@ namespace { TRACE_FUNCTION_F("_BinOp"); node.m_left->visit(*this); + CHECK_DEFER(m_rv); auto left = mv$(m_rv); auto ret_type = mv$(m_rv_type); node.m_right->visit(*this); + CHECK_DEFER(m_rv); auto right = mv$(m_rv); if( left.tag() != right.tag() ) { @@ -601,6 +605,7 @@ namespace { ::std::vector< ::HIR::Literal> vals; for(const auto& vn : node.m_args ) { vn->visit(*this); + CHECK_DEFER(m_rv); assert( !m_rv.is_Invalid() ); vals.push_back( mv$(m_rv) ); } @@ -824,7 +829,13 @@ namespace { auto ep = get_ent_fullpath(node.span(), m_crate, node.m_path, EntNS::Value); TU_MATCH_DEF( EntPtr, (ep), (e), ( - BUG(node.span(), "Path value with unsupported value type - " << ep.tag_str()); + BUG(node.span(), "_PathValue(" << node.m_path << ") with unsupported value type - " << ep.tag_str()); + ), + (NotFound, + // If the value can't be found, and it's an associated constant, return a literal indicating + // that the value can't yet be evaluated. + DEBUG(node.span() << " - _PathValue(" << node.m_path << ") not found"); + m_rv = ::HIR::Literal::make_Defer({}); ), (Static, // TODO: Should be a more complex path to support associated paths @@ -915,6 +926,7 @@ namespace { } val_set.second->visit(*this); + CHECK_DEFER(m_rv); vals[idx] = mv$(m_rv); } for( unsigned int i = 0; i < vals.size(); i ++ ) { @@ -962,6 +974,7 @@ namespace { m_exp_type = mv$(exp_tys[i]); node.m_vals[i]->visit(*this); + CHECK_DEFER(m_rv); assert( !m_rv.is_Invalid() ); vals.push_back( mv$(m_rv) ); @@ -994,6 +1007,7 @@ namespace { { m_exp_type = exp_inner_ty.clone(); vn->visit(*this); + CHECK_DEFER(m_rv); assert( !m_rv.is_Invalid() ); vals.push_back( mv$(m_rv) ); } @@ -1029,6 +1043,7 @@ namespace { { m_exp_type = mv$(exp_inner_ty); node.m_val->visit(*this); + CHECK_DEFER(m_rv); assert( !m_rv.is_Invalid() ); for(unsigned int i = 0; i < count-1; i ++) { @@ -1285,6 +1300,11 @@ namespace { (BinOp, auto inval_l = read_param(e.val_l); auto inval_r = read_param(e.val_r); + if( inval_l.is_Invalid() || inval_r.is_Invalid() ) + { + val = ::HIR::Literal::make_Invalid({}); + break ; + } ASSERT_BUG(sp, inval_l.tag() == inval_r.tag(), "Mismatched literal types in binop - " << inval_l << " and " << inval_r); TU_MATCH_DEF( ::HIR::Literal, (inval_l, inval_r), (l, r), ( diff --git a/src/parse/types.cpp b/src/parse/types.cpp index a07e66f8..db66a77e 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -15,6 +15,7 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list); TypeRef Parse_Type_Fn(TokenStream& lex, AST::HigherRankedBounds hrbs = {}); TypeRef Parse_Type_Path(TokenStream& lex, AST::HigherRankedBounds hrbs, bool allow_trait_list); +TypeRef Parse_Type_TraitObject(TokenStream& lex, ::AST::HigherRankedBounds hrbs = {}); TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list); // === CODE === @@ -84,6 +85,10 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list) // TODO: path macros return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(ps, mv$(tok.str()), lex)); } + if( TARGETVER_1_29 && tok.str() == "dyn" ) + { + return Parse_Type_TraitObject(lex, {}); + } // or a primitive //if( auto ct = coretype_fromstring(tok.str()) ) //{ @@ -311,6 +316,37 @@ TypeRef Parse_Type_Path(TokenStream& lex, ::AST::HigherRankedBounds hrbs, bool a } } } +TypeRef Parse_Type_TraitObject(TokenStream& lex, ::AST::HigherRankedBounds hrbs) +{ + Token tok; + auto ps = lex.start_span(); + + ::std::vector<Type_TraitPath> traits; + ::std::vector<AST::LifetimeRef> lifetimes; + + traits.push_back(Type_TraitPath { mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) }); + + while( lex.lookahead(0) == TOK_PLUS ) + { + GET_CHECK_TOK(tok, lex, TOK_PLUS); + if( LOOK_AHEAD(lex) == TOK_LIFETIME ) { + GET_TOK(tok, lex); + lifetimes.push_back(AST::LifetimeRef( /*lex.point_span(),*/ lex.get_ident(mv$(tok)) )); + } + else + { + if( lex.lookahead(0) == TOK_RWORD_FOR ) + { + hrbs = Parse_HRB(lex); + } + traits.push_back({ mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) }); + } + } + + if( lifetimes.empty()) + lifetimes.push_back(AST::LifetimeRef()); + return TypeRef(lex.end_span(ps), mv$(traits), mv$(lifetimes)); +} TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list) { Token tok; |