aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/ast/rust-ast-dump.cc32
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h14
-rw-r--r--gcc/testsuite/rust/compile/issue-1383.rs8
4 files changed, 58 insertions, 12 deletions
diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index f4bff44..3b02d84 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -48,7 +48,11 @@ void
Dump::go (AST::Crate &crate)
{
for (auto &item : crate.items)
- item->accept_vis (*this);
+ {
+ stream << indentation;
+ item->accept_vis (*this);
+ stream << "\n";
+ }
}
void
@@ -433,8 +437,12 @@ Dump::visit (AsyncBlockExpr &expr)
void
Dump::visit (TypeParam &param)
{
- // Is it possible to have a null type here?
- param.get_type ()->accept_vis (*this);
+ stream << param.get_type_representation ();
+ if (param.has_type ())
+ {
+ stream << ": ";
+ param.get_type ()->accept_vis (*this);
+ }
}
void
@@ -505,8 +513,24 @@ Dump::visit (UseDeclaration &use_decl)
void
Dump::visit (Function &function)
{
- stream << indentation << "fn " << function.get_function_name () << '(';
+ stream << "fn " << function.get_function_name ();
+
+ if (function.has_generics ())
+ {
+ stream << "<";
+ for (size_t i = 0; i < function.get_generic_params ().size (); i++)
+ {
+ auto &param = function.get_generic_params ().at (i);
+ param->accept_vis (*this);
+
+ bool has_next = (i + 1) < function.get_generic_params ().size ();
+ if (has_next)
+ stream << ", ";
+ }
+ stream << ">";
+ }
+ stream << '(';
auto &params = function.get_function_params ();
if (params.size () >= 1)
{
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 57a952f..65eddfa 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -542,9 +542,19 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
// BUILTIN transmute FN BODY BEGIN
tree result_type_tree = TREE_TYPE (DECL_RESULT (fndecl));
- tree result_expr
- = ctx->get_backend ()->convert_expression (result_type_tree,
- convert_me_expr, Location ());
+ tree result_expr = error_mark_node;
+ if (AGGREGATE_TYPE_P (TREE_TYPE (convert_me_expr)))
+ {
+ result_expr = fold_build1_loc (Location ().gcc_location (), CONVERT_EXPR,
+ result_type_tree, convert_me_expr);
+ }
+ else
+ {
+ result_expr = ctx->get_backend ()->convert_expression (result_type_tree,
+ convert_me_expr,
+ Location ());
+ }
+
auto return_statement
= ctx->get_backend ()->return_statement (fndecl, {result_expr},
Location ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index a5f0a84..df07cb3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -1060,9 +1060,11 @@ private:
Location expr_locus);
bool
- validate_arithmetic_type (TyTy::BaseType *type,
+ validate_arithmetic_type (const TyTy::BaseType *tyty,
HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
{
+ const TyTy::BaseType *type = tyty->destructure ();
+
// https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
// this will change later when traits are added
switch (expr_type)
@@ -1078,10 +1080,10 @@ private:
|| (type->get_kind () == TyTy::TypeKind::USIZE)
|| (type->get_kind () == TyTy::TypeKind::ISIZE)
|| (type->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) type)->get_infer_kind ()
+ && (((const TyTy::InferType *) type)->get_infer_kind ()
== TyTy::InferType::INTEGRAL))
|| (type->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) type)->get_infer_kind ()
+ && (((const TyTy::InferType *) type)->get_infer_kind ()
== TyTy::InferType::FLOAT));
// integers or bools
@@ -1094,7 +1096,7 @@ private:
|| (type->get_kind () == TyTy::TypeKind::ISIZE)
|| (type->get_kind () == TyTy::TypeKind::BOOL)
|| (type->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) type)->get_infer_kind ()
+ && (((const TyTy::InferType *) type)->get_infer_kind ()
== TyTy::InferType::INTEGRAL));
// integers only
@@ -1105,10 +1107,12 @@ private:
|| (type->get_kind () == TyTy::TypeKind::USIZE)
|| (type->get_kind () == TyTy::TypeKind::ISIZE)
|| (type->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) type)->get_infer_kind ()
+ && (((const TyTy::InferType *) type)->get_infer_kind ()
== TyTy::InferType::INTEGRAL));
}
+
gcc_unreachable ();
+ return false;
}
/* The return value of TypeCheckExpr::Resolve */
diff --git a/gcc/testsuite/rust/compile/issue-1383.rs b/gcc/testsuite/rust/compile/issue-1383.rs
new file mode 100644
index 0000000..cca12e8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1383.rs
@@ -0,0 +1,8 @@
+pub fn generic_function<X>(a: X) -> X {
+ a
+}
+
+fn main() -> i32 {
+ let a = generic_function(123);
+ a - 123
+}