From 6e0c46b86aaa38f18e2c0af2a4711bfeaa242498 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 14 Jul 2021 17:56:29 +0100 Subject: 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 --- gcc/rust/ast/rust-item.h | 4 +++- gcc/rust/resolve/rust-ast-resolve-item.h | 4 +++- gcc/rust/typecheck/rust-hir-type-check.cc | 10 +++++++--- gcc/testsuite/rust/compile/torture/traits7.rs | 22 ++++++++++++++++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/rust/compile/torture/traits7.rs (limited to 'gcc') 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 &get_outer_attrs () { return outer_attrs; } const std::vector &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 &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(); +} -- cgit v1.1