From 5e01a76097265f4bb27b18885b9af3f2778180f9 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 17 Dec 2024 12:13:04 +0800 Subject: [PATCH] HIR Typecheck - Properly pass type params to const evaluation (re #322) --- samples/test/mrustc-322.rs | 14 +++++++++++++ src/hir_conv/constant_evaluation.cpp | 30 ++++++++++++++++++++++++++-- src/hir_typeck/expr_cs.cpp | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 samples/test/mrustc-322.rs diff --git a/samples/test/mrustc-322.rs b/samples/test/mrustc-322.rs new file mode 100644 index 000000000..654f3ef71 --- /dev/null +++ b/samples/test/mrustc-322.rs @@ -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; +trait IsTrue {} +impl IsTrue for Assert {} +trait IsNotZst {} +impl IsNotZst for T +where + Assert<{ std::mem::size_of::() > 0 }>: IsTrue, +{} +fn assert_not_zero_sized(_: T) {} +fn main() { + assert_not_zero_sized(vec![]); +} diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 77d0e25a1..9ae986043 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -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, @@ -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 }; @@ -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(&v - ¶ms.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& ) diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 637542077..02b333bdc 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -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); } }