https://gcc.gnu.org/g:97a7ae203920812de36f3131bd096b499718c6fb
commit r16-2799-g97a7ae203920812de36f3131bd096b499718c6fb Author: Philip Herron <herron.phi...@googlemail.com> Date: Mon May 5 21:07:20 2025 +0100 gccrs: Emit error diagnostic for bad impl type usage Rust only allows impl traits to be used in the return position of functions. Fixes Rust-GCC#1485 gcc/rust/ChangeLog: * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): allow impl type * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): likewise * hir/rust-ast-lower-type.cc (ASTLoweringType::ASTLoweringType): new flag for impl trait (ASTLoweringType::translate): pass flag (ASTLoweringType::visit): track impl trait tag (ASTLoweringType::emit_impl_trait_error): new diagnostic * hir/rust-ast-lower-type.h: add new field gcc/testsuite/ChangeLog: * rust/compile/impl_trait_diag.rs: New test. * rust/compile/issue-1485.rs: New test. Signed-off-by: Philip Herron <herron.phi...@googlemail.com> Diff: --- gcc/rust/hir/rust-ast-lower-implitem.cc | 3 +- gcc/rust/hir/rust-ast-lower-item.cc | 3 +- gcc/rust/hir/rust-ast-lower-type.cc | 57 ++++++++++++++++++++------- gcc/rust/hir/rust-ast-lower-type.h | 13 +++--- gcc/testsuite/rust/compile/impl_trait_diag.rs | 17 ++++++++ gcc/testsuite/rust/compile/issue-1485.rs | 16 ++++++++ 6 files changed, 85 insertions(+), 24 deletions(-) diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index d815a71564ec..fc9fe1ace4a9 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -138,7 +138,8 @@ ASTLowerImplItem::visit (AST::Function &function) std::unique_ptr<HIR::Type> return_type = function.has_return_type () ? std::unique_ptr<HIR::Type> ( - ASTLoweringType::translate (function.get_return_type ())) + ASTLoweringType::translate (function.get_return_type (), false, + true /* impl trait is allowed here*/)) : nullptr; Defaultness defaultness diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc index f4396b58e595..1810d16d515d 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -411,7 +411,8 @@ ASTLoweringItem::visit (AST::Function &function) std::unique_ptr<HIR::Type> return_type = function.has_return_type () ? std::unique_ptr<HIR::Type> ( - ASTLoweringType::translate (function.get_return_type ())) + ASTLoweringType::translate (function.get_return_type (), false, + true /* impl trait is allowed here*/)) : nullptr; std::vector<HIR::FunctionParam> function_params; diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc index a678f189ac28..5aedb9196dc5 100644 --- a/gcc/rust/hir/rust-ast-lower-type.cc +++ b/gcc/rust/hir/rust-ast-lower-type.cc @@ -209,10 +209,17 @@ ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path) path.get_locus ()); } +ASTLoweringType::ASTLoweringType (bool default_to_static_lifetime, + bool impl_trait_allowed) + : ASTLoweringBase (), default_to_static_lifetime (default_to_static_lifetime), + impl_trait_allowed (impl_trait_allowed), translated (nullptr) +{} + HIR::Type * -ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime) +ASTLoweringType::translate (AST::Type &type, bool default_to_static_lifetime, + bool impl_trait_allowed) { - ASTLoweringType resolver (default_to_static_lifetime); + ASTLoweringType resolver (default_to_static_lifetime, impl_trait_allowed); type.accept_vis (resolver); rust_assert (resolver.translated != nullptr); @@ -260,7 +267,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype) HIR::Type *param_type = ASTLoweringType::translate (param.get_type (), - default_to_static_lifetime); + default_to_static_lifetime, + impl_trait_allowed); HIR::MaybeNamedParam p (param.get_name (), kind, std::unique_ptr<HIR::Type> (param_type), @@ -272,7 +280,8 @@ ASTLoweringType::visit (AST::BareFunctionType &fntype) if (fntype.has_return_type ()) { return_type = ASTLoweringType::translate (fntype.get_return_type (), - default_to_static_lifetime); + default_to_static_lifetime, + impl_trait_allowed); } auto crate_num = mappings.get_current_crate (); @@ -292,8 +301,8 @@ ASTLoweringType::visit (AST::TupleType &tuple) std::vector<std::unique_ptr<HIR::Type>> elems; for (auto &e : tuple.get_elems ()) { - HIR::Type *t - = ASTLoweringType::translate (*e, default_to_static_lifetime); + HIR::Type *t = ASTLoweringType::translate (*e, default_to_static_lifetime, + impl_trait_allowed); elems.push_back (std::unique_ptr<HIR::Type> (t)); } @@ -323,7 +332,8 @@ ASTLoweringType::visit (AST::ArrayType &type) { HIR::Type *translated_type = ASTLoweringType::translate (type.get_elem_type (), - default_to_static_lifetime); + default_to_static_lifetime, + impl_trait_allowed); HIR::Expr *array_size = ASTLoweringExpr::translate (type.get_size_expr ()); auto crate_num = mappings.get_current_crate (); @@ -343,9 +353,9 @@ ASTLoweringType::visit (AST::ReferenceType &type) HIR::Lifetime lifetime = lower_lifetime (type.get_lifetime (), default_to_static_lifetime); - HIR::Type *base_type - = ASTLoweringType::translate (type.get_base_type (), - default_to_static_lifetime); + HIR::Type *base_type = ASTLoweringType::translate (type.get_base_type (), + default_to_static_lifetime, + impl_trait_allowed); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, type.get_node_id (), @@ -364,7 +374,8 @@ ASTLoweringType::visit (AST::RawPointerType &type) { HIR::Type *base_type = ASTLoweringType::translate (type.get_type_pointed_to (), - default_to_static_lifetime); + default_to_static_lifetime, + impl_trait_allowed); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, type.get_node_id (), @@ -384,9 +395,9 @@ ASTLoweringType::visit (AST::RawPointerType &type) void ASTLoweringType::visit (AST::SliceType &type) { - HIR::Type *base_type - = ASTLoweringType::translate (type.get_elem_type (), - default_to_static_lifetime); + HIR::Type *base_type = ASTLoweringType::translate (type.get_elem_type (), + default_to_static_lifetime, + impl_trait_allowed); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, type.get_node_id (), @@ -463,7 +474,8 @@ void ASTLoweringType::visit (AST::ParenthesisedType &type) { auto *inner = ASTLoweringType::translate (*type.get_type_in_parens (), - default_to_static_lifetime); + default_to_static_lifetime, + impl_trait_allowed); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, type.get_node_id (), @@ -480,6 +492,9 @@ ASTLoweringType::visit (AST::ParenthesisedType &type) void ASTLoweringType::visit (AST::ImplTraitType &type) { + if (!impl_trait_allowed) + emit_impl_trait_error (type.get_locus ()); + std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds; for (auto &bound : type.get_type_param_bounds ()) { @@ -499,6 +514,9 @@ ASTLoweringType::visit (AST::ImplTraitType &type) void ASTLoweringType::visit (AST::ImplTraitTypeOneBound &type) { + if (!impl_trait_allowed) + emit_impl_trait_error (type.get_locus ()); + std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds; auto b = ASTLoweringTypeBounds::translate (type.get_trait_bound ()); @@ -513,6 +531,15 @@ ASTLoweringType::visit (AST::ImplTraitTypeOneBound &type) = new HIR::ImplTraitType (mapping, std::move (bounds), type.get_locus ()); } +void +ASTLoweringType::emit_impl_trait_error (location_t locus) +{ + rich_location r (line_table, locus); + rust_error_at (r, ErrorCode::E0562, + "%<impl Trait%> not allowed outside of function and inherent " + "method return types"); +} + HIR::GenericParam * ASTLowerGenericParam::translate (AST::GenericParam ¶m) { diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 4efaeee13149..50f543a357cf 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -66,7 +66,8 @@ class ASTLoweringType : public ASTLoweringBase public: static HIR::Type *translate (AST::Type &type, - bool default_to_static_lifetime = false); + bool default_to_static_lifetime = false, + bool impl_trait_allowed = false); void visit (AST::BareFunctionType &fntype) override; void visit (AST::TupleType &tuple) override; @@ -81,19 +82,17 @@ public: void visit (AST::TraitObjectTypeOneBound &type) override; void visit (AST::TraitObjectType &type) override; void visit (AST::ParenthesisedType &type) override; - void visit (AST::ImplTraitType &type) override; void visit (AST::ImplTraitTypeOneBound &type) override; + void emit_impl_trait_error (location_t locus); + private: - ASTLoweringType (bool default_to_static_lifetime) - : ASTLoweringBase (), - default_to_static_lifetime (default_to_static_lifetime), - translated (nullptr) - {} + ASTLoweringType (bool default_to_static_lifetime, bool impl_trait_allowed); /** Used when compiling const and static items. */ bool default_to_static_lifetime; + bool impl_trait_allowed; HIR::Type *translated; }; diff --git a/gcc/testsuite/rust/compile/impl_trait_diag.rs b/gcc/testsuite/rust/compile/impl_trait_diag.rs new file mode 100644 index 000000000000..54a0cd220a39 --- /dev/null +++ b/gcc/testsuite/rust/compile/impl_trait_diag.rs @@ -0,0 +1,17 @@ +#[lang = "sized"] +pub trait Sized {} + +trait Foo { + fn method(&self); +} + +struct Bar; +impl Foo for Bar {} + +fn main() { + let x: impl Foo = Bar; // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." } + + struct Wrapper { + field: impl Foo, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." } + } +} diff --git a/gcc/testsuite/rust/compile/issue-1485.rs b/gcc/testsuite/rust/compile/issue-1485.rs new file mode 100644 index 000000000000..a0cd5a0f1f92 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-1485.rs @@ -0,0 +1,16 @@ +#[lang = "sized"] +pub trait Sized {} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + #[lang = "fn_once_output"] + type Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +struct BinOpInvalid { + lhs: i32, + rhs: i32, + f: impl FnOnce(i32) -> i32, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." } +}