|
17 | 17 | // <http://www.gnu.org/licenses/>.
|
18 | 18 |
|
19 | 19 | #include "optional.h"
|
| 20 | +#include "rust-common.h" |
20 | 21 | #include "rust-hir-expr.h"
|
21 | 22 | #include "rust-system.h"
|
22 | 23 | #include "rust-tyty-call.h"
|
@@ -59,6 +60,19 @@ TypeCheckExpr::Resolve (HIR::Expr &expr)
|
59 | 60 | return resolver.infered;
|
60 | 61 | }
|
61 | 62 |
|
| 63 | +TyTy::BaseType * |
| 64 | +TypeCheckExpr::ResolveOpOverload (LangItem::Kind lang_item_type, |
| 65 | + HIR::OperatorExprMeta expr, |
| 66 | + TyTy::BaseType *lhs, TyTy::BaseType *rhs, |
| 67 | + HIR::PathIdentSegment specified_segment) |
| 68 | +{ |
| 69 | + TypeCheckExpr resolver; |
| 70 | + |
| 71 | + resolver.resolve_operator_overload (lang_item_type, expr, lhs, rhs, |
| 72 | + specified_segment); |
| 73 | + return resolver.infered; |
| 74 | +} |
| 75 | + |
62 | 76 | void
|
63 | 77 | TypeCheckExpr::visit (HIR::TupleIndexExpr &expr)
|
64 | 78 | {
|
@@ -1885,7 +1899,16 @@ TypeCheckExpr::resolve_operator_overload (
|
1885 | 1899 | // probe for the lang-item
|
1886 | 1900 | if (!lang_item_defined)
|
1887 | 1901 | return false;
|
| 1902 | + |
1888 | 1903 | DefId &respective_lang_item_id = lang_item_defined.value ();
|
| 1904 | + auto def_lookup = mappings.lookup_defid (respective_lang_item_id); |
| 1905 | + rust_assert (def_lookup.has_value ()); |
| 1906 | + |
| 1907 | + HIR::Item *def_item = def_lookup.value (); |
| 1908 | + rust_assert (def_item->get_item_kind () == HIR::Item::ItemKind::Trait); |
| 1909 | + HIR::Trait &trait = *static_cast<HIR::Trait *> (def_item); |
| 1910 | + TraitReference *defid_trait_reference = TraitResolver::Resolve (trait); |
| 1911 | + rust_assert (!defid_trait_reference->is_error ()); |
1889 | 1912 |
|
1890 | 1913 | // we might be in a static or const context and unknown is fine
|
1891 | 1914 | TypeCheckContextItem current_context = TypeCheckContextItem::get_error ();
|
@@ -1929,15 +1952,49 @@ TypeCheckExpr::resolve_operator_overload (
|
1929 | 1952 |
|
1930 | 1953 | if (selected_candidates.size () > 1)
|
1931 | 1954 | {
|
1932 |
| - // mutliple candidates |
1933 |
| - rich_location r (line_table, expr.get_locus ()); |
1934 |
| - for (auto &c : resolved_candidates) |
1935 |
| - r.add_range (c.candidate.locus); |
| 1955 | + auto infer |
| 1956 | + = TyTy::TyVar::get_implicit_infer_var (expr.get_locus ()).get_tyty (); |
| 1957 | + auto trait_subst = defid_trait_reference->get_trait_substs (); |
| 1958 | + rust_assert (trait_subst.size () > 0); |
1936 | 1959 |
|
1937 |
| - rust_error_at ( |
1938 |
| - r, "multiple candidates found for possible operator overload"); |
| 1960 | + TyTy::TypeBoundPredicate pred (respective_lang_item_id, trait_subst, |
| 1961 | + BoundPolarity::RegularBound, |
| 1962 | + expr.get_locus ()); |
1939 | 1963 |
|
1940 |
| - return false; |
| 1964 | + std::vector<TyTy::SubstitutionArg> mappings; |
| 1965 | + auto &self_param_mapping = trait_subst[0]; |
| 1966 | + mappings.push_back (TyTy::SubstitutionArg (&self_param_mapping, lhs)); |
| 1967 | + |
| 1968 | + if (rhs != nullptr) |
| 1969 | + { |
| 1970 | + rust_assert (trait_subst.size () == 2); |
| 1971 | + auto &rhs_param_mapping = trait_subst[1]; |
| 1972 | + mappings.push_back (TyTy::SubstitutionArg (&rhs_param_mapping, lhs)); |
| 1973 | + } |
| 1974 | + |
| 1975 | + std::map<std::string, TyTy::BaseType *> binding_args; |
| 1976 | + binding_args["Output"] = infer; |
| 1977 | + |
| 1978 | + TyTy::SubstitutionArgumentMappings arg_mappings (mappings, binding_args, |
| 1979 | + TyTy::RegionParamList ( |
| 1980 | + trait_subst.size ()), |
| 1981 | + expr.get_locus ()); |
| 1982 | + pred.apply_argument_mappings (arg_mappings, false); |
| 1983 | + |
| 1984 | + infer->inherit_bounds ({pred}); |
| 1985 | + DeferredOpOverload defer (expr.get_mappings ().get_hirid (), |
| 1986 | + lang_item_type, specified_segment, pred, expr); |
| 1987 | + context->insert_deferred_operator_overload (std::move (defer)); |
| 1988 | + |
| 1989 | + if (rhs != nullptr) |
| 1990 | + lhs = unify_site (expr.get_mappings ().get_hirid (), |
| 1991 | + TyTy::TyWithLocation (lhs), |
| 1992 | + TyTy::TyWithLocation (rhs), expr.get_locus ()); |
| 1993 | + |
| 1994 | + infered = unify_site (expr.get_mappings ().get_hirid (), |
| 1995 | + TyTy::TyWithLocation (lhs), |
| 1996 | + TyTy::TyWithLocation (infer), expr.get_locus ()); |
| 1997 | + return true; |
1941 | 1998 | }
|
1942 | 1999 |
|
1943 | 2000 | // Get the adjusted self
|
|
0 commit comments