aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-07-14 17:56:29 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-07-14 18:57:27 +0100
commit6e0c46b86aaa38f18e2c0af2a4711bfeaa242498 (patch)
tree5d7acdd2a74a68fe91fe42dd161460a9dd174e95
parent60b1209d64cee3b47cf9b3f5b9da4f74f03a25bb (diff)
downloadgcc-6e0c46b86aaa38f18e2c0af2a4711bfeaa242498.zip
gcc-6e0c46b86aaa38f18e2c0af2a4711bfeaa242498.tar.gz
gcc-6e0c46b86aaa38f18e2c0af2a4711bfeaa242498.tar.bz2
Trait item consts can have an optional expr
When we are checking for trait constants their expression can be optional which will cause an ICE when ignored. Fixes #471
-rw-r--r--gcc/rust/ast/rust-item.h4
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc10
-rw-r--r--gcc/testsuite/rust/compile/torture/traits7.rs22
4 files changed, 35 insertions, 5 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 37d087c..30cab0e 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3265,10 +3265,12 @@ public:
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
+ bool has_expr () const { return expr != nullptr; }
+
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Expr> &get_expr ()
{
- rust_assert (expr != nullptr);
+ rust_assert (has_expr ());
return expr;
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 1f1ff30..0714f5d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -168,7 +168,9 @@ public:
void visit (AST::TraitItemConst &constant) override
{
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
- ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
+
+ if (constant.has_expr ())
+ ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
// the mutability checker needs to verify for immutable decls the number
// of assignments are <1. This marks an implicit assignment
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 1d97deb..acfc022 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -409,10 +409,14 @@ TraitItemReference::get_type_from_constant (
/*const*/ HIR::TraitItemConst &constant) const
{
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ().get ());
- TyTy::BaseType *expr
- = TypeCheckExpr::Resolve (constant.get_expr ().get (), false);
+ if (constant.has_expr ())
+ {
+ TyTy::BaseType *expr
+ = TypeCheckExpr::Resolve (constant.get_expr ().get (), false);
- return type->unify (expr);
+ return type->unify (expr);
+ }
+ return type;
}
TyTy::BaseType *
diff --git a/gcc/testsuite/rust/compile/torture/traits7.rs b/gcc/testsuite/rust/compile/torture/traits7.rs
new file mode 100644
index 0000000..a6fe5a3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits7.rs
@@ -0,0 +1,22 @@
+trait Foo {
+ const A: i32;
+ // { dg-warning "unused name .Foo::A." "" { target *-*-* } .-1 }
+
+ fn test(self);
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .Foo::test." "" { target *-*-* } .-2 }
+}
+
+struct Bar;
+impl Foo for Bar {
+ const A: i32 = 123;
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+ fn test(self) {}
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+ let a = Bar;
+ a.test();
+}