aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-08-03 13:14:54 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-04 16:52:52 +0100
commit5d17a8b6b2c086d4df516de06ddacdf88728f6ba (patch)
treef35b2207aeda6e2fa6fde7fa36f986d1f9667f3b /gcc
parent79d0f29464fc0aa68af7b317964aff4bc35af59a (diff)
downloadgcc-5d17a8b6b2c086d4df516de06ddacdf88728f6ba.zip
gcc-5d17a8b6b2c086d4df516de06ddacdf88728f6ba.tar.gz
gcc-5d17a8b6b2c086d4df516de06ddacdf88728f6ba.tar.bz2
Support Autoderef coercions
This is an incremental approach to get our coercion sites more acurate to rustc. This allows us to support coercions which require a deref by sharing the code from the autoderef cycle. The eventual goal here will allow us to remove the rust-tyty-coercion rules which is messy and cannot handle logic such as DST's very well. Fixes #1198
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.h5
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc13
-rw-r--r--gcc/rust/backend/rust-compile-expr.h14
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h3
-rw-r--r--gcc/rust/backend/rust-compile.cc28
-rw-r--r--gcc/rust/typecheck/rust-autoderef.h2
-rw-r--r--gcc/rust/typecheck/rust-coercion.cc92
-rw-r--r--gcc/rust/typecheck/rust-coercion.h70
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc21
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc9
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc22
-rw-r--r--gcc/testsuite/rust/compile/generics4.rs7
-rw-r--r--gcc/testsuite/rust/compile/reference1.rs3
-rw-r--r--gcc/testsuite/rust/compile/shadow1.rs3
-rw-r--r--gcc/testsuite/rust/compile/type-bindings1.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1198.rs75
20 files changed, 330 insertions, 47 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index ee8473f..886bafb 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -118,6 +118,7 @@ GRS_OBJS = \
rust/rust-hir-type-check-pattern.o \
rust/rust-hir-type-check-expr.o \
rust/rust-hir-dot-operator.o \
+ rust/rust-coercion.o \
rust/rust-hir-type-check-base.o \
rust/rust-autoderef.o \
rust/rust-substitution-mapper.o \
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index aad0da3..5a0ac8f 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -40,9 +40,12 @@ protected:
protected:
Context *get_context () { return ctx; }
- tree coercion_site (tree rvalue, const TyTy::BaseType *actual,
+ tree coercion_site (HirId id, tree rvalue, const TyTy::BaseType *actual,
const TyTy::BaseType *expected, Location lvalue_locus,
Location rvalue_locus);
+ tree coercion_site1 (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,
const TyTy::BaseType *expected,
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 8576cf2..38d10d2 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -853,8 +853,9 @@ CompileExpr::visit (HIR::CallExpr &expr)
Location lvalue_locus
= ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
Location rvalue_locus = argument->get_locus ();
- rvalue = coercion_site (rvalue, actual, expected, lvalue_locus,
- rvalue_locus);
+ rvalue
+ = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
// add it to the list
arguments.push_back (rvalue);
@@ -951,8 +952,8 @@ CompileExpr::visit (HIR::CallExpr &expr)
Location lvalue_locus
= ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
Location rvalue_locus = argument->get_locus ();
- rvalue
- = coercion_site (rvalue, actual, expected, lvalue_locus, rvalue_locus);
+ rvalue = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
// add it to the list
args.push_back (rvalue);
@@ -1069,8 +1070,8 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
Location lvalue_locus
= ctx->get_mappings ()->lookup_location (expected->get_ty_ref ());
Location rvalue_locus = argument->get_locus ();
- rvalue
- = coercion_site (rvalue, actual, expected, lvalue_locus, rvalue_locus);
+ rvalue = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
// add it to the list
args.push_back (rvalue);
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index bc14239..9b8976d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -177,9 +177,9 @@ public:
expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
rust_assert (ok);
- rvalue
- = coercion_site (rvalue, actual, expected, expr.get_lhs ()->get_locus (),
- expr.get_rhs ()->get_locus ());
+ rvalue = coercion_site (expr.get_mappings ().get_hirid (), rvalue, actual,
+ expected, expr.get_lhs ()->get_locus (),
+ expr.get_rhs ()->get_locus ());
tree assignment
= ctx->get_backend ()->assignment_statement (lvalue, rvalue,
@@ -435,8 +435,9 @@ public:
if (ok)
{
- rvalue = coercion_site (rvalue, actual, expected, lvalue_locus,
- rvalue_locus);
+ rvalue
+ = coercion_site (argument->get_mappings ().get_hirid (), rvalue,
+ actual, expected, lvalue_locus, rvalue_locus);
}
// add it to the list
@@ -469,7 +470,8 @@ public:
// compile/torture/struct_base_init_1.rs
if (ok)
{
- rvalue = coercion_site (rvalue, actual, expected, lvalue_locus,
+ rvalue = coercion_site (argument->get_mappings ().get_hirid (),
+ rvalue, actual, expected, lvalue_locus,
rvalue_locus);
}
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index aa17a4a..9bb4b7b 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -87,7 +87,8 @@ public:
Location lvalue_locus = stmt.get_pattern ()->get_locus ();
Location rvalue_locus = stmt.get_init_expr ()->get_locus ();
TyTy::BaseType *expected = ty;
- init = coercion_site (init, actual, expected, lvalue_locus, rvalue_locus);
+ init = coercion_site (stmt.get_mappings ().get_hirid (), init, actual,
+ expected, lvalue_locus, rvalue_locus);
auto fnctx = ctx->peek_fn ();
if (ty->is_unit ())
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 4f17fa6..8a614f2 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -198,10 +198,26 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
// Shared methods in compilation
tree
-HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
+HIRCompileBase::coercion_site (HirId id, tree rvalue,
+ const TyTy::BaseType *rval,
const TyTy::BaseType *lval,
Location lvalue_locus, Location rvalue_locus)
{
+ std::vector<Resolver::Adjustment> *adjustments = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (id, &adjustments);
+ if (ok)
+ {
+ rvalue = resolve_adjustements (*adjustments, rvalue, rvalue_locus);
+ }
+
+ return coercion_site1 (rvalue, rval, lval, lvalue_locus, rvalue_locus);
+}
+
+tree
+HIRCompileBase::coercion_site1 (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;
@@ -227,8 +243,8 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
tree deref_rvalue = indirect_expression (rvalue, rvalue_locus);
tree coerced
- = coercion_site (deref_rvalue, act->get_base (), exp->get_base (),
- lvalue_locus, rvalue_locus);
+ = coercion_site1 (deref_rvalue, act->get_base (), exp->get_base (),
+ lvalue_locus, rvalue_locus);
if (exp->is_dyn_object () && SLICE_TYPE_P (TREE_TYPE (coerced)))
return coerced;
@@ -269,8 +285,10 @@ HIRCompileBase::coercion_site (tree rvalue, const TyTy::BaseType *rval,
rust_assert (actual_base != nullptr);
tree deref_rvalue = indirect_expression (rvalue, rvalue_locus);
- tree coerced = coercion_site (deref_rvalue, actual_base, exp->get_base (),
- lvalue_locus, rvalue_locus);
+ tree coerced
+ = coercion_site1 (deref_rvalue, actual_base, exp->get_base (),
+ lvalue_locus, rvalue_locus);
+
if (exp->is_dyn_object () && SLICE_TYPE_P (TREE_TYPE (coerced)))
return coerced;
diff --git a/gcc/rust/typecheck/rust-autoderef.h b/gcc/rust/typecheck/rust-autoderef.h
index 159f4c0..220b6f4 100644
--- a/gcc/rust/typecheck/rust-autoderef.h
+++ b/gcc/rust/typecheck/rust-autoderef.h
@@ -157,7 +157,7 @@ protected:
// type
virtual void try_hook (const TyTy::BaseType &);
- bool cycle (const TyTy::BaseType *receiver);
+ virtual bool cycle (const TyTy::BaseType *receiver);
bool try_autoderefed (const TyTy::BaseType *r);
diff --git a/gcc/rust/typecheck/rust-coercion.cc b/gcc/rust/typecheck/rust-coercion.cc
new file mode 100644
index 0000000..e6e82c3
--- /dev/null
+++ b/gcc/rust/typecheck/rust-coercion.cc
@@ -0,0 +1,92 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-coercion.h"
+
+namespace Rust {
+namespace Resolver {
+
+AutoderefTypeCoercion::CoercionResult
+AutoderefTypeCoercion::Coerce (const TyTy::BaseType *receiver,
+ const TyTy::BaseType *expected, Location locus)
+{
+ AutoderefTypeCoercion resolver (expected, locus);
+ bool ok = resolver.cycle (receiver);
+ return ok ? resolver.try_result : CoercionResult::get_error ();
+}
+
+AutoderefTypeCoercion::AutoderefTypeCoercion (const TyTy::BaseType *expected,
+ Location locus)
+ : AutoderefCycle (false), mappings (Analysis::Mappings::get ()),
+ context (TypeCheckContext::get ()), expected (expected), locus (locus),
+ try_result (CoercionResult::get_error ())
+{}
+
+bool
+AutoderefTypeCoercion::cycle (const TyTy::BaseType *receiver)
+{
+ // FIXME this is not finished and might be super simplified
+ // see:
+ // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
+
+ if (receiver->get_kind () == TyTy::TypeKind::REF
+ && expected->get_kind () == TyTy::TypeKind::REF)
+ {
+ // if we expect to get a mutable pointer we can't get that from an
+ // immutable one so we have to be careful
+
+ const auto &receiver_ref
+ = static_cast<const TyTy::ReferenceType &> (*receiver);
+ const auto &expected_ref
+ = static_cast<const TyTy::ReferenceType &> (*expected);
+
+ // we can allow for mutability changes here by casting down from
+ // mutability eg: mut vs const, we cant take a mutable reference from a
+ // const eg: const vs mut we can take a const reference from a mutable
+ // one
+
+ bool mutability_ok
+ = !expected_ref.is_mutable ()
+ || (expected_ref.is_mutable () == receiver_ref.is_mutable ());
+ if (!mutability_ok)
+ {
+ RichLocation r (locus);
+ r.add_range (mappings->lookup_location (receiver_ref.get_ref ()));
+ r.add_range (mappings->lookup_location (expected_ref.get_ref ()));
+ rust_error_at (r, "mismatched mutability");
+
+ return false;
+ }
+ }
+
+ return AutoderefCycle::cycle (receiver);
+}
+
+bool
+AutoderefTypeCoercion::select (const TyTy::BaseType &autoderefed)
+{
+ if (autoderefed.can_eq (expected, false))
+ {
+ try_result = CoercionResult{adjustments, autoderefed.clone ()};
+ return true;
+ }
+ return false;
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-coercion.h b/gcc/rust/typecheck/rust-coercion.h
new file mode 100644
index 0000000..c3d5d02
--- /dev/null
+++ b/gcc/rust/typecheck/rust-coercion.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_COERCION
+#define RUST_COERCION
+
+#include "rust-autoderef.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+class AutoderefTypeCoercion : protected AutoderefCycle
+{
+public:
+ struct CoercionResult
+ {
+ std::vector<Adjustment> adjustments;
+ TyTy::BaseType *tyty;
+
+ bool is_error ()
+ {
+ return tyty == nullptr || tyty->get_kind () == TyTy::TypeKind::ERROR;
+ }
+
+ static CoercionResult get_error () { return CoercionResult{{}, nullptr}; }
+ };
+
+ static CoercionResult Coerce (const TyTy::BaseType *receiver,
+ const TyTy::BaseType *expected, Location locus);
+
+protected:
+ AutoderefTypeCoercion (const TyTy::BaseType *expected, Location locus);
+
+ bool cycle (const TyTy::BaseType *receiver) override;
+
+ bool select (const TyTy::BaseType &autoderefed) override;
+
+private:
+ // context info
+ Analysis::Mappings *mappings;
+ TypeCheckContext *context;
+
+ // search
+ const TyTy::BaseType *expected;
+ Location locus;
+
+ // mutable fields
+ CoercionResult try_result;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_COERCION
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 092b635..c501998 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-hir-type-check-base.h"
+#include "rust-coercion.h"
namespace Rust {
namespace Resolver {
@@ -328,10 +329,24 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, Location locus)
}
TyTy::BaseType *
-TypeCheckBase::coercion_site (TyTy::BaseType *lhs, TyTy::BaseType *rhs,
- Location)
+TypeCheckBase::coercion_site (HirId id, TyTy::BaseType *expected,
+ TyTy::BaseType *expr, Location locus)
{
- return lhs->coerce (rhs);
+ auto context = TypeCheckContext::get ();
+ if (expected->get_kind () == TyTy::TypeKind::ERROR
+ || expr->get_kind () == TyTy::TypeKind::ERROR)
+ return expr;
+
+ // can we autoderef it?
+ auto result = AutoderefTypeCoercion::Coerce (expr, expected, locus);
+ if (!result.is_error ())
+ {
+ // save any adjustments
+ context->insert_autoderef_mappings (id, std::move (result.adjustments));
+ return expected->coerce (result.tyty);
+ }
+
+ return expected->coerce (expr);
}
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 9d53610..4078697 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -39,7 +39,7 @@ public:
virtual ~TypeCheckBase () {}
- static TyTy::BaseType *coercion_site (TyTy::BaseType *lhs,
+ static TyTy::BaseType *coercion_site (HirId id, TyTy::BaseType *lhs,
TyTy::BaseType *rhs, Location locus);
protected:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 8a0c305..de542ca 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -230,7 +230,8 @@ public:
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
- coercion_site (lhs, rhs, expr.get_locus ());
+ coercion_site (expr.get_mappings ().get_hirid (), lhs, rhs,
+ expr.get_locus ());
}
void visit (HIR::CompoundAssignmentExpr &expr) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 11f4d64..f8bf6e0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -99,7 +99,8 @@ public:
if (specified_ty != nullptr && init_expr_ty != nullptr)
{
// FIXME use this result and look at the regressions
- coercion_site (specified_ty, init_expr_ty, stmt.get_locus ());
+ coercion_site (stmt.get_mappings ().get_hirid (), specified_ty,
+ init_expr_ty, stmt.get_locus ());
context->insert_type (stmt_pattern.get_pattern_mappings (),
specified_ty);
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 736bc5e..5b52277 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -222,7 +222,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field)
TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
resolved_field_value_expr
- = coercion_site (field_type->get_field_type (), value, field.get_locus ());
+ = coercion_site (field.get_mappings ().get_hirid (),
+ field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
fields_assigned.insert (field.field_name);
@@ -252,7 +253,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field)
TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ());
resolved_field_value_expr
- = coercion_site (field_type->get_field_type (), value, field.get_locus ());
+ = coercion_site (field.get_mappings ().get_hirid (),
+ field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
fields_assigned.insert (field_name);
@@ -287,7 +289,8 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field)
TyTy::BaseType *value = TypeCheckExpr::Resolve (&expr);
resolved_field_value_expr
- = coercion_site (field_type->get_field_type (), value, field.get_locus ());
+ = coercion_site (field.get_mappings ().get_hirid (),
+ field_type->get_field_type (), value, field.get_locus ());
if (resolved_field_value_expr != nullptr)
{
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 416527e..b810bd8 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -58,7 +58,9 @@ TypeCheckCallExpr::visit (ADTType &type)
return;
}
- auto res = field_tyty->coerce (arg);
+ auto res = Resolver::TypeCheckBase::coercion_site (
+ argument->get_mappings ().get_hirid (), field_tyty, arg,
+ argument->get_locus ());
if (res->get_kind () == TyTy::TypeKind::ERROR)
{
return;
@@ -123,8 +125,9 @@ TypeCheckCallExpr::visit (FnType &type)
if (i < type.num_params ())
{
auto fnparam = type.param_at (i);
- auto resolved_argument_type
- = fnparam.second->coerce (argument_expr_tyty);
+ auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
+ argument->get_mappings ().get_hirid (), fnparam.second,
+ argument_expr_tyty, argument->get_locus ());
if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (argument->get_locus (),
@@ -176,9 +179,9 @@ TypeCheckCallExpr::visit (FnPtr &type)
return;
}
- auto resolved_argument_type
- = Resolver::TypeCheckBase::coercion_site (fnparam, argument_expr_tyty,
- argument->get_locus ());
+ auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
+ argument->get_mappings ().get_hirid (), fnparam, argument_expr_tyty,
+ argument->get_locus ());
if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (argument->get_locus (),
@@ -234,10 +237,9 @@ TypeCheckMethodCallExpr::visit (FnType &type)
return;
}
- auto resolved_argument_type
- = Resolver::TypeCheckBase::coercion_site (fnparam.second,
- argument_expr_tyty,
- argument->get_locus ());
+ auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
+ argument->get_mappings ().get_hirid (), fnparam.second,
+ argument_expr_tyty, argument->get_locus ());
if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (argument->get_locus (),
diff --git a/gcc/testsuite/rust/compile/generics4.rs b/gcc/testsuite/rust/compile/generics4.rs
index 4eaaea7..8af1358 100644
--- a/gcc/testsuite/rust/compile/generics4.rs
+++ b/gcc/testsuite/rust/compile/generics4.rs
@@ -3,10 +3,9 @@ struct GenericStruct<T>(T, usize);
fn main() {
let a2;
a2 = GenericStruct::<i8, i32>(1, 456); // { dg-error "generic item takes at most 1 type arguments but 2 were supplied" }
- // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
- // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 }
- // { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-3 }
- // { dg-error {expected \[T\?\] got \[<tyty::error>\]} "" { target *-*-* } .-4 }
+ // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+ // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 }
+ // { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-3 }
let b2: i32 = a2.0;
// { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/reference1.rs b/gcc/testsuite/rust/compile/reference1.rs
index 3d97926..ff79153 100644
--- a/gcc/testsuite/rust/compile/reference1.rs
+++ b/gcc/testsuite/rust/compile/reference1.rs
@@ -1,5 +1,6 @@
fn main() {
let a = &123;
let b: &mut i32 = a;
- // { dg-error "expected .&mut i32. got .& i32." "" { target *-*-* } .-1 }
+ // { dg-error "mismatched mutability" "" { target *-*-* } .-1 }
+ // { dg-error "expected .&mut i32. got .& i32." "" { target *-*-* } .-2 }
}
diff --git a/gcc/testsuite/rust/compile/shadow1.rs b/gcc/testsuite/rust/compile/shadow1.rs
index 730b53d..77410e9 100644
--- a/gcc/testsuite/rust/compile/shadow1.rs
+++ b/gcc/testsuite/rust/compile/shadow1.rs
@@ -3,6 +3,5 @@ fn main() {
let mut x;
x = true;
x = x + 2; // { dg-error "cannot apply this operator to types bool and <integer>" }
- // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
- // { dg-error {expected \[bool\] got \[<tyty::error>\]} "" { target *-*-* } .-2 }
+ // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs b/gcc/testsuite/rust/compile/type-bindings1.rs
index 3f61b8b4e..ad85ed9 100644
--- a/gcc/testsuite/rust/compile/type-bindings1.rs
+++ b/gcc/testsuite/rust/compile/type-bindings1.rs
@@ -7,5 +7,4 @@ fn main() {
// { dg-error {failed to type resolve expression} "" { target *-*-* } .-2 }
// { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-3 }
// { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-4 }
- // { dg-error {expected \[T\?\] got \[<tyty::error>\]} "" { target *-*-* } .-5 }
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1198.rs b/gcc/testsuite/rust/execute/torture/issue-1198.rs
new file mode 100644
index 0000000..fce44ad
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1198.rs
@@ -0,0 +1,75 @@
+/* { dg-output "foo_deref\nimm_deref\n123\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+ type Target;
+
+ fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ unsafe {
+ let a = "imm_deref\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+
+ *self
+ }
+}
+
+impl<T> Deref for &mut T {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ unsafe {
+ let a = "mut_deref\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+
+ *self
+ }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ unsafe {
+ let a = "foo_deref\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+
+ &self.0
+ }
+}
+
+fn main() -> i32 {
+ let foo: Foo<i32> = Foo(123);
+ let bar: &i32 = &foo;
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, *bar);
+ }
+
+ 0
+}