From a8520d9d7d7a3504078495014405a5e5f35e6051 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Wed, 25 Dec 2024 18:13:43 +0000 Subject: [PATCH] tychk: Add more support for additional trait bounds in functions 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 56ce95f5f903..a4878a2b816a 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 763838ea488b..3a7dbd68dabb 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 @@ class ResolveType : public ResolverBase 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 d2758a5f76ad..1437daa60ea3 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 10acde081b7d..aafdac86b8b4 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 @@ class TypeCheckType : public TypeCheckBase, public HIR::HIRTypeVisitor 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 @@ class TypeCheckType : public TypeCheckBase, public HIR::HIRTypeVisitor 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 000000000000..7d0dcc11cd2a --- /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 000000000000..81c39ecda7f4 --- /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 2a5bc94b6463..e23669f309b4 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