diff options
Diffstat (limited to 'src/hir_conv/constant_evaluation.cpp')
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
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, |