Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for unsized method resolution #1045

Merged
merged 1 commit into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gcc/rust/backend/rust-compile-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class HIRCompileBase
tree resolve_indirection_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);

tree resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);

static void setup_attributes_on_fndecl (
tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility,
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
Expand Down
30 changes: 30 additions & 0 deletions gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,10 @@ HIRCompileBase::resolve_adjustements (
case Resolver::Adjustment::AdjustmentType::INDIRECTION:
e = resolve_indirection_adjustment (adjustment, e, locus);
break;

case Resolver::Adjustment::AdjustmentType::UNSIZE:
e = resolve_unsized_adjustment (adjustment, e, locus);
break;
}
}

Expand Down Expand Up @@ -1257,6 +1261,32 @@ HIRCompileBase::resolve_indirection_adjustment (
locus);
}

tree
HIRCompileBase::resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus)
{
// assumes this is an array
tree expr_type = TREE_TYPE (expression);
rust_assert (TREE_CODE (expr_type) == ARRAY_TYPE);

// takes an array and returns a fat-pointer so this becomes a constructor
// expression
rust_assert (adjustment.get_expected ()->get_kind ()
== TyTy::TypeKind::SLICE);
tree fat_pointer
= TyTyResolveCompile::compile (ctx, adjustment.get_expected ());

// make a constructor for this
tree data = address_expression (expression, locus);

// fetch the size from the domain
tree domain = TYPE_DOMAIN (expr_type);
tree size = TYPE_MAX_VALUE (domain);

return ctx->get_backend ()->constructor_expression (fat_pointer, false,
{data, size}, -1, locus);
}

void
CompileExpr::visit (HIR::IdentifierExpr &expr)
{
Expand Down
21 changes: 21 additions & 0 deletions gcc/rust/typecheck/rust-autoderef.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@ Adjuster::try_raw_deref_type (const TyTy::BaseType *ty)
return Adjustment (Adjustment::AdjustmentType::INDIRECTION, infered);
}

Adjustment
Adjuster::try_unsize_type (const TyTy::BaseType *ty)
{
bool is_valid_type = ty->get_kind () == TyTy::TypeKind::ARRAY;
if (!is_valid_type)
return Adjustment::get_error ();

auto mappings = Analysis::Mappings::get ();
auto context = TypeCheckContext::get ();

const auto ref_base = static_cast<const TyTy::ArrayType *> (ty);
auto slice_elem = ref_base->get_element_type ();

auto slice
= new TyTy::SliceType (mappings->get_next_hir_id (), ty->get_ident ().locus,
TyTy::TyVar (slice_elem->get_ref ()));
context->insert_implicit_type (slice);

return Adjustment (Adjustment::AdjustmentType::INDIRECTION, slice);
}

static bool
resolve_operator_overload_fn (
Analysis::RustLangItem::ItemType lang_item_type, const TyTy::BaseType *ty,
Expand Down
5 changes: 5 additions & 0 deletions gcc/rust/typecheck/rust-autoderef.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Adjustment
DEREF,
DEREF_MUT,
INDIRECTION,
UNSIZE,
};

// ctor for all adjustments except derefs
Expand Down Expand Up @@ -78,6 +79,8 @@ class Adjustment
return "DEREF_MUT";
case AdjustmentType::INDIRECTION:
return "INDIRECTION";
case AdjustmentType::UNSIZE:
return "UNSIZE";
}
gcc_unreachable ();
return "";
Expand Down Expand Up @@ -135,6 +138,8 @@ class Adjuster

static Adjustment try_raw_deref_type (const TyTy::BaseType *ty);

static Adjustment try_unsize_type (const TyTy::BaseType *ty);

private:
const TyTy::BaseType *base;
};
Expand Down
15 changes: 15 additions & 0 deletions gcc/rust/typecheck/rust-hir-dot-operator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ MethodResolver::Probe (const TyTy::BaseType *receiver,
if (autoderef_flag)
return MethodCandidate::get_error ();

// try unsize
Adjustment unsize = Adjuster::try_unsize_type (r);
if (!unsize.is_error ())
{
adjustments.push_back (unsize);
auto unsize_r = unsize.get_expected ();
auto res = Try (unsize_r, segment_name, adjustments);
if (!res.is_error ())
{
return res;
}

adjustments.pop_back ();
}

Adjustment deref
= Adjuster::try_deref_type (r, Analysis::RustLangItem::ItemType::DEREF);
if (!deref.is_error ())
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/typecheck/rust-hir-type-check.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class TypeCheckContext

void insert_type (const Analysis::NodeMapping &mappings,
TyTy::BaseType *type);
void insert_implicit_type (TyTy::BaseType *type);
bool lookup_type (HirId id, TyTy::BaseType **type);

void insert_implicit_type (HirId id, TyTy::BaseType *type);
Expand Down
7 changes: 7 additions & 0 deletions gcc/rust/typecheck/rust-tyctx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
resolved[id] = type;
}

void
TypeCheckContext::insert_implicit_type (TyTy::BaseType *type)
{
rust_assert (type != nullptr);
resolved[type->get_ref ()] = type;
}

void
TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
{
Expand Down