diff options
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 4 | ||||
-rw-r--r-- | src/hir_typeck/common.hpp | 17 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 20 |
3 files changed, 32 insertions, 9 deletions
diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp index 9bdb2feb..19ec84ba 100644 --- a/src/hir_conv/resolve_ufcs.cpp +++ b/src/hir_conv/resolve_ufcs.cpp @@ -6,7 +6,9 @@ * - Resolve unkown UFCS traits into inherent or trait * - HACK: Will likely be replaced with a proper typeck pass (no it won't) * - * - TODO: What are the rules for UFCS lookup? + * TODO: Remove this pass, except maybe for running EAT on outer types + * - Expression code can handle picking UFCS functions better than this code can + * - Outer EAT is nice, but StaticTraitResolve will need to handle non-EAT-ed types when doing lookups */ #include "main_bindings.hpp" #include <hir/hir.hpp> diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp index c0e495a6..4de874a8 100644 --- a/src/hir_typeck/common.hpp +++ b/src/hir_typeck/common.hpp @@ -29,6 +29,23 @@ extern ::HIR::Path monomorphise_path_with(const Span& sp, const ::HIR::Path& tpl extern ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true); extern ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl); +// Wrappers to only monomorphise if required +static inline const ::HIR::TypeRef& monomorphise_type_with_opt(const Span& sp, ::HIR::TypeRef& tmp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true) { + return (monomorphise_type_needed(tpl) ? tmp = monomorphise_type_with(sp, tpl, callback, allow_infer) : tpl); +} +static inline const ::HIR::Path& monomorphise_path_with_opt(const Span& sp, ::HIR::Path& tmp, const ::HIR::Path& tpl, t_cb_generic callback, bool allow_infer=true) { + return (monomorphise_path_needed(tpl) ? tmp = monomorphise_path_with(sp, tpl, callback, allow_infer) : tpl); +} +static inline const ::HIR::GenericPath& monomorphise_genericpath_with_opt(const Span& sp, ::HIR::GenericPath& tmp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer=true) { + return (monomorphise_genericpath_needed(tpl) ? tmp = monomorphise_genericpath_with(sp, tpl, callback, allow_infer) : tpl); +} +static inline const ::HIR::TraitPath& monomorphise_traitpath_with_opt(const Span& sp, ::HIR::TraitPath& tmp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer=true) { + return (monomorphise_traitpath_needed(tpl) ? tmp = monomorphise_traitpath_with(sp, tpl, callback, allow_infer) : tpl); +} +static inline const ::HIR::PathParams& monomorphise_pathparams_with_opt(const Span& sp, ::HIR::PathParams& tmp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer=true) { + return (monomorphise_pathparams_needed(tpl) ? tmp = monomorphise_path_params_with(sp, tpl, callback, allow_infer) : tpl); +} + typedef ::std::function<bool(const ::HIR::TypeRef&)> t_cb_visit_ty; /// Calls the provided callback on every type seen when recursing the type. /// If the callback returns `true`, no further types are visited and the function returns `true`. diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index d4d16aad..0c76b4e5 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -1981,7 +1981,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, ( ), (TraitBound, - DEBUG("Trait bound - " << be.type << " : " << be.trait); + DEBUG("[expand_associated_types_inplace__UfcsKnown] Trait bound - " << be.type << " : " << be.trait); // 1. Check if the type matches // - TODO: This should be a fuzzier match? if( be.type != *pe.type ) @@ -1993,7 +1993,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, if( it == be.trait.m_type_bounds.end() ) { // If not, assume it's opaque and return as such // TODO: What happens if there's two bounds that overlap? 'F: FnMut<()>, F: FnOnce<(), Output=Bar>' - DEBUG("Found impl for " << input << " but no bound on item, assuming opaque"); + DEBUG("[expand_associated_types_inplace__UfcsKnown] Found impl for " << input << " but no bound on item, assuming opaque"); } else { assume_opaque = false; @@ -2066,6 +2066,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, } // If the type of this UfcsKnown is ALSO a UfcsKnown - Check if it's bounded by this trait with equality + // e.g. `<<Foo as Bar>::Baz as Trait2>::Type` may have an ATY bound `trait Bar { type Baz: Trait2<Type=...> }` // Use bounds on other associated types too (if `pe.type` was resolved to a fixed associated type) TU_IFLET(::HIR::TypeRef::Data, pe.type->m_data, Path, te_inner, TU_IFLET(::HIR::Path::Data, te_inner.path.m_data, UfcsKnown, pe_inner, @@ -2099,7 +2100,10 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, { // If the bound is for Self and the outer trait // - TODO: Fuzzy check the parameters? - if( bound.m_path == pe.trait ) { + ::HIR::GenericPath tmp_tp; + const auto& bound_tp = monomorphise_genericpath_with_opt(sp, tmp_tp, bound.m_path, cb_placeholders_trait); + DEBUG(bound_tp << " ?= " << pe.trait); + if( bound_tp == pe.trait ) { auto it = bound.m_type_bounds.find( pe.item ); if( it != bound.m_type_bounds.end() ) { if( monomorphise_type_needed(it->second) ) { @@ -2115,10 +2119,10 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp, } // TODO: Find trait in this trait. - const auto& bound_trait = m_crate.get_trait_by_path(sp, bound.m_path.m_path); + const auto& bound_trait = m_crate.get_trait_by_path(sp, bound_tp.m_path); bool replaced = this->find_named_trait_in_trait(sp, pe.trait.m_path,pe.trait.m_params, - bound_trait, bound.m_path.m_path,bound.m_path.m_params, *pe.type, + bound_trait, bound_tp.m_path,bound_tp.m_params, *pe.type, [&](const auto&, const auto& x, const auto& assoc){ auto it = assoc.find(pe.item); if( it != assoc.end() ) { @@ -2292,9 +2296,9 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple ) ) - //if(type.m_data.is_Infer()) { - // return false; - //} + if(type.m_data.is_Infer()) { + return false; + } // NOTE: Even if the type is completely unknown (infer or unbound UFCS), search the bound list. |