From: Arthur Cohen <[email protected]>
This commit correctly lowers and typechecks parenthesized types, which are used
for trait objects with additional bounds.
gcc/rust/ChangeLog:
* resolve/rust-ast-resolve-type.cc (ResolveType::visit): New visitor to
handle
ParenthesizedType.
* resolve/rust-ast-resolve-type.h: Likewise.
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit):
Likewise.
* typecheck/rust-hir-type-check-type.h: Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/auto_traits2.rs: New test.
* rust/compile/auto_traits3.rs: New test.
* rust/compile/nr2/exclude: Add auto_traits2 test.
---
gcc/rust/resolve/rust-ast-resolve-type.cc | 6 ++++
gcc/rust/resolve/rust-ast-resolve-type.h | 3 ++
.../typecheck/rust-hir-type-check-type.cc | 6 ++++
gcc/rust/typecheck/rust-hir-type-check-type.h | 4 +--
gcc/testsuite/rust/compile/auto_traits2.rs | 26 ++++++++++++++
gcc/testsuite/rust/compile/auto_traits3.rs | 34 +++++++++++++++++++
gcc/testsuite/rust/compile/nr2/exclude | 2 ++
7 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/auto_traits2.rs
create mode 100644 gcc/testsuite/rust/compile/auto_traits3.rs
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index cb5a18d5d47..1d004b1ba9b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -50,6 +50,12 @@ ResolveType::visit (AST::TraitObjectType &type)
}
}
+void
+ResolveType::visit (AST::ParenthesisedType &type)
+{
+ resolved_node = ResolveType::go (*type.get_type_in_parens ());
+}
+
void
ResolveType::visit (AST::ReferenceType &type)
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 518c0d80b14..5e8cdb11b2d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -24,6 +24,7 @@
#include "rust-diagnostics.h"
#include "rust-hir-map.h"
#include "rust-path.h"
+#include "rust-type.h"
#include "util/rust-hir-map.h"
namespace Rust {
@@ -143,6 +144,8 @@ public:
void visit (AST::TraitObjectType &type) override;
+ void visit (AST::ParenthesisedType &type) override;
+
void visit (AST::SliceType &type) override;
private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 4ea1a493fa8..859cdfedcd0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -790,6 +790,12 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
std::move (specified_bounds));
}
+void
+TypeCheckType::visit (HIR::ParenthesisedType &type)
+{
+ translated = TypeCheckType::Resolve (type.get_type_in_parens ());
+}
+
void
TypeCheckType::visit (HIR::ArrayType &type)
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h
b/gcc/rust/typecheck/rust-hir-type-check-type.h
index bf5589cbbab..1da01b869dd 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -59,6 +59,7 @@ public:
void visit (HIR::InferredType &type) override;
void visit (HIR::NeverType &type) override;
void visit (HIR::TraitObjectType &type) override;
+ void visit (HIR::ParenthesisedType &type) override;
void visit (HIR::TypePathSegmentFunction &segment) override
{ /* TODO */
@@ -69,9 +70,6 @@ public:
void visit (HIR::ImplTraitType &type) override
{ /* TODO */
}
- void visit (HIR::ParenthesisedType &type) override
- { /* TODO */
- }
void visit (HIR::ImplTraitTypeOneBound &type) override
{ /* TODO */
}
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs
b/gcc/testsuite/rust/compile/auto_traits2.rs
new file mode 100644
index 00000000000..7d0dcc11cd2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -0,0 +1,26 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+ fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+ a.a_method();
+}
+
+struct S;
+
+impl A for S {
+ fn a_method(&self) {}
+}
+
+fn main() {
+ let s = S;
+
+ foo(&s); // { dg-error "bounds not satisfied" }
+ // { dg-error "mismatched type" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/auto_traits3.rs
b/gcc/testsuite/rust/compile/auto_traits3.rs
new file mode 100644
index 00000000000..81c39ecda7f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits3.rs
@@ -0,0 +1,34 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+ fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+ a.a_method();
+}
+
+struct S;
+
+impl A for S {
+ fn a_method(&self) {} // { dg-warning "unused" }
+}
+
+// These should not be necessary because they are both auto traits
+// They need to be removed once we figure out the proper implementation for
each of them
+// However, it'd be silly to implement other traits in order to ensure the
test is okay,
+// as these extra trait bounds are only allowed to use auto traits
+// FIXME: #3327
+// FIXME: #3326
+unsafe impl Send for S {}
+unsafe impl Sync for S {}
+
+fn main() {
+ let s = S;
+
+ foo(&s);
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude
b/gcc/testsuite/rust/compile/nr2/exclude
index 2a5bc94b646..e23669f309b 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -207,4 +207,6 @@ issue-2907.rs
issue-2423.rs
issue-266.rs
additional-trait-bounds2.rs
+auto_traits2.rs
+auto_traits3.rs
# please don't delete the trailing newline
--
2.45.2