From afa451b311dec27476941e6f307d04450d28ab88 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Mon, 21 Mar 2022 12:40:20 +0000 Subject: Add initial support for unsized method resolution In order to support slices, we end up with an operator overload call of: ``` impl Index for [T] where I: SliceIndex<[T]>, { type Output = I::Output; fn index(&self, index: I) -> &I::Output { index.index(self) } } ``` So this means the self in this case is an array[T,capacity] and the index parameter is of type Range. In order to actually call this method which has a self parameter of [T] we need to be able to 'unsize' the array into a slice. Addresses #849 --- gcc/rust/backend/rust-compile-base.h | 3 +++ gcc/rust/backend/rust-compile-expr.cc | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index c30aa4d..c7f7f40 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -72,6 +72,9 @@ protected: 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); diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 03e3c2e..74ab6a4 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -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; } } @@ -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) { -- cgit v1.1