diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-07-14 17:56:29 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-07-14 18:57:27 +0100 |
commit | 6e0c46b86aaa38f18e2c0af2a4711bfeaa242498 (patch) | |
tree | 5d7acdd2a74a68fe91fe42dd161460a9dd174e95 | |
parent | 60b1209d64cee3b47cf9b3f5b9da4f74f03a25bb (diff) | |
download | gcc-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.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 4 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/traits7.rs | 22 |
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(); +} |