diff --git a/Notes/HigherRankedTypes.txt b/Notes/HigherRankedTypes.txt index f7a24a9db..ac54aedf9 100644 --- a/Notes/HigherRankedTypes.txt +++ b/Notes/HigherRankedTypes.txt @@ -8,6 +8,7 @@ - `HIR::GenericPath` has a HRL blob attached - Alternative: - Return the HRLs to `TraitPath`, but also put them in `TypeData::Data_Path` + - VTable _value_ paths need `::vtable#` - that also needs the HRLs diff --git a/src/hir/path.cpp b/src/hir/path.cpp index 3cc49dc8d..d2c32f41d 100644 --- a/src/hir/path.cpp +++ b/src/hir/path.cpp @@ -106,7 +106,12 @@ namespace HIR { return os << "<" << e.type << " /*- " << e.impl_params << "*/>::" << e.item << e.params; ), (UfcsKnown, - return os << "<" << e.type << " as " << e.trait << ">::" << e.item << e.params; + os << "<" << e.type << " as "; + if( e.hrtbs ) { + os << "for" << e.hrtbs->fmt_args() << " "; + } + os << e.trait << ">::" << e.item << e.params; + return os; ), (UfcsUnknown, return os << "<" << e.type << " as _>::" << e.item << e.params; @@ -232,6 +237,10 @@ ::HIR::Path::Path(TypeRef ty, GenericPath trait, RcString item, PathParams item_ m_data( Data::make_UfcsKnown({ mv$(ty), mv$(trait), mv$(item), mv$(item_params) }) ) { } +::HIR::Path::Path(TypeRef ty, GenericParams hrtbs, GenericPath trait, RcString item, PathParams item_params): + m_data( Data::make_UfcsKnown({ mv$(ty), mv$(trait), mv$(item), mv$(item_params), box$(hrtbs) }) ) +{ +} ::HIR::Path HIR::Path::clone() const { TU_MATCH_HDRA((m_data), {) @@ -251,7 +260,8 @@ ::HIR::Path HIR::Path::clone() const e.type.clone(), e.trait.clone(), e.item, - e.params.clone() + e.params.clone(), + e.hrtbs ? box$(e.hrtbs->clone()) : nullptr, })); } TU_ARMA(UfcsUnknown, e) { diff --git a/src/hir/path.hpp b/src/hir/path.hpp index 56cc07256..8823ffefe 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -277,6 +277,7 @@ class Path GenericPath trait; RcString item; PathParams params; + std::unique_ptr hrtbs; }), (UfcsUnknown, struct { TypeRef type; @@ -296,6 +297,7 @@ class Path Path(TypeRef ty, RcString item, PathParams item_params=PathParams()); Path(TypeRef ty, GenericPath trait, RcString item, PathParams item_params=PathParams()); + Path(TypeRef ty, GenericParams hrtbs, GenericPath trait, RcString item, PathParams item_params=PathParams()); Path clone() const; Compare compare_with_placeholders(const Span& sp, const Path& x, t_cb_resolve_type resolve_placeholder) const; diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp index 516ed6759..9473cc283 100644 --- a/src/hir_typeck/common.cpp +++ b/src/hir_typeck/common.cpp @@ -453,12 +453,20 @@ ::HIR::Path Monomorphiser::monomorph_path(const Span& sp, const ::HIR::Path& tpl return ::HIR::Path( this->monomorph_genericpath(sp, e2, allow_infer, false) ); } TU_ARMA(UfcsKnown, e2) { - return ::HIR::Path::Data::make_UfcsKnown({ + if( e2.hrtbs /*&& !ignore_hrls*/ ) { + m_hrb_stack.push_back(e2.hrtbs.get()); + } + auto rv = ::HIR::Path::Data::make_UfcsKnown({ this->monomorph_type(sp, e2.type, allow_infer), this->monomorph_genericpath(sp, e2.trait, allow_infer, false), e2.item, - this->monomorph_path_params(sp, e2.params, allow_infer) + this->monomorph_path_params(sp, e2.params, allow_infer), + e2.hrtbs ? box$(e2.hrtbs->clone()) : nullptr }); + if( e2.hrtbs /*&& !ignore_hrls*/ ) { + m_hrb_stack.pop_back(); + } + return rv; } TU_ARMA(UfcsUnknown, e2) { return ::HIR::Path::Data::make_UfcsUnknown({ diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 42a8998db..425a63a33 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -4821,6 +4821,8 @@ bool TraitResolution::find_method(const Span& sp, { if( *self_ty_p == *ityp ) { + auto pp_hrb = bound.m_hrtbs ? bound.m_hrtbs->make_empty_params(3) : HIR::PathParams(); + monomorph_cb.pp_hrb = &pp_hrb; final_trait_path = monomorph_cb.monomorph_genericpath(sp, final_trait_path, false); DEBUG("- Monomorph to " << final_trait_path); diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 4938f19c7..772a4a4f7 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -159,6 +159,15 @@ const EncodedLiteral* MIR_Cleanup_GetConstant(const MIR::TypeResolve& state, con } } +namespace { + ::MIR::Constant create_vtable(HIR::TypeRef ty, const HIR::TraitPath& trait) { + auto vtable_path = trait.m_hrtbs + ? ::HIR::Path(mv$(ty), trait.m_hrtbs->clone(), trait.m_path.clone(), "vtable#") + : ::HIR::Path(mv$(ty), trait.m_path.clone(), "vtable#"); + return ::MIR::Constant::make_ItemAddr(box$(vtable_path)); + } +} + ::MIR::RValue MIR_Cleanup_LiteralToRValue(const ::MIR::TypeResolve& state, MirMutator& mutator, EncodedLiteralSlice lit, ::HIR::TypeRef ty, const MonomorphState& params, ::HIR::Path path) { struct M: Monomorphiser { @@ -455,9 +464,7 @@ ::MIR::RValue MIR_Cleanup_LiteralToRValue(const ::MIR::TypeResolve& state, MirMu const auto* tep = te.inner.data().opt_TraitObject(); if(!tep) MIR_TODO(state, "Hidden vtable"); - auto vtable_path = ::HIR::Path(&ty == &tmp ? mv$(tmp) : src_ty.clone(), tep->m_trait.m_path.clone(), "vtable#"); - - auto vtable_val = ::MIR::Param( ::MIR::Constant::make_ItemAddr(box$(vtable_path)) ); + auto vtable_val = ::MIR::Param( create_vtable(&ty == &tmp ? mv$(tmp) : src_ty.clone(), tep->m_trait) ); return ::MIR::RValue::make_MakeDst({ ::MIR::Param(mv$(ptr_val)), mv$(vtable_val) }); break; } @@ -776,8 +783,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator& else { MIR_ASSERT(state, state.m_resolve.type_is_sized(state.sp, src_ty), "Attempting to get vtable for unsized type - " << src_ty); - auto vtable = ::HIR::Path( HIR::Path::Data::make_UfcsKnown({ src_ty.clone(), trait_path.m_path.clone(), "vtable#" }) ); - out_meta_val = ::MIR::Constant::make_ItemAddr(box$(vtable)); + out_meta_val = create_vtable(src_ty.clone(), trait_path); } } return true;