TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup_fntype);
TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_receiver ().get_mappings ().get_hirid (), &receiver);
rust_assert (ok);
bool is_dyn_dispatch
TyTy::BaseType *receiver = nullptr;
bool ok
- = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
- &receiver);
+ = ctx->get_tyctx ()->lookup_type (lhs_expr.get_mappings ().get_hirid (),
+ &receiver);
rust_assert (ok);
bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
#include "rust-compile-item.h"
#include "rust-compile-implitem.h"
#include "rust-compile-extern.h"
+#include "rust-substitution-mapper.h"
+#include "rust-type-util.h"
#include "rust-immutable-name-resolution-context.h"
namespace Rust {
// is given
if (concrete == nullptr)
return;
- else
+
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *concrete_fnty = static_cast<TyTy::FnType *> (concrete);
+ bool is_trait_item_concrete
+ = ctx->get_mappings ()
+ .lookup_trait_item_defid (concrete_fnty->get_id ())
+ .has_value ();
+ if (!is_trait_item_concrete)
{
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
fntype = static_cast<TyTy::FnType *> (concrete);
- fntype->monomorphize ();
}
+ else
+ {
+ TyTy::BaseType *infer
+ = Resolver::SubstMapper::InferSubst (fntype, function.get_locus ());
+ TyTy::BaseType *resolved
+ = Resolver::unify_site (function.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (infer),
+ TyTy::TyWithLocation (concrete),
+ function.get_locus ());
+
+ rust_assert (resolved->is<TyTy::FnType> ());
+ fntype = resolved->as<TyTy::FnType> ();
+ }
+
+ fntype->monomorphize ();
}
else
{
trait->get_mappings ().get_defid (), &trait_ref);
rust_assert (ok);
- TyTy::BaseType *receiver = nullptr;
- ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (),
- &receiver);
- rust_assert (ok);
- receiver = receiver->destructure ();
-
// the type resolver can only resolve type bounds to their trait
// item so its up to us to figure out if this path should resolve
// to an trait-impl-block-item or if it can be defaulted to the
// trait-impl-item's definition
+ //
+ // because we know this is resolved to a trait item we can actually
+ // just grab the Self type parameter here for the receiver to match
+ // the appropriate impl block
+
+ rust_assert (lookup->is<TyTy::FnType> ());
+ auto fn = lookup->as<TyTy::FnType> ();
+ rust_assert (fn->get_num_type_params () > 0);
+ auto &self = fn->get_substs ().at (0);
+ auto receiver = self.get_param_ty ();
auto candidates
= Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
trait_ref);
return;
}
- context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
-
rust_debug_loc (expr.get_locus (), "attempting to resolve method for %s",
receiver_tyty->debug_str ().c_str ());
auto candidates
context->insert_autoderef_mappings (expr.get_lvalue_mappings ().get_hirid (),
std::move (candidate.adjustments));
- // now its just like a method-call-expr
- context->insert_receiver (expr.get_mappings ().get_hirid (), lhs);
-
PathProbeCandidate &resolved_candidate = candidate.candidate;
TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
NodeId resolved_node_id
HirId autoderef_mappings_id = fnexpr.get_mappings ().get_hirid ();
context->insert_autoderef_mappings (autoderef_mappings_id,
std::move (candidate.adjustments));
- context->insert_receiver (expr.get_mappings ().get_hirid (), receiver_tyty);
PathProbeCandidate &resolved_candidate = candidate.candidate;
TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
root_resolved_node_id);
}
- context->insert_receiver (expr.get_mappings ().get_hirid (), root);
return;
}
}
rust_assert (resolved_node_id != UNKNOWN_NODEID);
- context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
-
if (flag_name_resolution_2_0)
{
auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
resolver->insert_resolved_type (path.get_mappings ().get_nodeid (),
root_resolved_node_id);
}
-
- context->insert_receiver (path.get_mappings ().get_hirid (), root);
return;
}
}
}
- context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
rust_assert (resolved_node_id != UNKNOWN_NODEID);
-
if (flag_name_resolution_2_0)
{
auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
void insert_trait_reference (DefId id, TraitReference &&ref);
bool lookup_trait_reference (DefId id, TraitReference **ref);
- void insert_receiver (HirId id, TyTy::BaseType *t);
- bool lookup_receiver (HirId id, TyTy::BaseType **ref);
-
void insert_associated_trait_impl (HirId id,
AssociatedImplTrait &&associated);
bool lookup_associated_trait_impl (HirId id,
std::vector<TyTy::BaseType *> loop_type_stack;
StackedContexts<TypeCheckBlockContextItem> block_stack;
std::map<DefId, TraitReference> trait_context;
- std::map<HirId, TyTy::BaseType *> receiver_context;
std::map<HirId, AssociatedImplTrait> associated_impl_traits;
// trait-id -> list of < self-tyty:impl-id>
return true;
}
-void
-TypeCheckContext::insert_receiver (HirId id, TyTy::BaseType *t)
-{
- receiver_context[id] = t;
-}
-
-bool
-TypeCheckContext::lookup_receiver (HirId id, TyTy::BaseType **ref)
-{
- auto it = receiver_context.find (id);
- if (it == receiver_context.end ())
- return false;
-
- *ref = it->second;
- return true;
-}
-
void
TypeCheckContext::insert_associated_trait_impl (
HirId id, AssociatedImplTrait &&associated)
--- /dev/null
+/* { dg-output "Err: 15\r*\n" } */
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ #[lang = "Ok"]
+ Ok(T),
+ #[lang = "Err"]
+ Err(E),
+}
+
+#[lang = "try"]
+pub trait Try {
+ type Ok;
+ type Error;
+
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Ok) -> Self;
+
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Error) -> Self;
+}
+
+impl<T, E> Try for Result<T, E> {
+ type Ok = T;
+ type Error = E;
+
+ fn into_result(self) -> Result<T, E> {
+ self
+ }
+
+ fn from_ok(v: T) -> Self {
+ Result::Ok(v)
+ }
+
+ fn from_error(v: E) -> Self {
+ Result::Err(v)
+ }
+}
+
+pub trait From<T>: Sized {
+ fn from(_: T) -> Self;
+}
+
+impl<T> From<T> for T {
+ fn from(t: T) -> Self {
+ t
+ }
+}
+
+fn print(s: &str, value: i32) {
+ extern "C" {
+ fn printf(s: *const i8, ...);
+ }
+
+ unsafe {
+ printf(s as *const str as *const i8, value);
+ }
+}
+
+fn baz() -> Result<i32, i32> {
+ Result::Err(15)
+}
+
+fn foo() -> Result<i32, i32> {
+ let b = match baz() {
+ Result::Ok(value) => value,
+ Result::Err(err) => {
+ return Try::from_error(From::from(err));
+ }
+ };
+
+ Result::Ok(15 + b)
+}
+
+fn main() -> i32 {
+ let a = foo();
+ match a {
+ Result::Ok(value) => print("Ok: %i\n", value),
+ Result::Err(err) => print("Err: %i\n", err),
+ };
+
+ 0
+}