aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/ast/rust-desugar-apit.cc6
-rw-r--r--gcc/rust/ast/rust-item.h25
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.cc3
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc9
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h16
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc21
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h1
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_generic_arg.rs24
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude1
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 &param)
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 &param_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 (&param_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