|
25 | 25 | #include "rust-hir-type-check-pattern.h"
|
26 | 26 | #include "rust-hir-type-check-expr.h"
|
27 | 27 | #include "rust-hir-type-check-stmt.h"
|
| 28 | +#include "rust-hir-type-check-item.h" |
28 | 29 | #include "rust-type-util.h"
|
29 | 30 |
|
30 | 31 | namespace Rust {
|
@@ -1122,58 +1123,31 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
|
1122 | 1123 | }
|
1123 | 1124 |
|
1124 | 1125 | fn->prepare_higher_ranked_bounds ();
|
1125 |
| - auto root = receiver_tyty->get_root (); |
1126 |
| - if (root->get_kind () == TyTy::TypeKind::ADT) |
| 1126 | + rust_debug_loc (expr.get_locus (), "resolved method call to: {%u} {%s}", |
| 1127 | + candidate.candidate.ty->get_ref (), |
| 1128 | + candidate.candidate.ty->debug_str ().c_str ()); |
| 1129 | + |
| 1130 | + if (resolved_candidate.is_impl_candidate ()) |
1127 | 1131 | {
|
1128 |
| - const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (root); |
1129 |
| - if (adt->has_substitutions () && fn->needs_substitution ()) |
| 1132 | + auto infer_arguments = TyTy::SubstitutionArgumentMappings::error (); |
| 1133 | + HIR::ImplBlock &impl = *resolved_candidate.item.impl.parent; |
| 1134 | + TyTy::BaseType *impl_self_infer |
| 1135 | + = TypeCheckItem::ResolveImplBlockSelfWithInference (impl, |
| 1136 | + expr.get_locus (), |
| 1137 | + &infer_arguments); |
| 1138 | + if (impl_self_infer->get_kind () == TyTy::TypeKind::ERROR) |
1130 | 1139 | {
|
1131 |
| - // consider the case where we have: |
1132 |
| - // |
1133 |
| - // struct Foo<X,Y>(X,Y); |
1134 |
| - // |
1135 |
| - // impl<T> Foo<T, i32> { |
1136 |
| - // fn test<X>(self, a:X) -> (T,X) { (self.0, a) } |
1137 |
| - // } |
1138 |
| - // |
1139 |
| - // In this case we end up with an fn type of: |
1140 |
| - // |
1141 |
| - // fn <T,X> test(self:Foo<T,i32>, a:X) -> (T,X) |
1142 |
| - // |
1143 |
| - // This means the instance or self we are calling this method for |
1144 |
| - // will be substituted such that we can get the inherited type |
1145 |
| - // arguments but then need to use the turbo fish if available or |
1146 |
| - // infer the remaining arguments. Luckily rust does not allow for |
1147 |
| - // default types GenericParams on impl blocks since these must |
1148 |
| - // always be at the end of the list |
1149 |
| - |
1150 |
| - auto s = fn->get_self_type ()->get_root (); |
1151 |
| - rust_assert (s->can_eq (adt, false)); |
1152 |
| - rust_assert (s->get_kind () == TyTy::TypeKind::ADT); |
1153 |
| - const TyTy::ADTType *self_adt |
1154 |
| - = static_cast<const TyTy::ADTType *> (s); |
1155 |
| - |
1156 |
| - // we need to grab the Self substitutions as the inherit type |
1157 |
| - // parameters for this |
1158 |
| - if (self_adt->needs_substitution ()) |
1159 |
| - { |
1160 |
| - rust_assert (adt->was_substituted ()); |
1161 |
| - |
1162 |
| - TyTy::SubstitutionArgumentMappings used_args_in_prev_segment |
1163 |
| - = GetUsedSubstArgs::From (adt); |
1164 |
| - |
1165 |
| - TyTy::SubstitutionArgumentMappings inherit_type_args |
1166 |
| - = self_adt->solve_mappings_from_receiver_for_self ( |
1167 |
| - used_args_in_prev_segment); |
1168 |
| - |
1169 |
| - // there may or may not be inherited type arguments |
1170 |
| - if (!inherit_type_args.is_error ()) |
1171 |
| - { |
1172 |
| - // need to apply the inherited type arguments to the |
1173 |
| - // function |
1174 |
| - lookup = fn->handle_substitions (inherit_type_args); |
1175 |
| - } |
1176 |
| - } |
| 1140 | + rich_location r (line_table, expr.get_locus ()); |
| 1141 | + r.add_range (impl.get_type ()->get_locus ()); |
| 1142 | + rust_error_at ( |
| 1143 | + r, "failed to resolve impl type for method call resolution"); |
| 1144 | + return; |
| 1145 | + } |
| 1146 | + |
| 1147 | + if (!infer_arguments.is_empty ()) |
| 1148 | + { |
| 1149 | + lookup = SubstMapperInternal::Resolve (lookup, infer_arguments); |
| 1150 | + lookup->debug (); |
1177 | 1151 | }
|
1178 | 1152 | }
|
1179 | 1153 |
|
@@ -1687,6 +1661,24 @@ TypeCheckExpr::resolve_operator_overload (
|
1687 | 1661 | rust_debug ("is_impl_item_candidate: %s",
|
1688 | 1662 | resolved_candidate.is_impl_candidate () ? "true" : "false");
|
1689 | 1663 |
|
| 1664 | + if (resolved_candidate.is_impl_candidate ()) |
| 1665 | + { |
| 1666 | + auto infer_arguments = TyTy::SubstitutionArgumentMappings::error (); |
| 1667 | + HIR::ImplBlock &impl = *resolved_candidate.item.impl.parent; |
| 1668 | + TyTy::BaseType *impl_self_infer |
| 1669 | + = TypeCheckItem::ResolveImplBlockSelfWithInference (impl, |
| 1670 | + expr.get_locus (), |
| 1671 | + &infer_arguments); |
| 1672 | + if (impl_self_infer->get_kind () == TyTy::TypeKind::ERROR) |
| 1673 | + { |
| 1674 | + return false; |
| 1675 | + } |
| 1676 | + if (!infer_arguments.is_empty ()) |
| 1677 | + { |
| 1678 | + lookup = SubstMapperInternal::Resolve (lookup, infer_arguments); |
| 1679 | + } |
| 1680 | + } |
| 1681 | + |
1690 | 1682 | // in the case where we resolve to a trait bound we have to be careful we are
|
1691 | 1683 | // able to do so there is a case where we are currently resolving the deref
|
1692 | 1684 | // operator overload function which is generic and this might resolve to the
|
@@ -1735,61 +1727,6 @@ TypeCheckExpr::resolve_operator_overload (
|
1735 | 1727 | candidate.candidate.ty->get_ref (),
|
1736 | 1728 | candidate.candidate.ty->debug_str ().c_str ());
|
1737 | 1729 |
|
1738 |
| - auto root = lhs->get_root (); |
1739 |
| - if (root->get_kind () == TyTy::TypeKind::ADT) |
1740 |
| - { |
1741 |
| - const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (root); |
1742 |
| - if (adt->has_substitutions () && fn->needs_substitution ()) |
1743 |
| - { |
1744 |
| - // consider the case where we have: |
1745 |
| - // |
1746 |
| - // struct Foo<X,Y>(X,Y); |
1747 |
| - // |
1748 |
| - // impl<T> Foo<T, i32> { |
1749 |
| - // fn test<X>(self, a:X) -> (T,X) { (self.0, a) } |
1750 |
| - // } |
1751 |
| - // |
1752 |
| - // In this case we end up with an fn type of: |
1753 |
| - // |
1754 |
| - // fn <T,X> test(self:Foo<T,i32>, a:X) -> (T,X) |
1755 |
| - // |
1756 |
| - // This means the instance or self we are calling this method for |
1757 |
| - // will be substituted such that we can get the inherited type |
1758 |
| - // arguments but then need to use the turbo fish if available or |
1759 |
| - // infer the remaining arguments. Luckily rust does not allow for |
1760 |
| - // default types GenericParams on impl blocks since these must |
1761 |
| - // always be at the end of the list |
1762 |
| - |
1763 |
| - auto s = fn->get_self_type ()->get_root (); |
1764 |
| - rust_assert (s->can_eq (adt, false)); |
1765 |
| - rust_assert (s->get_kind () == TyTy::TypeKind::ADT); |
1766 |
| - const TyTy::ADTType *self_adt |
1767 |
| - = static_cast<const TyTy::ADTType *> (s); |
1768 |
| - |
1769 |
| - // we need to grab the Self substitutions as the inherit type |
1770 |
| - // parameters for this |
1771 |
| - if (self_adt->needs_substitution ()) |
1772 |
| - { |
1773 |
| - rust_assert (adt->was_substituted ()); |
1774 |
| - |
1775 |
| - TyTy::SubstitutionArgumentMappings used_args_in_prev_segment |
1776 |
| - = GetUsedSubstArgs::From (adt); |
1777 |
| - |
1778 |
| - TyTy::SubstitutionArgumentMappings inherit_type_args |
1779 |
| - = self_adt->solve_mappings_from_receiver_for_self ( |
1780 |
| - used_args_in_prev_segment); |
1781 |
| - |
1782 |
| - // there may or may not be inherited type arguments |
1783 |
| - if (!inherit_type_args.is_error ()) |
1784 |
| - { |
1785 |
| - // need to apply the inherited type arguments to the |
1786 |
| - // function |
1787 |
| - lookup = fn->handle_substitions (inherit_type_args); |
1788 |
| - } |
1789 |
| - } |
1790 |
| - } |
1791 |
| - } |
1792 |
| - |
1793 | 1730 | // handle generics
|
1794 | 1731 | if (lookup->needs_generic_substitutions ())
|
1795 | 1732 | lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
|
|
0 commit comments