diff options
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.patch | 102 |
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 - ¶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 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 + |