diff options
-rw-r--r-- | src/hir/item_path.hpp | 5 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 26 | ||||
-rw-r--r-- | src/hir_typeck/common.cpp | 4 | ||||
-rw-r--r-- | src/hir_typeck/common.hpp | 1 |
4 files changed, 34 insertions, 2 deletions
diff --git a/src/hir/item_path.hpp b/src/hir/item_path.hpp index d19435eb..d93df9e8 100644 --- a/src/hir/item_path.hpp +++ b/src/hir/item_path.hpp @@ -87,6 +87,11 @@ public: return name ? name : ""; } + const ItemPath& get_top_ip() const { + if( this->parent ) + return this->parent->get_top_ip(); + return *this; + } ItemPath operator+(const ::std::string& name) const { return ItemPath(*this, name.c_str()); } diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index a4210e05..acb613be 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -73,6 +73,9 @@ namespace { (Invalid, return ::HIR::Literal(); ), + (Defer, + return ::HIR::Literal::make_Defer({}); + ), (List, ::std::vector< ::HIR::Literal> vals; for(const auto& val : e) { @@ -400,8 +403,13 @@ namespace { ), (Const, auto p = ms.monomorph(state.sp, e2.p); + // If there's any mention of generics in this path, then return Literal::Defer + if( visit_path_tys_with(e2.p, [&](const auto& ty)->bool { return ty.m_data.is_Generic(); }) ) + { + DEBUG("Return Literal::Defer for constant " << e2.p << " which references a generic parameter"); + return ::HIR::Literal::make_Defer({}); + } MonomorphState const_ms; - // TODO: If there's any mention of Self in this path, then return Literal::Defer auto ent = get_ent_fullpath(state.sp, this->resolve.m_crate, p, EntNS::Value, const_ms); MIR_ASSERT(state, ent.is_Constant(), "MIR Constant::Const(" << p << ") didn't point to a Constant - " << ent.tag_str()); const auto& c = *ent.as_Constant(); @@ -588,6 +596,8 @@ namespace { (BinOp, auto inval_l = read_param(e.val_l); auto inval_r = read_param(e.val_r); + if( inval_l.is_Defer() || inval_r.is_Defer() ) + return ::HIR::Literal::make_Defer({}); MIR_ASSERT(state, 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), ( @@ -654,6 +664,8 @@ namespace { ), (UniOp, auto inval = local_state.read_lval(e.val); + if( inval.is_Defer() ) + return ::HIR::Literal::make_Defer({}); TU_IFLET( ::HIR::Literal, inval, Integer, i, switch( e.op ) { @@ -830,7 +842,15 @@ namespace { const auto* mir = this->resolve.m_crate.get_or_gen_mir(ip, expr, exp); if( mir ) { - return evaluate_constant_mir(ip, *mir, {}, mv$(exp), {}); + ::HIR::TypeRef ty_self { "Self", GENERIC_Self }; + // Might want to have a fully-populated MonomorphState for expanding inside impl blocks + // HACK: Generate a roughly-correct one + MonomorphState ms; + const auto& top_ip = ip.get_top_ip(); + if( top_ip.trait && !top_ip.ty ) { + ms.self_ty = &ty_self; + } + return evaluate_constant_mir(ip, *mir, mv$(ms), mv$(exp), {}); } else { BUG(this->root_span, "Attempting to evaluate constant expression with no associated code"); @@ -839,6 +859,8 @@ namespace { void check_lit_type(const Span& sp, const ::HIR::TypeRef& type, ::HIR::Literal& lit) { + if( lit.is_Defer() ) + return ; // TODO: Mask down limited size integers TU_MATCHA( (type.m_data), (te), (Infer, diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp index e78ed21b..4b0328e7 100644 --- a/src/hir_typeck/common.cpp +++ b/src/hir_typeck/common.cpp @@ -113,6 +113,10 @@ bool visit_ty_with(const ::HIR::TypeRef& ty, t_cb_visit_ty callback) ) return false; } +bool visit_path_tys_with(const ::HIR::Path& path, t_cb_visit_ty callback) +{ + return visit_ty_with__path(path, callback); +} bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl) { diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp index 09a5d9b2..14d9162f 100644 --- a/src/hir_typeck/common.hpp +++ b/src/hir_typeck/common.hpp @@ -33,6 +33,7 @@ typedef ::std::function<bool(const ::HIR::TypeRef&)> t_cb_visit_ty; /// Calls the provided callback on every type seen when recursing the type. /// If the callback returns `true`, no further types are visited and the function returns `true`. extern bool visit_ty_with(const ::HIR::TypeRef& ty, t_cb_visit_ty callback); +extern bool visit_path_tys_with(const ::HIR::Path& ty, t_cb_visit_ty callback); typedef ::std::function<bool(const ::HIR::TypeRef&, ::HIR::TypeRef&)> t_cb_clone_ty; /// Clones a type, calling the provided callback on every type (optionally providing a replacement) |