diff options
-rw-r--r-- | gcc/rust/ast/rust-desugar-apit.cc | 6 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 25 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.cc | 3 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.cc | 9 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-item.h | 16 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-subst.cc | 21 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-subst.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/impl_trait_generic_arg.rs | 24 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/nr2/exclude | 1 |
9 files changed, 73 insertions, 33 deletions
diff --git a/gcc/rust/ast/rust-desugar-apit.cc b/gcc/rust/ast/rust-desugar-apit.cc index 2f31bcf..5b9486e 100644 --- a/gcc/rust/ast/rust-desugar-apit.cc +++ b/gcc/rust/ast/rust-desugar-apit.cc @@ -203,7 +203,8 @@ public: // Create the new generic parameter auto generic_param = std::unique_ptr<TypeParam> ( - new TypeParam (ident, type.get_locus (), std::move (bounds))); + new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {}, + true /*from impl trait*/)); // Store the generic parameter to be added to the function signature implicit_generic_params.push_back (std::move (generic_param)); @@ -241,7 +242,8 @@ public: // Create the new generic parameter auto generic_param = std::unique_ptr<TypeParam> ( - new TypeParam (ident, type.get_locus (), std::move (bounds))); + new TypeParam (ident, type.get_locus (), std::move (bounds), nullptr, {}, + true /*from impl trait*/)); // Store the generic parameter to be added to the function signature implicit_generic_params.push_back (std::move (generic_param)); diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index f507c90..2f53f8d 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -51,21 +51,12 @@ class TypePath; // A type generic parameter (as opposed to a lifetime generic parameter) class TypeParam : public GenericParam { - // bool has_outer_attribute; - // std::unique_ptr<Attribute> outer_attr; AST::AttrVec outer_attrs; - Identifier type_representation; - - // bool has_type_param_bounds; - // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> - type_param_bounds; // inlined form - - // bool has_type; + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; std::unique_ptr<Type> type; - location_t locus; + bool was_impl_trait; public: Identifier get_type_representation () const { return type_representation; } @@ -85,18 +76,19 @@ public: std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds = std::vector<std::unique_ptr<TypeParamBound>> (), std::unique_ptr<Type> type = nullptr, - AST::AttrVec outer_attrs = {}) + AST::AttrVec outer_attrs = {}, bool was_impl_trait = false) : GenericParam (Analysis::Mappings::get ().get_next_node_id ()), outer_attrs (std::move (outer_attrs)), type_representation (std::move (type_representation)), type_param_bounds (std::move (type_param_bounds)), - type (std::move (type)), locus (locus) + type (std::move (type)), locus (locus), was_impl_trait (was_impl_trait) {} // Copy constructor uses clone TypeParam (TypeParam const &other) : GenericParam (other.node_id), outer_attrs (other.outer_attrs), - type_representation (other.type_representation), locus (other.locus) + type_representation (other.type_representation), locus (other.locus), + was_impl_trait (other.was_impl_trait) { // guard to prevent null pointer dereference if (other.type != nullptr) @@ -114,6 +106,7 @@ public: outer_attrs = other.outer_attrs; locus = other.locus; node_id = other.node_id; + was_impl_trait = other.was_impl_trait; // guard to prevent null pointer dereference if (other.type != nullptr) @@ -153,17 +146,19 @@ public: return type; } - // TODO: mutable getter seems kinda dodgy std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds () { return type_param_bounds; } + const std::vector<std::unique_ptr<TypeParamBound>> & get_type_param_bounds () const { return type_param_bounds; } + bool from_impl_trait () const { return was_impl_trait; } + protected: // Clone function implementation as virtual method TypeParam *clone_generic_param_impl () const override diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc index 6a5b7db..b83d804 100644 --- a/gcc/rust/hir/rust-ast-lower-type.cc +++ b/gcc/rust/hir/rust-ast-lower-type.cc @@ -620,7 +620,8 @@ ASTLowerGenericParam::visit (AST::TypeParam ¶m) translated = new HIR::TypeParam (mapping, param.get_type_representation (), param.get_locus (), std::move (type_param_bounds), - std::move (type), param.get_outer_attrs ()); + std::move (type), param.get_outer_attrs (), + param.from_impl_trait ()); } HIR::TypeParamBound * diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc index 160f710..1406e7a 100644 --- a/gcc/rust/hir/tree/rust-hir-item.cc +++ b/gcc/rust/hir/tree/rust-hir-item.cc @@ -26,16 +26,18 @@ TypeParam::TypeParam ( Analysis::NodeMapping mappings, Identifier type_representation, location_t locus, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, - tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs) + tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs, + bool was_impl_trait) : GenericParam (mappings), outer_attrs (std::move (outer_attrs)), type_representation (std::move (type_representation)), type_param_bounds (std::move (type_param_bounds)), type (std::move (type)), - locus (locus) + locus (locus), was_impl_trait (was_impl_trait) {} TypeParam::TypeParam (TypeParam const &other) : GenericParam (other.mappings), outer_attrs (other.outer_attrs), - type_representation (other.type_representation), locus (other.locus) + type_representation (other.type_representation), locus (other.locus), + was_impl_trait (other.was_impl_trait) { // guard to prevent null pointer dereference if (other.has_type ()) @@ -55,6 +57,7 @@ TypeParam::operator= (TypeParam const &other) outer_attrs = other.outer_attrs; locus = other.locus; mappings = other.mappings; + was_impl_trait = other.was_impl_trait; // guard to prevent null pointer dereference if (other.has_type ()) diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 41ba38c..dc8f9f9 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -95,17 +95,11 @@ protected: class TypeParam : public GenericParam { AST::AttrVec outer_attrs; - Identifier type_representation; - - // bool has_type_param_bounds; - // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> - type_param_bounds; // inlined form - + std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds; tl::optional<std::unique_ptr<Type>> type; - location_t locus; + bool was_impl_trait; public: // Returns whether the type of the type param has been specified. @@ -121,9 +115,9 @@ public: TypeParam (Analysis::NodeMapping mappings, Identifier type_representation, location_t locus = UNDEF_LOCATION, std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds - = std::vector<std::unique_ptr<TypeParamBound>> (), + = {}, tl::optional<std::unique_ptr<Type>> type = tl::nullopt, - AST::AttrVec outer_attrs = std::vector<AST::Attribute> ()); + AST::AttrVec outer_attrs = {}, bool was_impl_trait = false); // Copy constructor uses clone TypeParam (TypeParam const &other); @@ -154,6 +148,8 @@ public: std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds (); + bool from_impl_trait () const { return was_impl_trait; } + protected: // Clone function implementation as (not pure) virtual method TypeParam *clone_generic_param_impl () const override diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc index c3033ee..8279c8f 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.cc +++ b/gcc/rust/typecheck/rust-tyty-subst.cc @@ -72,6 +72,12 @@ SubstitutionParamMapping::get_generic_param () return generic; } +const HIR::TypeParam & +SubstitutionParamMapping::get_generic_param () const +{ + return generic; +} + bool SubstitutionParamMapping::needs_substitution () const { @@ -618,7 +624,6 @@ SubstitutionRef::get_mappings_from_generic_args ( if (args.get_binding_args ().size () > get_num_associated_bindings ()) { rich_location r (line_table, args.get_locus ()); - rust_error_at (r, "generic item takes at most %lu type binding " "arguments but %lu were supplied", @@ -702,7 +707,19 @@ SubstitutionRef::get_mappings_from_generic_args ( return SubstitutionArgumentMappings::error (); } - SubstitutionArg subst_arg (&substitutions.at (offs), resolved); + const auto ¶m_mapping = substitutions.at (offs); + const auto &type_param = param_mapping.get_generic_param (); + if (type_param.from_impl_trait ()) + { + rich_location r (line_table, arg->get_locus ()); + r.add_fixit_remove (arg->get_locus ()); + rust_error_at (r, ErrorCode::E0632, + "cannot provide explicit generic arguments when " + "%<impl Trait%> is used in argument position"); + return SubstitutionArgumentMappings::error (); + } + + SubstitutionArg subst_arg (¶m_mapping, resolved); offs++; mappings.push_back (std::move (subst_arg)); } diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h index 8a43b91..084b453 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.h +++ b/gcc/rust/typecheck/rust-tyty-subst.h @@ -60,6 +60,7 @@ public: const ParamType *get_param_ty () const; HIR::TypeParam &get_generic_param (); + const HIR::TypeParam &get_generic_param () const; // this is used for the backend to override the HirId ref of the param to // what the concrete type is for the rest of the context diff --git a/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs new file mode 100644 index 0000000..ecdb088 --- /dev/null +++ b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs @@ -0,0 +1,24 @@ +#[lang = "sized"] +trait Sized {} + +trait Foo { + fn id(&self) -> u8; +} + +struct Bar; + +impl Foo for Bar { + fn id(&self) -> u8 { + 1 + } +} + +fn takes(val: impl Foo) -> u8 { + val.id() +} + +fn main() { + let b = Bar; + let x = takes::<Bar>(b); + // { dg-error "cannot provide explicit generic arguments when .impl Trait. is used in argument position .E0632." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude index d3bdb1c..b9b9e39 100644 --- a/gcc/testsuite/rust/compile/nr2/exclude +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -17,4 +17,5 @@ issue-3649.rs issue-1487.rs issue-2015.rs issue-3454.rs +impl_trait_generic_arg.rs # please don't delete the trailing newline |