summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_conv/resolve_ufcs.cpp4
-rw-r--r--src/hir_typeck/common.hpp17
-rw-r--r--src/hir_typeck/helpers.cpp20
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.