Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/hir_conv/constant_evaluation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace {
void ConvertHIR_ConstantEvaluate_Static(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::ItemPath& ip, ::HIR::Static& e);
void ConvertHIR_ConstantEvaluate_FcnSig(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::ItemPath& ip, ::HIR::Function& fcn);

struct Defer {};
using HIR::Defer;

struct NewvalState
: public HIR::Evaluator::Newval
Expand Down
6 changes: 6 additions & 0 deletions src/hir_conv/constant_evaluation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ namespace MIR {

namespace HIR {

// Thrown by Evaluator::evaluate_constant when some dependency of the
// constant being evaluated is itself not yet resolved (typically still a
// generic parameter or an inferred type). Callers outside this module are
// expected to catch and treat as "leave for a later pass to retry".
struct Defer {};

struct Evaluator
{
class Newval
Expand Down
39 changes: 34 additions & 5 deletions src/hir_expand/static_borrow_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,23 @@ namespace static_borrow_constants {
} v(resolve, monomorph);
node->visit(v);
v.visit_type(node->m_res_type);
if( !v.is_generic ) {
// `is_generic` is set by the targeted visit overrides above
// (ExprNode_ConstParam, ExprNode_ArraySized) plus visit_type /
// visit_path_params. Those reliably cover type- and lifetime-
// generic references, but a const-generic value param can still
// leak through paths not yet enumerated -- e.g. ARM Neon's
// `core_arch::arm_shared::neon::generated` lifted const blocks
// hit `_ = Constant(N/*M:0*/)` in MIR with the surrounding
// method's `const N: i32` never remapped, then assert in
// MonomorphiserPP::get_value because the lifted static was
// wiped to a concrete (empty params) item. Preserve the params
// whenever the source context carries any const-generic value
// param: the only cost is a slightly later (Trans Monomorph)
// evaluation instead of an SBC-time concrete one.
Comment on lines +913 to +925

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really verbose comment, and points to a different error. The visitor above should be able to detect that const-generic and flag the generic-ness.
How is that const-generic still getting though without being flagged?

bool has_value_generics =
!m_resolve.impl_generics().m_values.empty()
|| !m_resolve.item_generics().m_values.empty();
if( !v.is_generic && !has_value_generics ) {
params_def = HIR::GenericParams();
constr_params = HIR::PathParams();
DEBUG("Concrete static");
Expand Down Expand Up @@ -1159,8 +1175,16 @@ namespace static_borrow_constants {
if( !new_static.m_params.is_generic() )
{
new_static.m_value.m_state->stage = ::HIR::ExprState::Stage::Sbc;
new_static.m_value_res = ::HIR::Evaluator(sp, m_crate, nvs).evaluate_constant( new_static_pair.path, new_static.m_value, new_static.m_type.clone());
new_static.m_value_generated = true;
try {
new_static.m_value_res = ::HIR::Evaluator(sp, m_crate, nvs).evaluate_constant( new_static_pair.path, new_static.m_value, new_static.m_type.clone());
new_static.m_value_generated = true;
}
catch(const ::HIR::Defer&) {
// A dependency is not fully resolved yet; leave the
// extracted static value as not-generated and let the
// subsequent passes pick it up rather than aborting.
DEBUG("Deferred static borrow eval: " << new_static_pair.path);
}
}

struct H {
Expand Down Expand Up @@ -1402,8 +1426,13 @@ void HIR_Expand_StaticBorrowConstants_Expr(const ::HIR::Crate& crate, const ::HI
if( !new_static.m_params.is_generic() )
{
new_static.m_value.m_state->stage = ::HIR::ExprState::Stage::Sbc;
new_static.m_value_res = ::HIR::Evaluator(sp, crate, nvs).evaluate_constant( path, new_static.m_value, new_static.m_type.clone());
new_static.m_value_generated = true;
try {
new_static.m_value_res = ::HIR::Evaluator(sp, crate, nvs).evaluate_constant( path, new_static.m_value, new_static.m_type.clone());
new_static.m_value_generated = true;
}
catch(const ::HIR::Defer&) {
DEBUG("Deferred static borrow eval: " << path);
}
}

DEBUG(path << " = ?");
Expand Down
Loading