diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-05-05 21:07:20 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2025-05-07 12:04:19 +0000 |
commit | ef44f649655dcbba63b925c06e923ed1aefd6678 (patch) | |
tree | 2df1721f870a7d3d1266347a5333d24f82ce3e1a /gcc | |
parent | 5599bf49cdf6d89f7e1f4e13b150b43d2cf6dca3 (diff) | |
download | gcc-ef44f649655dcbba63b925c06e923ed1aefd6678.zip gcc-ef44f649655dcbba63b925c06e923ed1aefd6678.tar.gz gcc-ef44f649655dcbba63b925c06e923ed1aefd6678.tar.bz2 |
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.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-implitem.cc | 3 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.cc | 3 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.cc | 57 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/impl_trait_diag.rs | 17 | ||||
-rw-r--r-- | 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 66488ac..c06e88f 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 47b4b71..9bb968f 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 baffbf8..d871583 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 3586298..72a361f 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 0000000..54a0cd2 --- /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 0000000..a0cd5a0 --- /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." } +} |