aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-05-06 12:46:13 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-05-09 11:30:48 +0100
commit55346cc59b766266202a0ba2114275eb2fc53dda (patch)
tree652828c92c611dee3a451ee3ffd48ba2ac778800
parent74e836599ce80a11b1fe28065ed7aae6ffa3b7e2 (diff)
downloadgcc-55346cc59b766266202a0ba2114275eb2fc53dda.zip
gcc-55346cc59b766266202a0ba2114275eb2fc53dda.tar.gz
gcc-55346cc59b766266202a0ba2114275eb2fc53dda.tar.bz2
Destructure our generics, placeholers or projections during coercion
When we coerce types we need to destructure from the generics in order to apply these coercion rules correctly or we end up returning a bad error_mark_node.
-rw-r--r--gcc/rust/backend/rust-compile-base.h4
-rw-r--r--gcc/rust/backend/rust-compile.cc25
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc32
-rw-r--r--gcc/rust/typecheck/rust-tyty.h5
4 files changed, 55 insertions, 11 deletions
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 77e6cc3..52e0568 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -40,8 +40,8 @@ protected:
protected:
Context *get_context () { return ctx; }
- tree coercion_site (tree rvalue, TyTy::BaseType *actual,
- TyTy::BaseType *expected, Location lvalue_locus,
+ tree coercion_site (tree rvalue, const TyTy::BaseType *actual,
+ const TyTy::BaseType *expected, Location lvalue_locus,
Location rvalue_locus);
tree coerce_to_dyn_object (tree compiled_ref, const TyTy::BaseType *actual,
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 49155d2..d9349d5 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -198,21 +198,26 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
// Shared methods in compilation
tree
-HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual,
- TyTy::BaseType *expected, Location lvalue_locus,
- Location rvalue_locus)
+HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
+ const TyTy::BaseType *lval,
+ Location lvalue_locus, Location rvalue_locus)
{
if (rvalue == error_mark_node)
return error_mark_node;
+ const TyTy::BaseType *actual = rval->destructure ();
+ const TyTy::BaseType *expected = lval->destructure ();
+
if (expected->get_kind () == TyTy::TypeKind::REF)
{
// bad coercion... of something to a reference
if (actual->get_kind () != TyTy::TypeKind::REF)
return error_mark_node;
- TyTy::ReferenceType *exp = static_cast<TyTy::ReferenceType *> (expected);
- TyTy::ReferenceType *act = static_cast<TyTy::ReferenceType *> (actual);
+ const TyTy::ReferenceType *exp
+ = static_cast<const TyTy::ReferenceType *> (expected);
+ const TyTy::ReferenceType *act
+ = static_cast<const TyTy::ReferenceType *> (actual);
tree expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
tree deref_rvalue
@@ -235,20 +240,22 @@ HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual,
if (!valid_coercion)
return error_mark_node;
- TyTy::ReferenceType *exp = static_cast<TyTy::ReferenceType *> (expected);
+ const TyTy::ReferenceType *exp
+ = static_cast<const TyTy::ReferenceType *> (expected);
TyTy::BaseType *actual_base = nullptr;
tree expected_type = error_mark_node;
if (actual->get_kind () == TyTy::TypeKind::REF)
{
- TyTy::ReferenceType *act
- = static_cast<TyTy::ReferenceType *> (actual);
+ const TyTy::ReferenceType *act
+ = static_cast<const TyTy::ReferenceType *> (actual);
actual_base = act->get_base ();
expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
}
else if (actual->get_kind () == TyTy::TypeKind::POINTER)
{
- TyTy::PointerType *act = static_cast<TyTy::PointerType *> (actual);
+ const TyTy::PointerType *act
+ = static_cast<const TyTy::PointerType *> (actual);
actual_base = act->get_base ();
expected_type = TyTyResolveCompile::compile (ctx, act->get_base ());
}
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index fcbf998..09f5e4c 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -229,6 +229,38 @@ BaseType::get_root () const
return root;
}
+const BaseType *
+BaseType::destructure () const
+{
+ switch (get_kind ())
+ {
+ case TyTy::TypeKind::PARAM: {
+ const TyTy::ParamType *p = static_cast<const TyTy::ParamType *> (this);
+ return p->resolve ();
+ }
+ break;
+
+ case TyTy::TypeKind::PLACEHOLDER: {
+ const TyTy::PlaceholderType *p
+ = static_cast<const TyTy::PlaceholderType *> (this);
+ rust_assert (p->can_resolve ());
+ return p->resolve ();
+ }
+ break;
+
+ case TyTy::TypeKind::PROJECTION: {
+ const TyTy::ProjectionType *p
+ = static_cast<const TyTy::ProjectionType *> (this);
+ return p->get ();
+ }
+
+ default:
+ return this;
+ }
+
+ return this;
+}
+
TyVar::TyVar (HirId ref) : ref (ref)
{
// ensure this reference is defined within the context
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index b00237c..8517b72 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -253,8 +253,13 @@ public:
debug_str ().c_str ());
}
+ // FIXME this will eventually go away
const BaseType *get_root () const;
+ // This will get the monomorphized type from Params, Placeholders or
+ // Projections if available or error
+ const BaseType *destructure () const;
+
const RustIdent &get_ident () const { return ident; }
Location get_locus () const { return ident.locus; }