|
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