TyTy::BaseType *receiver,
Location expr_locus)
{
+ rust_debug_loc (expr_locus, "resolve_method_address for %s and receiver %s",
+ fntype->debug_str ().c_str (),
+ receiver->debug_str ().c_str ());
+
DefId id = fntype->get_id ();
rust_assert (id != UNKNOWN_DEFID);
ctx, fntype, true, expr_locus);
}
- // FIXME this will be a case to return error_mark_node, there is
- // an error scenario where a Trait Foo has a method Bar, but this
- // receiver does not implement this trait or has an incompatible
- // implementation and we should just return error_mark_node
+ const Resolver::PathProbeCandidate *selectedCandidate = nullptr;
+ rust_debug_loc (expr_locus, "resolved to %lu candidates", candidates.size ());
+
+ // filter for the possible case of non fn type items
+ std::set<Resolver::PathProbeCandidate> filteredFunctionCandidates;
+ for (auto &candidate : candidates)
+ {
+ bool is_fntype = candidate.ty->get_kind () == TyTy::TypeKind::FNDEF;
+ if (!is_fntype)
+ continue;
+
+ filteredFunctionCandidates.insert (candidate);
+ }
+
+ // look for the exact fntype
+ for (auto &candidate : filteredFunctionCandidates)
+ {
+ bool compatable
+ = Resolver::types_compatable (TyTy::TyWithLocation (candidate.ty),
+ TyTy::TyWithLocation (fntype), expr_locus,
+ false);
+
+ rust_debug_loc (candidate.locus, "candidate: %s vs %s compatable=%s",
+ candidate.ty->debug_str ().c_str (),
+ fntype->debug_str ().c_str (),
+ compatable ? "true" : "false");
+
+ if (compatable)
+ {
+ selectedCandidate = &candidate;
+ break;
+ }
+ }
+
+ // FIXME eventually this should just return error mark node when we support
+ // going through all the passes
+ rust_assert (selectedCandidate != nullptr);
- rust_assert (candidates.size () == 1);
- auto &candidate = *candidates.begin ();
+ // lets compile it
+ const Resolver::PathProbeCandidate &candidate = *selectedCandidate;
rust_assert (candidate.is_impl_candidate ());
rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty);
--- /dev/null
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+
+impl Add for u32 {
+ type Output = u32;
+
+ fn add(self, other: u32) -> u32 {
+ self + other
+ }
+}
+
+impl<'a> Add<u32> for &'a u32 {
+ type Output = <u32 as Add<u32>>::Output;
+
+ fn add(self, other: u32) -> <u32 as Add<u32>>::Output {
+ Add::add(*self, other)
+ }
+}
+
+impl<'a> Add<&'a u32> for u32 {
+ type Output = <u32 as Add<u32>>::Output;
+
+ fn add(self, other: &'a u32) -> <u32 as Add<u32>>::Output {
+ Add::add(self, *other)
+ }
+}
--- /dev/null
+macro_rules! forward_ref_binop {
+ (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
+ forward_ref_binop!(impl $imp, $method for $t, $u,
+ #[stable(feature = "rust1", since = "1.0.0")]);
+ };
+ (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
+ #[$attr]
+ impl<'a> $imp<$u> for &'a $t {
+ type Output = <$t as $imp<$u>>::Output;
+
+ #[inline]
+ fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
+ $imp::$method(*self, other)
+ }
+ }
+
+ #[$attr]
+ impl<'a> $imp<&'a $u> for $t {
+ type Output = <$t as $imp<$u>>::Output;
+
+ #[inline]
+ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
+ $imp::$method(self, *other)
+ }
+ }
+
+ #[$attr]
+ impl<'a, 'b> $imp<&'a $u> for &'b $t {
+ type Output = <$t as $imp<$u>>::Output;
+
+ #[inline]
+ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
+ $imp::$method(*self, *other)
+ }
+ }
+ }
+}
+
+#[lang = "add"]
+pub trait Add<RHS = Self> {
+ type Output;
+
+ fn add(self, rhs: RHS) -> Self::Output;
+}
+
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl Add for $t {
+ type Output = $t;
+
+ fn add(self, other: $t) -> $t { self + other }
+ }
+
+ forward_ref_binop! { impl Add, add for $t, $t }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 /*u128*/ isize i8 i16 i32 i64 /*i128*/ f32 f64 }