summaryrefslogtreecommitdiff
path: root/experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch
diff options
context:
space:
mode:
Diffstat (limited to 'experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch')
-rw-r--r--experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch b/experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch
new file mode 100644
index 000000000..d190dbb40
--- /dev/null
+++ b/experimental/mrustc/mrustc-0007-HIR-Typecheck-Properly-pass-type-params-to-const-eva.patch
@@ -0,0 +1,102 @@
+From 5e01a76097265f4bb27b18885b9af3f2778180f9 Mon Sep 17 00:00:00 2001
+From: John Hodge <tpg@mutabah.net>
+Date: Tue, 17 Dec 2024 12:13:04 +0800
+Subject: [PATCH] HIR Typecheck - Properly pass type params to const evaluation
+ (re #322)
+
+
+diff --git a/samples/test/mrustc-322.rs b/samples/test/mrustc-322.rs
+new file mode 100644
+index 00000000..654f3ef7
+--- /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<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![]);
++}
+diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
+index 77d0e25a..9ae98604 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<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& )
+diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
+index 63754207..02b333bd 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);
+ }
+ }
+--
+2.40.0
+