Skip to content

Commit

Permalink
HIR Typecheck - Properly pass type params to const evaluation (re #322)
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Dec 17, 2024
1 parent 994ddf8 commit 5e01a76
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
14 changes: 14 additions & 0 deletions samples/test/mrustc-322.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// ignore-test - Rustc doesn't allow this, plus it doesn't specify the type for the `Vec<_>`
#![crate_type = "lib"]
struct Assert<const COND: bool>;
trait IsTrue {}
impl IsTrue for Assert<true> {}
trait IsNotZst {}
impl<T> IsNotZst for T
where
Assert<{ std::mem::size_of::<T>() > 0 }>: IsTrue,
{}
fn assert_not_zero_sized<T: IsNotZst>(_: T) {}
fn main() {
assert_not_zero_sized(vec![]);
}
30 changes: 28 additions & 2 deletions src/hir_conv/constant_evaluation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3729,6 +3729,22 @@ void ConvertHIR_ConstantEvaluate_ArraySize(const Span& sp, const ::HIR::Crate& c
}
}

namespace {
bool params_contain_ivars(const ::HIR::PathParams& params) {
for(const auto& t : params.m_types) {
if( visit_ty_with(t, [](const HIR::TypeRef& t){ return t.data().is_Infer(); })) {
return true;
}
}
for(const auto& v : params.m_values) {
if( v.is_Infer() ) {
return true;
}
}
return false;
}
}

void ConvertHIR_ConstantEvaluate_MethodParams(
const Span& sp,
const ::HIR::Crate& crate, const HIR::SimplePath& mod_path, const ::HIR::GenericParams* impl_generics, const ::HIR::GenericParams* item_generics,
Expand All @@ -3740,7 +3756,8 @@ void ConvertHIR_ConstantEvaluate_MethodParams(
{
if(v.is_Unevaluated())
{
const auto& e = *v.as_Unevaluated()->expr;
const auto& ue = *v.as_Unevaluated();
const auto& e = *ue.expr;
auto name = FMT("param_" << &v << "#");
TRACE_FUNCTION_FR(name, name);
auto nvs = NewvalState { crate.get_mod_by_path(Span(), mod_path), mod_path, name };
Expand All @@ -3751,12 +3768,21 @@ void ConvertHIR_ConstantEvaluate_MethodParams(
// - Which, might not be known at this point - might be a UfcsInherent
try
{
// TODO: if there's an ivar in the param list, then throw defer
// - Caller should ensure that known ivars are expanded.
if( params_contain_ivars(ue.params_impl) || params_contain_ivars(ue.params_item) ) {
throw Defer();
}

auto idx = static_cast<size_t>(&v - &params.m_values.front());
ASSERT_BUG(sp, idx < params_def.m_values.size(), "");
const auto& ty = params_def.m_values[idx].m_type;
ASSERT_BUG(sp, !monomorphise_type_needed(ty), "" << ty);
MonomorphState ms;
ms.pp_impl = &ue.params_impl;
ms.pp_method = &ue.params_item;

auto val = eval.evaluate_constant( ::HIR::ItemPath(mod_path, name.c_str()), e, ty.clone() );
auto val = eval.evaluate_constant( ::HIR::ItemPath(mod_path, name.c_str()), e, ty.clone(), std::move(ms) );
v = ::HIR::ConstGeneric::make_Evaluated(std::move(val));
}
catch(const Defer& )
Expand Down
1 change: 1 addition & 0 deletions src/hir_typeck/expr_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2385,6 +2385,7 @@ void Context::equate_values(const Span& sp, const ::HIR::ConstGeneric& rl, const
this->m_ivars.set_ivar_val_to(r.as_Infer().index, l.clone());
}
else {
// TODO: What about unevaluated values due to type inference?
ERROR(sp, E0000, "Value mismatch between " << l << " and " << r);
}
}
Expand Down

0 comments on commit 5e01a76

Please sign in to comment.